<分区>
有什么方法可以禁用 D3 力导向图中的动画吗?
我正在处理这个例子:https://bl.ocks.org/mbostock/4062045
我想在没有初始动画的情况下渲染图形,也就是说,在它们的最终位置显示所有节点和链接。
<分区>
有什么方法可以禁用 D3 力导向图中的动画吗?
我正在处理这个例子:https://bl.ocks.org/mbostock/4062045
我想在没有初始动画的情况下渲染图形,也就是说,在它们的最终位置显示所有节点和链接。
最佳答案
尽管这个问题已经有了 accepted answer , 建议的解决方案不是在 D3 力图中禁用动画的正确方法。浏览器仍在移动节点和链接!您只是没有看到它们在移动,但浏览器正在移动它们,进行大量计算并浪费大量时间/资源。此外,您不需要服务器端。
我的回答提出了一个不同的解决方案,实际上不绘制动画。你可以在 this code 中看到它例如,由 Mike Bostock(D3 创作者)创作。
当您了解什么是 tick
函数时,这个解决方案很容易遵循:它只是一个计算模拟中所有位置并前进一步的函数。尽管绝大多数 D3 力导向图在每个刻度处绘制节点和链接,但您不需要这样做。
以下是您可以执行的操作:
在定义之后立即使用 stop()
停止模拟:
var simulation = d3.forceSimulation(graph.nodes)
.force("link", d3.forceLink().id(function(d) { return d.id; }))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2))
.stop();//stop the simulation here
让模拟运行不绘制任何东西。这是最重要的一步:您不必在每个刻度时移动元素。在这里,我运行了 300 个刻度,这大约是默认数字:
for (var i = 0; i < 300; ++i) simulation.tick();
然后,只需使用模拟创建的属性 (x
, y
, source
, target
) 绘制圆和线,一次:
node.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
以下是仅包含这些更改的链接 block :http://bl.ocks.org/anonymous/8a4e4e2fed281ea5e2a5c804a9a03783/85ced3ea82a4bed20a2010530562b655d8f6e464
将此解决方案的时间与“隐藏节点”解决方案(接受的答案)的时间进行比较。这里的速度更快。在我的测试中,我得到了这个结果:
也就是说,快了 25 倍。
PS:为简单起见,我删除了 fork block 中的 ticked
函数。如果要拖动节点,只需将其添加回去即可。
编辑 D3 v5.8
现在 D3 v5.8 允许将交互次数传递给 simulation.tick()
,您甚至不再需要 for
循环。所以,而不是:
for (var i = 0; i < 300; ++i) simulation.tick();
你可以这样做:
simulation.tick(300);
关于javascript - 如何在力导向图中禁用动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47510853/