子元素没有继承D3力布局的父数据

时间:2016-05-20 12:27:43

标签: d3.js force-layout selectall

我创建了一个d3力布局,效果很好。 我的主要代码是这样的:

var nodes = [{id:1, n:'n_1',np:'0'},{id:2, n:'n_2',np:'0'}];//just for demo
//1. set data
var update = svg.selectAll(".node").data(nodes);
//2. enter
update.enter().append("svg:g").attr("class", "node")
.call(function(p){
  p.append("svg:image").attr("class", "nodeimage");
  p.append("svg:text").attr("class", "nodetext");
});
//3. exit
update.exit().remove();

正如我们所知,d3.selectAll(“。node”)。data()是我的数据。因为g的子元素将继承父数据中的数据,d3.selectAll(".nodeimage").data()也是我的数据。我是对的吗?

实际上,我的数据节点来自后端,并且数据已更新。例如,某些属性(如np)已从0更改为1.我们认为结果是 nodes = [{id:1, n:'n_1',np:'1'},{id:2, n:'n_2',np:'0'}];

我需要再次调用上面的函数。但是,d3.selectAll(".node").data()是正确的,而d3.selectAll(".nodeimage").data()现在是错误的。

以下代码无效。

d3.selectAll('.nodeimage').attr("test", function(d){
    //d.np is a wrong value.
});

对我有什么建议吗?

以下是我的jsfiddle演示:http://jsfiddle.net/bpKG4/663/

1 个答案:

答案 0 :(得分:1)

这是d3的奇怪行为。如果我理解正确(未授权),selection.data(...)会自动将数据传输到子元素,除非它们已经绑定了一些数据。

在您的情况下,这意味着您需要“手动”将数据复制到每个孩子:

  //select any child node, then:
    .each(function() {
      d3.select(this).datum(d3.select(this.parentNode).datum());
    }) 

注意:在您的小提琴中,您只在xlink:href选项中设置了enter():这是错误的,您需要在整个update选项中进行设置。

update.selectAll(".nodeimage") 
          .each(function() {
             d3.select(this).datum(d3.select(this.parentNode).datum());
          }) 
          .attr("xlink:href", function(d){
            var img;
            if(d.np == 1){
                img = "http://www.gravatar.com/avatar/1eccef322f0beef11e0e47ed7963189b/?default=&s=80"
            }else{
                img = "http://www.gravatar.com/avatar/a1338368fe0b4f3d301398a79c171987/?default=&s=80";
            }
            return img;
          });

见这里:http://jsfiddle.net/cs4xhs7s/1/