Подтвердить что ты не робот

Отключение всех анимаций D3 (для тестирования)

Я ищу эквивалент D3 для jQuery.fx.off = true.

Скажите, что вы пишете тесты (с Mocha, QUnit и т.д.) для приложения, которое использует D3. В приложении есть несколько анимаций D3 (с .transition()).

Анимация действительно плохо для тестов:

Во-первых, они медленны.

Во-вторых, поскольку они асинхронны, они могут легко вызвать мерцающие тесты. В идеале вы бы хотели избежать любых вызовов setTimeout/setInterval/requestAnimationFrame.

Есть ли способ отключить все анимации D3, чтобы они мгновенно (и в идеале, синхронно) переходили в конечное состояние? (Возможно, если нет возможности, мы можем подключиться к timer.js?)

4b9b3361

Ответ 1

Альтернативой издевательствам переходов является их синхронно синхронизировать с их конечным состоянием.

С D3.js v4 используйте:

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

С D3.js v3 и предыдущим, do:

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

См. также d3 issue 1789.

Ответ 2

Я не знаю, как это сделать в d3. Но вы можете легко изменить API-селектор d3, чтобы пропустить анимацию, добавив прототипы d3:

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 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(), о котором я не знаю.

Ответ 3

Один из подходов, который вы можете предпринять, - использовать поддельный таймер в вашем тестовом пакете, например Sinon, который работает с Mocha или QUnit. Жасмин также имеет макет таймера встроенный. Я думаю, что это лучший подход, потому что это означает, что код, который вы тестируете, ближе к текущему коду (в отличие от саботажа функций перехода).

Ответ 4

Похоже, вы можете издеваться над функцией d3.timer:

var d3timer = d3.timer;

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