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

Jo *_*iss 21 animation d3.js

我正在寻找相当于D3的D3 jQuery.fx.off = true.

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

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

首先,它们很慢.

其次,因为它们是异步的,所以它们很容易导致闪烁测试.理想情况下,您希望避免对setTimeout/ setInterval/进行任何调用requestAnimationFrame.

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

rbu*_*rbu 13

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

使用D3.js v4,使用:

function flushAllD3Transitions() {
    var now = performance.now;
    performance.now = function() { return Infinity; };
    d3.timerFlush();
    performance.now = now;
 }
Run Code Online (Sandbox Code Playgroud)

使用D3.js v3和之前的版本,执行:

function flushAllD3Transitions() {
    var now = Date.now;
    Date.now = function() { return Infinity; };
    d3.timer.flush();
    Date.now = now;
 }
Run Code Online (Sandbox Code Playgroud)

另见d3 issue 1789.


Juv*_*uve 6

我不知道在d3中这样做的本地方式.但您可以通过扩充d3原型轻松修改d3选择器API以跳过动画:

要动画的HTML代码:

<svg width="200" height="200">
    <rect x="1" y="1" width="0" height="100" />
</svg>
Run Code Online (Sandbox Code Playgroud)

动画和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 )
Run Code Online (Sandbox Code Playgroud)

注意!这个hack可能不适合作为一个完整的解决方案.您可能希望使用应用程序transition().*中未使用的其他功能扩展此解决方案d3.selection.prototype.您还可以考虑d3支持的其他形式的动画.也许还有更多<selection>.transition()我不知道的事情.