d3js:使新的父数据下降到子节点

Lon*_*Rob 24 d3.js

我无法弄清楚如何最好地将对父节点(例如SVG g元素)发生的数据的更改传递给它的子节点(例如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); });   
Run Code Online (Sandbox Code Playgroud)

任何人都可以帮我找到一个简洁的方法来获取组中所有子元素的新名称吗?在我的现实生活中,每个都g包含许多circles.

Sco*_*ron 32

有两种方法可以将数据从父母传播到孩子:

  1. selection.select将隐式执行此操作.(实现selection.appendselection.insert实际上基于selection.select内部)

    svg.selectAll("g").select("circle")
    
    Run Code Online (Sandbox Code Playgroud)
  2. 您可以使用函数显式重做数据连接以接收父数据并将其返回到子数组中.

    svg.selectAll("g").selectAll("circle")
        .data(function(d) { return [d]; });
    
    Run Code Online (Sandbox Code Playgroud)

这些都是相同的.第一个选项依赖于select中的一些特殊行为,因此它起初可能有点令人惊讶,但它的好处在于它使节点更新的模式与通过insert/append创建节点的模式对称.如果您需要在传播数据时对数据应用任何更改,则第二个选项很有用.

这是另一篇你没有链接的文章,也可能是有用的:用连接思考