I have created a d3 force layout,and works very well. My mainly code like so:
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();
As is known to us, d3.selectAll(".node").data() is my data. Because the child elements of g will inherit the data from the parent data, d3.selectAll(".nodeimage").data()
is also my data.Am I right?
In fact, my data nodes is from backend, and the data is updated. For example, some properties like np
have been changed from 0 to 1. We consider the result is
nodes = [{id:1, n:'n_1',np:'1'},{id:2, n:'n_2',np:'0'}]
;
I need to call the function above again. However,d3.selectAll(".node").data()
is right, while d3.selectAll(".nodeimage").data()
is wrong now.
The following code will not work well.
d3.selectAll('.nodeimage').attr("test", function(d){
//d.np is a wrong value.
});
Any suggestions for me?
Here is my demo of jsfiddle:http://jsfiddle.net/bpKG4/663/
This is a strange behavior of d3
. If I understand correctly (which is not granted), selection.data(...)
automatically transfers data to child elements, unless they already have some data binded.
In your case, it means that you need to copy "by hand" the data to each child:
//select any child node, then:
.each(function() {
d3.select(this).datum(d3.select(this.parentNode).datum());
})
NB: in your fiddle, you only set the xlink:href
in the enter()
selection: this is wrong, you need to set it within the whole update
selection.
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;
});
See here: http://jsfiddle.net/cs4xhs7s/1/