使用 D3 强制布局,子元素不会继承父数据
Children elements didn't inherit parent data with D3 force layout
我创建了一个 d3 force 布局,效果很好。
我的主要代码是这样的:
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()
也是我的data.Am我对吧?
其实我的数据节点是后端的,数据是更新的。例如,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/
这是 d3
的一个奇怪行为。如果我理解正确(未被授予),selection.data(...)
会自动将数据传输到 child 元素,除非它们已经绑定了一些数据。
在你的情况下,这意味着你需要将数据"by hand"复制到每个child:
//select any child node, then:
.each(function() {
d3.select(this).datum(d3.select(this.parentNode).datum());
})
注意:在你的fiddle中,你只在enter()
选择中设置了xlink:href
:这是错误的,你需要在整个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;
});
我创建了一个 d3 force 布局,效果很好。 我的主要代码是这样的:
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()
也是我的data.Am我对吧?
其实我的数据节点是后端的,数据是更新的。例如,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/
这是 d3
的一个奇怪行为。如果我理解正确(未被授予),selection.data(...)
会自动将数据传输到 child 元素,除非它们已经绑定了一些数据。
在你的情况下,这意味着你需要将数据"by hand"复制到每个child:
//select any child node, then:
.each(function() {
d3.select(this).datum(d3.select(this.parentNode).datum());
})
注意:在你的fiddle中,你只在enter()
选择中设置了xlink:href
:这是错误的,你需要在整个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;
});