D3.jsがどのように機能するかを理解しようとしていますが、いくつかの(おそらく)基本的な原則を理解するのに苦労しています...助けていただければ幸いです。
私が理解していることから、このスニペットはrect
SVG要素を作成し、それらの属性を設定します。
var nodes = d3.selectAll('circle.node')
.data(mydata)
.enter()
.append('rect').class('attr', 'node');
// now set some attributes on these SVG elements:
nodes.attr('...', function(d) {
return '...';
});
後でデータが変更されたとき、私はこれを行うだけでよいと思います。
d3.selectAll('circle.node')
.data(mydata) // doesn't work as I would expect
ただし、上記のスニペットは期待どおりに機能しません。属性を変更したい場合はattr()
、属性がデータの関数として指定されていて、それ自体を再計算できるはずですが、選択を呼び出す必要があります。さらに悪いことに、この再計算を強制したい場合は、同一の無名関数を指定する必要があります。
何故ですか?.updateMyAttributesFromData()
どういうわけか見逃していた機能はありますか?このようなもの:
d3.selectAll('circle.node')
.data(mydata)
.updateMyAttributesFromData(); // not a real function
私は何かが足りないのですか?
-
ちなみに、「重複する質問」マークを避けるために:質問d3jsで基になるデータが変更されたときに要素を更新する方法には有望なタイトルがありますが、残念ながら内容は完全に異なります。:)
何も見逃していません。これは単にD3の動作方法です。データを更新しても、属性は自動的に更新されません。つまり、新しいデータを割り当てるときに、実際には同じコードを再度実行する必要があります。これは設計上の決定であり、バグではありません。
ただし、これらすべてを実行するコードを、たとえばデータを受け取る関数でラップすることにより、少し簡単に(そして冗長性を少なくして)行うことができます。
function update(data) {
var sel = d3.selectAll("foo").data(data);
sel.enter().append("foo");
// elements added in the enter selection merge into the update selection,
// so this attribute is set for the elements that have just been added as well
sel.attr("foo", "bar");
sel.exit().remove();
}
属性の更新を自動的に行わない理由の1つは(実装の複雑さが増すことは別として)、通常、レンダリング要素がデータ集約型アプリケーションのボトルネックであるためです。これが自動的に発生した場合、実際に何も更新する必要がなくても、常にこのパフォーマンスのオーバーヘッドが発生します。さらに、それは.exit()
選択とうまく機能しません(つまり、とにかく削除される要素の属性を更新します)。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加