d3js:使新的父数据下降到子节点 [英] d3js: make new parent data descend into child nodes

查看:74
本文介绍了d3js:使新的父数据下降到子节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不能解决如何最好地将发生在父节点(例如SVG g 元素)的数据传递到它的孩子(例如SVG circle 元素)。



我读过,但仍然不能弄清楚。 p>

这是一个最低工作示例。该示例假设您有一个名为 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);})

//数据传递到圆圈log(circle data:);
d3.selectAll(g circle)。each(function(d){console.log(d.name);});

//现在更改数据,并相应地更新组的数据
data = [{id:A,name:carol},{id :B,name:diane},{id:C,name:susan}];
svg.selectAll(g)。data(data,function(d){return d.id;});

//这些是更改的结果:
console.log(更改后,组具有:);
d3.selectAll(g)。each(function(d){console.log(d.name);});
console.log(the circles still have:);
d3.selectAll(g circle)。each(function(d){console.log(d.name);});

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


  1. 解决方案

selection.select 会隐式执行此操作。 ( selection.append selection.insert 的实现实际上是基于 selection.select internal)

  svg.selectAll(g)。 $ b  


  • 您可以使用函数显式重做数据连接以接收父数据,

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


  • 第一个选项依赖于select中的一些特殊行为,所以它可能有点令人惊讶,但它是很好的,因为它使节点更新的模式与通过插入/附加节点创建的模式对称。第二个选项是有用的,如果你需要应用任何更改的数据,因为它正在传播。



    这里有另一篇文章,你没有链接到这可能是有用的:加入思考


    I can't work out how best to pass changes to the data which occur at a parent node (e.g. an SVG g element) down to it's children (e.g. SVG circle elements).

    I've read this and this but still can't figure it out.

    Here's a minimum working example. The example assumes you've got an object called svg which refers to a d3 selection containing an SVG element.

    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); });   
    

    Can anyone help me find a concise way to get the new names into all the child elements of a group? In my real-life example, each g contains many circles.

    解决方案

    There are 2 ways to propagate the data from parents to children:

    1. selection.select will do this implicitly. (The implementations of selection.append and selection.insert are actually based on selection.select internally)

      svg.selectAll("g").select("circle")
      

    2. You can explicitly redo the data join using a function to receive the parent data and return it in an array for the child.

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

    These amount to the same thing. The first option relies on some special behaviour in select so it can be a bit surprising at first, but it is nice in that it makes the pattern for node update symmetrical with the pattern for node creation via insert/append. The second option is useful if you need to apply any changes to the data as it is being propagated.

    Here's another article you didn't link to that might be useful also: Thinking with Joins

    这篇关于d3js:使新的父数据下降到子节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆