25

g親ノード (SVG要素など)で発生したデータへの変更をその子ノード (SVG 要素など) に渡す最善の方法がわかりませんcircle

これこれを読みましたが、まだわかりません。

これは最小限の作業例です。svgこの例では、SVG 要素を含む d3 セレクションを参照するというオブジェクトがあることを前提としています。

data = [{"id":"A","name":"jim"},{"id":"B","name":"dave"},{"id":"C","name":"pete"}];

g = svg.selectAll("g").data(data, function(d) { return d.id; }).enter().append("g");

g.append("circle")
      .attr("r", 3)
      .attr("cx", 100)
      .attr("cy", function(d,i) {return 100 + (i * 30);})

// The data gets passed down to the circles (I think):
console.log("circle data:");
d3.selectAll("g circle").each(function(d) { console.log(d.name); });     

// Now change the data, and update the groups' data accordingly
data = [{"id":"A","name":"carol"},{"id":"B","name":"diane"},{"id":"C","name":"susan"}];
svg.selectAll("g").data(data, function(d) { return d.id;});

// These are the results of the change:
console.log("after change, the group has:");
d3.selectAll("g").each(function(d) { console.log(d.name); });     
console.log("but the circles still have:");
d3.selectAll("g circle").each(function(d) { console.log(d.name); });   

グループのすべての子要素に新しい名前を付ける簡潔な方法を見つけるのを手伝ってくれる人はいますか? 私の実際の例では、それぞれgに多くcircleの が含まれています。

4

2 に答える 2

33

親から子にデータを伝達するには、次の 2 つの方法があります。

  1. selection.selectはこれを暗黙的に行います。( と の実装はselection.append、実際には内部selection.insertに基づいています)selection.select

    svg.selectAll("g").select("circle")
    
  2. 関数を使用して明示的にデータ結合をやり直して、親データを受け取り、それを子の配列で返すことができます。

    svg.selectAll("g").selectAll("circle")
        .data(function(d) { return [d]; });
    

これらは同じことになります。最初のオプションは select のいくつかの特別な動作に依存しているため、最初は少し驚くかもしれませんが、挿入/追加によるノード作成のパターンとノード更新のパターンが対称になるという点で優れています。2 番目のオプションは、伝播中にデータに変更を適用する必要がある場合に便利です。

リンクしていない別の記事も参考になるかもしれません: Thinking with Joins

于 2013-09-16T15:50:00.420 に答える