D3: почти одинаковые коды, разные результаты

Я пытаюсь применить это предложение, чтобы поймать конец нескольких переходов. Но в моем локальном файле появляется Uncaught TypeError: t.call is not a function ошибка. Код выглядит следующим образом:

    var svg = d3.select('svg');

  function endall(transition, callback) { 
    if (typeof callback !== "function") throw new Error("Wrong callback in endall");
    if (transition.size() === 0) { callback() }
    var n = 0; 
    transition 
        .each(function() { ++n; }) 
        .each("end", function() { if (!--n) callback.apply(this, arguments); }); 
  } 


for (var i=0;i<5;i++) {

    svg.append('rect')
            .attr("x",i*60)
      .attr("y",50)
      .attr("height",50)
      .attr("width",50)
      .style("fill","#ff0000");
}

    svg.selectAll("rect:not(.active)")
      .transition()
      .duration(1000)
      .style("fill","#00ff00")
      .call(endall, function() { alert("all done") });

Когда я портирую его на jsfiddle с использованием шаблона D3, он работает хорошо. С другой стороны, когда я портирую его на jsfiddle без шаблона D3, я получаю ту же ошибку.

Видно чего-то не хватает, но что не могу понять.


person tic    schedule 07.09.2018    source источник


Ответы (1)


Скрипка, которая не вызывает ошибки, работает на v3, а та, которая действительно работает, на v5.

В d3v3 вы можете использовать transition.each("end",...) для событий:

transition.each ([тип,] слушатель)

Если указан тип, добавляет слушателя для событий перехода, поддерживающего события «начало», «конец» и «прерывание». Слушатель будет вызываться для каждого отдельного элемента в переходе. (v3 docs)

В d3v4 и v5 этот метод был заменен на transition.on("end",...) для событий:

selection.on (typenames [, listener [, options]]) ‹>

Добавляет или удаляет слушателя для каждого выбранного элемента для указанных типов событий. (текущие документы)

transition.each(function) по-прежнему можно использовать для выполнения действий с каждым перемещаемым элементом, но нельзя использовать для прослушивания событий. Из-за этого изменения между версиями вы получаете сообщение об ошибке: t.call не является функцией (это строка: "end"), и предупреждение никогда не срабатывает.

Для d3v4 или d3v5 вместо этого используйте:

transition 
    .each(function() { ++n; }) 
    .on("end", function() { if (!--n) callback.apply(this, arguments); }); 

Обновленная скрипка.

person Andrew Reid    schedule 07.09.2018
comment
Основные версии очень важны для библиотек javascript, и, по-видимому, jsfiddle не поддерживает их в массовом порядке (собирался опубликовать гораздо менее подробный ответ, аналогичный вашему, браво, победив меня как минимум на 3 минуты: )) - person Thymine; 08.09.2018