禁用所有D3动画(用于测试)

22

我正在寻找一个D3等效的方法来关闭动画,类似于jQuery.fx.off = true

例如你正在为使用D3的应用编写测试(使用Mocha,QUnit等)。该应用包含一些D3动画(使用.transition())。

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

首先,它们很慢。

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

是否有一种方法可以禁用所有D3动画,以便它们立即(最好是同步地)跳到结束状态?(也许如果没有选项,我们可以钩入timer.js?)


d3.timer.flush() 可能会有所帮助。 - Lars Kotthoff
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


对于 d3 版本 4,请参见此答案 - Mark

7

我不知道在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 )

注意!这个方法可能不能完全解决你的问题。你可能需要在这个方法上使用其他 transition().* 函数才能实现你想要的效果,这些函数并不是 d3.selection.prototype 中提供的,你可以在你的应用程序中使用它们。 你也可以考虑使用 d3 支持的其他动画形式。也许有更多我不知道的方式来进行动画,<selection>.transition() 不是唯一选择。


2

看起来你可以模拟d3.timer函数:

var d3timer = d3.timer;

d3.timer = function(callback, delay, then) {
    d3timer(callback, 0, 0);
};

1

你可以采用一种方法,在测试套件中使用虚拟计时器,例如 Sinon,它与Mocha或QUnit兼容。Jasmine也有一个内置的模拟计时器。我认为这是更好的方法,因为这意味着你正在测试的代码更接近正在运行的代码(而不是破坏过渡函数)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接