问题
I've got a tree layout. As shown in this JSBin http://jsbin.com/AbOmAZE/11/
On a click event on the text associated with a node, I would like the data behind the visualization to be updated (I need to update the data behind the tree layout, as it is used as an interface). I have the redraw and the click event already implemented, however I am not sure how to update the data just from knowing the current selection returned from the click function.
node.append("text")
.text(function(d){ return d.name; })
.on('click', function(d){
var result = prompt('Change the name of the node',d.name)
if(!result) {
d.name = result; // !!! This is where the problem is.
}
console.log(d)
draw(); //This redraws the graph
})
Please refer to the JSBin posted above.
回答1:
After playing around with D3 for 2 months I finally understand exactly what I was confused about:
I was looking for a way to extract the data after it has been updated using d3.
This is fairly simple and involves two main steps:
Get the data array
For this step you simply have to select the element you originally binded the data to using .data() - in this case it is the .nodes element
var node = d3.select('svg').select('.nodes')
Then you need to get the data using the .data() function. This returns an array for each node available. Since you want the data for the whole tree, select the node root by getting the data of the first item in the array with [0]
var data = node.data()[0]
Filter the data
Now we have the data, however running d3.tree(data) has added several attributes like 'x' and 'y' values. To get an array which resembles the one you originally put in you need a recursive filtering function:
function filter(data) { for(var i in data){ if(["depth","x","x0","y","y0","parent","size"].indexOf(i) != -1){ delete data[i]; } else if (i === "children") { for (var j in data.children) { data.children[j] = filter(data.children[j]) } } } return data; }
Now you have an array with the updated info as modified by d3, without any of the extra attributes d3 has added in the process. This array can now be saved back to the database.
Too see a fully working example, check out this jsbin.
回答2:
The problem is that you tried to redraw
the tree view. d3
's enter
, update
and exit
selections take care of the change in the underlying data. I have modified the jsbin here and it updates the nodes as accordingly.
node.append("text")
.text(function(d){ return d.name; })
.on('click', function(d){
console.log(d);
var result = prompt('Change the name of the node',d.name);
if(result) {
d.name = result;
var node = canvas.selectAll('.node').data(nodes);
node.select('text')
.text(function(d){ return d.name; });
}
});
来源:https://stackoverflow.com/questions/20534883/update-data-behind-the-visualization