「再利用可能なチャートに向けて」とd3.dispatch

Introduction

D3.js Advent Calendar 2013 の 23日目です。もともとはMike Bostockが書いた「再利用可能なチャートに向けて」(Towards Reusable Charts)を自分のアプリで実装した際に気づいたことを書こうと思っていました。そしたらそもそもその記事が英語なので「日本語に訳して下さい」という暗黙のプレッシャーが!


Towards Reusable Charts「再利用可能なチャートに向けて」



というわけで訳しました。

詳しくは訳文を読んでいただければ良いのですが、要点をまとめると

  • チャート作成用関数にゲッター、セッター用メソッドを定義することでチャートごとに異なる設定パラメーターの管理を容易にできる

var chart = timeSeriesChart()
.x(function(d) { return formatDate.parse(d.date); })
.y(function(d) { return +d.price; });

  • selection.callにチャート作成用関数を引数として渡すことでdataやdomもチャートごとに異なるものを渡すことができる

d3.csv("sp500.csv", function(data) {
d3.select("#example")
.datum(data)
.call(chart);
});

ということです。



d3.dispatch



でも実はこれだけだと片手落ちなんですね。それは彼の記事の最後に「インタラクティビティやアニメーションはどうするか」と問題提起しているのですが、たとえば似たようなチャートを再利用する際、チャートAではクリックイベントであることをするが、チャートBでは違うことをさせたい(あるいはなにもさせない)という必要がでてきます。
そういう時に便利なのがd3.dispatch。 これはd3が内部で使っているイベントシステムなのですが、これを使うことによって再利用可能チャート関数固有のイベントを定義することができ、チャートの呼び手は、チャートを作成した後に、各チャート個別のイベントを定義することができます。

もう「再利用可能なチャートに向けて」の使用例でいうと

chart.on("myCustomEvent", function(d, i) {
// do something
});

みたいなイベントが定義可能になる訳です。dispatchイベントの使い方ですが、まずd3.dispatch関数にイベント名を引数として渡すことでイベント名を登録します。

var dispatch = d3.dispatch("myCustomEvent");

そしてそのイベントを発動したいところでそのメソッド名を渡します。

my.append('rect')
.attr("width", this.w)
.attr("height", this.h)
.on("click", dispatch.myCustomEvent);

そしてそのイベントが外部からもアクセスできるようにrebindします。

d3.rebind(my, dispatch, "on");

非常に簡単ですね。

このパターンですが、実は私が発明したものではなくDeveloping a D3.js Edgeという本の受け売りです。

この本はd3.js google groupの何人かのメンバーが「再利用可能なチャートに向けて」の記事をもっと詳しく広げて一冊の本にまでしたものです。

そして先ほどのパターンの例はその本のサンプルプロジェクト
として載っています。

このパターンを使ってみて役に立ちそうであればその本も買ってあげて下さい。


Finally



実はこのパターンは私が現在開発中の反復学習ビデオプレーヤーであるStepUp.ioのエディターないで使われています。ご興味のある方は一度利用してみてさい。

そしてちょっと話しは変わりますが、私がこのアプリを開発する為に起業したのですが、その模様を「ロンドン起業日記」と題して達人出版会から絶賛発売中ですので、興味のあるかたはぜひご購読下さい。