D3 Force Layout Gradual Update

58 Views Asked by At

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)
      });

0

There are 0 best solutions below