22

我正在寻找与jQuery.fx.off = true.

假设您正在为使用 D3 的应用程序编写测试(使用 Mocha、QUnit 等)。该应用程序有一些 D3 动画(带有.transition())。

动画对于测试来说真的很糟糕:

首先,它们很慢。

其次,由于它们是异步的,它们很容易导致闪烁测试。理想情况下,您希望避免对setTimeout/ setInterval/的任何调用requestAnimationFrame

有没有办法禁用所有 D3 动画,以便它们立即(理想情况下,同步地)跳转到结束状态?(也许如果没有选项,我们可以挂钩timer.js?)

4

4 回答 4

13

模拟转换的另一种方法是直接同步执行它们到最终状态。

使用 D3.js v4,使用:

function flushAllD3Transitions() {
    var now = performance.now;
    performance.now = function() { return Infinity; };
    d3.timerFlush();
    performance.now = now;
 }

使用 D3.js v3 及之前的版本,请执行以下操作:

function flushAllD3Transitions() {
    var now = Date.now;
    Date.now = function() { return Infinity; };
    d3.timer.flush();
    Date.now = now;
 }

另见d3 问题 1789

于 2014-03-21T07:10:05.727 回答
6

我不知道在 d3 中执行此操作的本地方式。但是您可以通过扩充 d3 原型轻松修改 d3 选择器 API 以跳过动画:

要动画的 HTML 代码:

<svg width="200" height="200">
    <rect x="1" y="1" width="0" height="100" />
</svg>

动画和 D3 增强代码:

function animate(color){
    d3.selectAll("rect")
    .attr("width", 0).attr("fill", "white")
    .transition().duration(1000)
    .attr("width", 100).attr("fill", color)
}

function augment(){
    // add a duration function to the selection prototype
    d3.selection.prototype.duration   = function(){ return this }
    // hack the transition function of d3's select API
    d3.selection.prototype.transition = function(){ return this }
}

animate("red")
console.log("normal animation done")
setTimeout( function(){
        augment()
        console.log("d3 hacked!")
        animate("green")
        console.log("animation skipped")
}, 1200 )

注意力!此 hack 可能无法为您提供完整的解决方案。您可能希望使用您在应用程序transition().*中不可用的其他功能来扩展此解决方案。d3.selection.prototype您还可以考虑 d3 支持的其他形式的动画。也许还有更多<selection>.transition()我不知道的。

于 2013-03-13T14:22:52.450 回答
2

好像你可以模拟 d3.timer 功能:

var d3timer = d3.timer;

d3.timer = function(callback, delay, then) {
    d3timer(callback, 0, 0);
};
于 2016-02-07T20:16:20.470 回答
1

您可以采取的一种方法是在您的测试套件中使用假计时器,例如Sinon,它与 Mocha 或 QUnit 一起使用。Jasmine 还内置了一个模拟计时器。我认为这是一种更好的方法,因为它意味着您正在测试的代码更接近正在运行的代码(而不是破坏转换函数)。

于 2013-05-09T18:53:27.093 回答