I want the old nodes in the force layout to keep their position/momentum/fixedness, when i update the graph with new nodes.
The update adds and removes nodes and links, but the server only sends {name: _}
, and doesn't know about the rest, i.e. {x: _, y: _, px: _, py: _, fixed: _}
.
Now, I'm manually merging each:
var names = {};
// stores old nodes, indexed by _.name
function merge(nodes) {
for (var i=0; i < nodes.length; i++) {
var next = nodes[i];
var prev = names[nodes[i].name]; // defaults to null
var node = $.extend(true, {}, next, prev); // merge old into new
nodes[i] = node;
names[node.name] = node;
}
return nodes;
}
d3.json(function(error, graph){
merge(graph.nodes)
force.nodes(graph.nodes);
...
}
Is there a better way to do this? Maybe some d3 function that takes the two data (i.e. the old and the new) and outputs one (to be used as the new), that's called by the data join? selection.data()
only takes a key
.
This example replaces the nodes, rather than merging them.
Related: Problems adding and removing nodes in a force-layout using d3.js