flotで描画したグラフにイベント処理を追加する

こんにちは。松下です。

開発版のサンプルページで既に紹介されているものもありますが、flotで描画したグラフにイベント処理を追加する方法を紹介します。

flotには、あらかじめマウスのホバーやクリック時のカスタムイベントが定義されており、このカスタムイベントに対してコールバック関数を紐付ければ、独自のイベントを追加することができます。

クリックイベントを追加する

flotでは、”plotclick”というグラフのポイントをクリックした時のカスタムイベントが定義されているので、以下のようなコードを書けば、ポインンクリック時の処理が追加することができます。

$("placeholder").bind("plotclick", function(event, pos, item) {
--略--
});

使用する上での前提条件は、plot描画時のgridオプションのclickableを有効にすること、seriesオプションのpointsを有効にすることです。

option = {
    series: {points:  {show: true}},
    grid: {clickable: true},
    --略--
};

以下に、グラフで描画したポイントで際に、ポイントをハイライトする処理を例示します。

$("#placeholder").bind("plotclick", function (event, pos, item) {
    if (item) {
        plot.highlight(item.series, item.datapoint);
    }
});

クリックすると以下のようにポイントがハイライトします。

before

after

windowリサイズにグラフをリロードする

単純に再プロットするなら以下のとおりで、windowリサイズ時に通常と同じように描画する処理をバインドするだけです。

$(window).resize(function() {
    var plot = $.plot($("#placeholder"), datalist, options);
});

なぜ、こんな処理を行うかというと、グラフを描画する領域のサイズを固定しない場合、グラフのラベルや判例がずれてしまうからです。以下の画面では、判例を左上に設定したにも関わらず、windowサイズを小さくしたことで判例が右側にずれています。

画面が崩れる

この問題をリサイズ時に描画処理を行うことで問題を解決できます。

しかしながら、この処理には少し不満に思いました。理由は、再描画を処理的にはcanvasオブジェクトを再作成してデータを描画してといった処理を一からやり直すことになるので、windowサイズが変更されるたびに行う処理として少しコストが高い処理だと思ったからです。

そこで、初期化処理を行うことなくリサイズ処理だけ行うことはできないか、調査してみました。 が、結論からいうとコードの作り上、どうしようもないことがわかりました。 グラフの描画処理は

var plot = $.plot($("#placeholder"), datalist, options);

のように行いますが、plot関数実行後に内部で生成したPlotクラスが返却されます。 これを使って、以下のように実行できないか試してみましたが、グラフのリサイズは行われない模様。

    var plot = $.plot($("#placeholder"), datalist, options);
    plot.setupGrid();
    plot.draw();

でさらに調べてみると、初期化処理において、canvasWidth、canvasHeightという内部変数を設定しており、グラフの描画処理はこれらの変数に依存していることが分かりました。これらの変数をwindowリサイズ時に再設定すれば良いのですが、これらの変数を外部から書き換える手段、及びタイミングが存在しません。

で苦肉の策ですが、Plotクラスの内部関数であるconstructCanvasでcanvasWidth、canvasHeightを設定する処理を行っているので、これを外部公開するようにflotのコードを修正した上で、以下のコードを実行。

    var plot = $.plot($("#placeholder"), datalist, options);
    plot.constructCanvas();
    plot.setupGrid();
    plot.draw();

これはうまく行きました。reloadとかメソッドがあればいいんですが、今のところこの方法と同様にflot自体に手を加える方法しかないようです。

自分がflotを使っていて思ったのが、今回みたいにイベントを追加したりする場合に、今のflotがユーザに公開されている情報(メソッドやフィールド)が必要不十分であること。highlightメソッド、unhighlightメソッドはあるのに、外部からはどこがハイライトされているのか、ハイライトしていないのか分からないとか。 開発版なのでしょうがないのかもしれませんが、グラフライブラリとしては良いものだと思っているので、今後の改善に期待したいと思ってます。

記事を読んでくださった方で、他になにか方法があれば教えてください。

Comments are closed.