d3.js advent calendar 15日目

もう、どんどん、遅れてきていて、今日は17日ですが、15日目のd3.js API Advent Calendarの記事です

d3 advent calendar 15日目
internal api

内部API

15日目は次のような内部的なAPIについて紹介します

  • d3.functor
  • d3.rebind
  • d3.dispatch

使い所

d3.dispatchでオレオレイベント監視のRoleのような物を作って、それを、d3.rebindでmix-inしまくるってのがいい気がするです

d3.functor

属性やstyleなど特定の値のsetterにおいて、値を関数とすることでd3がデータを引き回します。
このとき、定数も指定することができますが、処理を一貫させるために内部的にfunctorというAPIを利用しています。

サンプル

var hoge = d3.functor("hogehoge");
hoge(); // "hogehoge"
var windowWidth = d3.functor(document.body.offsetWidth);
d3.select('body').append('svg').attr('width', windowWidth);

d3.rebind

名前を指定することで、sourceオブジェクトの値が関数である属性をtargetオブジェクトにコピーします
使い勝手としては、例えば、sortやonなどを何度も記述しないでも良くなるというメリットがあります
使い方としては次のサンプルを御覧ください

サンプル

var src = {age: function(){return 24;}, name: "muddydixon"};
var tgt = d3.rebind({name: "hoge"}, src, "age");
tgt.age() // 24
tgt.name; // "hoge"
tgt = d3.rebind({name: "hoge"}, src, "age", "name");
tgt.name // error srcのnameはmethodじゃないとダメです。
tgt.name() // error

d3.dispatch

独自のイベントを監視するオブジェクトを作成することができます。イベントのハンドラーのセットは通常の.onで行い、emit/triggerはイベント名のメソッドが用意されます(例えば、on("hoge")なら.hoge())
もちろん、jQueryの.trigger()で発火させることもできます

サンプル

var myobject = d3.dispatch("hoge", "fuga");
myobject.on("hoge", function(){ console.log(arguments);});
myobject.hoge(1, 2, 3); // 1, 2, 3
$(myobject).trigger("hoge"); // triggerの場合は引数渡せない