JavaScript最高!JavaScriptは神!
今回はグラフを描画するライブラリであるChart.jsのプラグインを作ってみたよというお話です。
テスト環境
Google Chrome
Chart.js 2.5.0
Chart.jsとは
htmlのcanvasタグを使ってグラフを描画してくれる粋なやつで、例えばsin波形のデータを入れるとこんな感じになります
グラフ描画の際にアニメーションがついていたりしてて非常におしゃれなのですが、欲しい機能がなかったりします。範囲選択ができる機能がデフォルトでないので、作ってみました!
完成したもの
githubのリンクはこちら
プラグインの作成について
Chart.jsのプラグインは必要なAPIを実装したオブジェクトを以下のようにchartに渡してやるだけです。
var plugin = { /* plugin implementation */ };
var chart = new Chart(ctx, {
plugins: [plugin]
});
また以下のようにChart.jsに登録してしまうこともできます。
Chart.pluginService.register(plugin);
var chart = new Chart(ctx, {
pluginOptions: { ... }
});
プラグイン用のAPIはここに一覧が載っています。一覧を見てもどれがどのタイミングで呼ばれるのかがわかりにくいですが、グラフ上に何かを表示する系のプラグインなら以下の2つで充分でしょう。
API名 | 使い方 |
---|---|
beforeInit | プラグインを初期化するのに使う。ここでEventListnerとか登録する。 |
afterDraw | update()をしたときにグラフの描画が終わってから呼ばれる? |
これらの関数は名前の通りのタイミングで呼ばれて、引数にChartのインスタンスが入ります。
これを使ってcanvasのeventListnerを登録したりするんですね。
var node = chartInstance.chart.ctx.canvas;
var ctx = chartInstance.chart.ctx;
ここでいうnodeでaddEventListerをすると、グラフ描画に使っているcanvasにeventを追加できます。
プラグイン作成に役立ちそうなTips
線を描画する
ctx.beginPath();
ctx.setLineDash([]);
ctx.lineWidth = 2;
ctx.strokeStyle = 'rgba(0, 0, 0, 1.0)';
ctx.moveTo(50, chartInstance.chartArea.top);
ctx.lineTo(50, chartInstance.chartArea.bottom);
ctx.stroke();
これはcanvasのoffsetXが50のところに直線を引きます。chartAreaのtop,bottom,left,rightでグラフの描画エリアのoffsetがわかります。ctx.setLineDash([5, 10])
みたいにすると破線を描画することも可能です。詳しくはこことかcanvasについて調べるとよいでしょう。
座標を取得する
グラフが描画されている場合に値に対応するcanvas内でのoffset値を取得できます。
let scale = chartInstance.scales['x-axis-0'];
let pixel = scale.getPixelForValue(value);
ここのchartInstanceというのはbeforeInitとかのプラグインの引数です。x-axis-0というのはx軸のデフォルトの名前で、自分で名前を付けることもできます(僕が作ったプラグインは名前変えたら使えなくなります・・・)。また、以下のようにすればoffset値からグラフでの値を取得することも可能です。
let value = scale.getValueForPixel(pixel);