如何在d3.js中加速力布局动画

8gsdolmq  于 2023-10-19  发布在  其他
关注(0)|答案(3)|浏览(134)

我正在使用D3.js渲染大约500个节点和它们之间的链接。布局通常需要10秒才能稳定下来(迭代收敛)。
我如何加快整个过程,比如说,节点在动画过程中移动速度提高了2倍。那么时间将是50%(用于迭代的CPU时间应该远小于10秒,但我如何才能减少动画时间)。
我试过:
1.手动管理for循环中的tick(),并使其达到一定的次数,比如100次,这样会更快,但动画会对用户隐藏,这是一个很大的损失。
1.增加链接强度将有所帮助,节点在动画期间移动得更快。但是布局是非常敏感的,任何微小的拖动都可能导致许多节点移动。
有什么建议吗?谢谢.

vs91vp4v

vs91vp4v1#

看看this thread,它有很多关于这个主题的好信息。
您可能会尝试实现的来自该线程的一个建议是在单个requestAnimationFrame回调中多次调用force.tick(),然后更新节点和链接位置,然后循环直到force.alpha达到0(或您希望alpha阈值为的任何值)。试试这样的方法:

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

这将每3个滴答或3倍速度渲染一次。根据需要调整ticksPerRender值。
HERE是一个简单的演示。在本例中,我使用了force.on('start', callback)来调用上述呈现逻辑。这意味着当开始拖动交互时,它将自动被再次调用。

0yg35tkg

0yg35tkg2#

在ticked事件处理程序中注入一个或多个调用可能会更好,requestAnimationFrame方法会在带有触摸板的MacBook环境中导致一个奇怪的错误。

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

相关问题