【问题标题】:How to speed up the force layout animation in d3.js如何加快d3.js中的强制布局动画
【发布时间】:2014-10-03 23:53:27
【问题描述】:

我正在使用 D3.js 来渲染大约 500 个节点和它们之间的链接。布局通常需要 10 秒才能稳定下来(迭代收敛)。

我如何加快整个过程,比如说,节点在动画期间移动的速度提高了 2 倍。那么时间将是 50%(用于迭代的 CPU 时间应该远小于 10 秒,但是我怎样才能减少动画时间)。

我试过了:

  1. 在 for 循环中手动管理 tick() 一定次数,比如 100 次,速度会更快,但动画会对用户隐藏,这是一个很大的损失。
  2. 增加链接强度会有所帮助,节点在动画期间移动得更快。但是布局非常敏感,任何小的拖动都可能导致许多节点移动。

有什么建议吗?谢谢。

【问题讨论】:

  • 如果您跳过刻度事件进行绘图,请使用过渡而不是仅设置节点位置。这样布局看起来仍然流畅。

标签: javascript d3.js


【解决方案1】:

查看this thread,其中有很多与此主题相关的好信息。

您可能尝试实施的该线程的一个建议是在单个requestAnimationFrame 回调中多次调用force.tick(),然后更新节点和链接位置,然后循环直到force.alpha 达到0(或其他你希望你的阿尔法阈值是)。试试这样的:

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) 来调用上述渲染逻辑。这意味着在开始拖动交互时会自动再次调用它。

【讨论】:

  • 这是一个很好的建议,我目前正在寻找一种测量浏览器性能的方法,并结合修改浏览器渲染端的负载,这是调整设置的好方法。
  • @jshanley 我不知道这是否仍然有效。我正在更改您 plunkr 上的滴答计数,但我看不出有什么不同。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2013-06-14
    • 1970-01-01
    • 2015-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-02
    • 2013-07-15
    • 2012-10-11
    相关资源
    最近更新 更多