I have adapted a D3 force layout example and made it dynamic by loading (slowly changing) data on a timer
var inter = setInterval(function() {
d3.json("http://localhost:5000/my_data", drawGraph);
}, 5000);
This all works, but the graph is redrawn from the starting position every 5s, which is visually distracting. In reality, very little changes from one iteration to the next, and I would like the graph to be laid out again starting from its previous position. Obviously, when a node is added, the graph layout will change; but I hope to minimize the visual disruption, because adding one node should not cause this much movement in the graph.
How can I do that?
I have tried saving and re-loading the positions of the graph nodes, but this does not do anything. Should I save and re-load the positions of the SVG objects representing the nodes? (In my case: circles.) Or can I set the initial positions from which the simulation starts moving the nodes around?
// Load the positions of the nodes, assuming they are available at this point
graph.nodes.forEach(function(o, i) {
if (nodePos.has(o.id)) {
o.x = nodePos.get(o.id).x
o.y = nodePos.get(o.id).y
console.log("< node " + o.id + ":" + o.x + "," + o.y)
}
});
// Compute the layout
var layout = d3.layout.force() // ... code omitted
drawLinks(graph.links);
drawNodes(graph.nodes);
// ...
// Save the positions of the nodes, assuming they are final at this point
graph.nodes.forEach(function(o, i) {
nodePos.set(o.id, {'x': o.x, 'y': o.y});
console.log("> node " + o.id + ":" + o.x + "," + o.y)
});