如何通过模拟同步进行 d3 更新

Posted

技术标签:

【中文标题】如何通过模拟同步进行 d3 更新【英文标题】:how to do d3 updating in lockstep with simulation 【发布时间】:2013-01-28 13:46:53 【问题描述】:

我正在使用 d3 编写一个模拟演示。我想展示解决方案状态的演变。

如果我在模拟循环中嵌入 d3 渲染,那么浏览器直到最后都不会显示任何内容。应该很忙吧。

我想要实现的是在主循环中进行一些计算、一些 d3 更新,然后等待所有转换完成。

由于转换是异步的,我无法找到等待它们的方法。

使用 setInterval 来运行主循环是可行的,但不是很好。

是否有“通常”的方法来实现使用 d3 转换锁定步长计算的目标?

【问题讨论】:

【参考方案1】:

使用 html5,您还可以采用不同的方法来解决此问题:让模拟发生在单独的线程 Web Worker 中,并让它在每次迭代时将结果传递回主显示线程。

http://www.html5rocks.com/en/tutorials/workers/basics/

事实上,你的应用程序几乎是完美的。

【讨论】:

【参考方案2】:

是的,就像你说的那样,如果你的模拟是同步运行的(例如在一个 for 循环中),那么浏览器永远没有机会呈现中间状态。

使用 setInteval 实际上是一个合理的解决方案,但您必须确保间隔至少与最长(基于 d3)的转换一样长。

但听起来您真正想要的是通过回调或事件准确地知道转换何时完成,然后调用模拟的 step 函数来推进状态。在这种情况下,请在此处阅读:Invoke a callback at the end of a transition。

虽然我从未尝试过这种方法,但我猜如果您要转换多个元素,那么转换的end 事件将被多次调用——每个转换元素一次。在这种情况下,您必须做一些工作才能将它们合并为一个事件。您可能必须“计算”调用end 事件的次数,并且仅在计数与预期的元素数量匹配时才对其进行操作。或者,您可以编写条件代码以仅绑定到单个元素的转换——转换最后开始或预计最后结束的元素。

希望这会有所帮助...

【讨论】:

以上是关于如何通过模拟同步进行 d3 更新的主要内容,如果未能解决你的问题,请参考以下文章

如何在 d3.js 中同步地图和点图层的比例和位置?

如何在 AngularJS 中进行模拟同步 AJAX 调用?

如何从同步代码中返回任务以进行模拟实现

使用 Laravel 同步或更新 ExistingPivot -- 如何根据第三个条件进行填充

如何通过媒体基础使用英特尔 Quicksync 进行解码?

Android:测试同步适配器