Mikeは、 D3で再利用可能なコンポーネントを作成することについての優れた記事を持っています。この記事では、コンポーネントを構成可能にする方法のパターンと、コンポーネントを選択範囲に適用する方法について説明します。
このパターンでは、単一のコンポーネントオブジェクトをデータに結合することにより、複数の選択で再利用できます。例えば
var chart = myChart();
d3.select("div.chart")
.data(data)
.call(chart);
私のコンポーネントの実装は次のようになります。
function myChart() {
function my(selection) {
selection.each(function(d, i) {
// generate chart here
// `d` is the data, `i` is the index, `this` is the element
var state = false;
var circle = d3.select(this).append("circle")
.attr("r", "10")
.style("fill", "#000")
.on("click", toggleState);
function toggleState() {
// this function updates the current instance trapped by this closure
(state = !state)
? circle.style("fill", "#fff")
: circle.style("fill", "#000");
}
});
}
my.toggleState(i) {
// How do I access the `i`th instance of the component here?
}
return my;
}
私が達成したいのは、呼び出し元がそのインデックスを指定してこのコンポーネントのインスタンスを操作できるようにすることです。たとえば、div.chart
上記のセレクターが2つの要素を持つ選択範囲を返す場合、呼び出しchart.toggleState(1)
て、選択範囲の2番目のdivを更新するようにします。
なぜ私がこれを行おうとしているのか誰かを混乱させないために、呼び出し元は2つのタイプのコンポーネントを一緒に同期する必要があります。円で表されるコンポーネントと、長方形で表される別のコンポーネントがあるとします。2つのコンポーネントは独立していて、相互に関連付けられていない必要があります。4つの円と4つの長方形を作成できる必要があります。長方形をクリックすると、インデックスの順序に基づいて対応する円を更新できるようにしたいと思います。コンポーネントからイベント(d3.dispatch)を発生させ、現在のインデックスをイベントのパラメーターとして提供する方法はすでに理解していますが、インデックスが指定されたコンポーネントの特定のインスタンスを呼び出す方法は理解していません。