How to speed up the force layout animation in d3.js

后端 未结 2 570
情书的邮戳
情书的邮戳 2020-12-09 20:49

I am using D3.js for rendering about 500 nodes and links among them. It usually needs 10 seconds for the layout to settle down (the iteration to converge).

How do I

相关标签:
2条回答
  • 2020-12-09 21:26

    Injecting a call / calls within ticked event handler can be better, the requestAnimationFrame method would cause a weird bug on MacBook with touch pad environment.

    function ticked() {
      for (let i = 0; i < 5; i++) {
        force.tick();
      }
    
      link.attr('x1', (d) => d.source.x)
          .attr('y1', (d) => d.source.y)
          .attr('x2', (d) => d.target.x)
          .attr('y2', (d) => d.target.y);
    
      node.attr('transform', (d) => `translate(${d.x}, ${d.y})`);
    }
    
    0 讨论(0)
  • 2020-12-09 21:30

    Check out this thread which has a lot of good info relating to this topic.

    One suggestion from that thread that you might try to implement is to call force.tick() several times within a single requestAnimationFrame callback, then update the node and link positions, and then loop until force.alpha reaches 0 (or whatever you want your alpha threshold to be). Try something like this:

    var ticksPerRender = 3;
    
    requestAnimationFrame(function render() {
    
      for (var i = 0; i < ticksPerRender; i++) {
        force.tick();
      }
    
      // UPDATE NODE AND LINK POSITIONS HERE
    
      if (force.alpha() > 0) {
        requestAnimationFrame(render);
      }
    });
    

    That would render once for every 3 ticks, or 3x speed. Adjust the ticksPerRender value as needed.

    HERE is a simple demo. In this case, I've used the force.on('start', callback) to call the rendering logic described above. This means it will automatically be called again when beginning a drag interaction.

    0 讨论(0)
提交回复
热议问题