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

D3: Как правильно перехватывать переходы по разным выборам

Я использую V3 популярной библиотеки d3 и в основном хочу иметь три перехода, за которыми следуют друг за другом. Первый переход должен применяться к выбору выхода, второй - к выбору обновления, а третий - к выбору ввода. Они должны быть соединены цепью таким образом, что когда один из вариантов пуст, его соответствующий переход пропускается. То есть когда нет выбора выхода, выбор обновления должен начинаться немедленно. До сих пор я придумал этот код (используя функцию delay).

// DATA JOIN
var items = d3.select('#data').selectAll('.item');
items = items.data(data, function(d){ 
    return d.twitter_screenname;
});


// EXIT
items.exit().transition().duration(TRANSITION_DURATION).style('opacity', 0).remove();

// UPDATE
// Divs bewegen
items.transition().duration(TRANSITION_DURATION).delay(TRANSITION_DURATION * 1)
    .style('left', function(d, i) {
        return positions[i].left + "px";
    }).style('top', function(d, i) {
        return positions[i].top + "px";
    });

// ENTER
// Divs hinzufügen
var div = items.enter().append('div')
    .attr('class', 'item')
    .style('left', function(d, i) {
        return positions[i].left + "px";
    }).style('top', function(d, i) {
        return positions[i].top + "px";
    });

 div.style('opacity', 0)
    .transition().duration(TRANSITION_DURATION).delay(TRANSITION_DURATION * 2)
    .style('opacity', 1);

Прежде всего, это не позволяет "пропустить" переходы, а во-вторых, я думаю, что есть лучший способ, чем delay. Я просмотрел http://bl.ocks.org/mbostock/3903818, но я действительно не понял, что происходит.

Также, как-то просто писать items.exit().transition().duration(TRANSITION_DURATION).remove() не работает с items, возможно, потому, что они не являются элементами SVG, а div s.

4b9b3361

Ответ 1

Конечно. Вот два способа.

Сначала вы можете использовать явный delay, который вы затем вычисляете с помощью selection.empty. пропустить пустые переходы. (Это лишь незначительная модификация того, что у вас уже есть.)

var div = d3.select("body").selectAll("div")
    .data(["enter", "update"], function(d) { return d || this.textContent; });

// 2. update
div.transition()
    .duration(duration)
    .delay(!div.exit().empty() * duration)
    .style("background", "orange");

// 3. enter
div.enter().append("div")
    .text(function(d) { return d; })
    .style("opacity", 0)
  .transition()
    .duration(duration)
    .delay((!div.exit().empty() + !div.enter().empty()) * duration)
    .style("background", "green")
    .style("opacity", 1);

// 1. exit
div.exit()
    .style("background", "red")
  .transition()
    .duration(duration)
    .style("opacity", 0)
    .remove();

http://bl.ocks.org/mbostock/5779682

Одна сложная вещь заключается в том, что вам нужно создать переход на элементах обновления, прежде чем создавать переход по входящим элементам; thats, потому что enter.append объединяет элементы ввода в выборку обновлений, и вы хотите сохранить их отдельно; подробнее см. Пример перехода только для обновления.

В качестве альтернативы вы можете использовать переход. переход в цепные переходы и transition.each, чтобы применить эти цепные переходы к существующим выборам. В контексте transition.each selection.transition наследует существующий переход, а не создает новый.

var div = d3.select("body").selectAll("div")
    .data(["enter", "update"], function(d) { return d || this.textContent; });

// 1. exit
var exitTransition = d3.transition().duration(750).each(function() {
  div.exit()
      .style("background", "red")
    .transition()
      .style("opacity", 0)
      .remove();
});

// 2. update
var updateTransition = exitTransition.transition().each(function() {
  div.transition()
      .style("background", "orange");
});

// 3. enter
var enterTransition = updateTransition.transition().each(function() {
  div.enter().append("div")
      .text(function(d) { return d; })
      .style("opacity", 0)
    .transition()
      .style("background", "green")
      .style("opacity", 1);
});

http://bl.ocks.org/mbostock/5779690

Я полагаю, что последнее немного более идиоматично, хотя и использует переход. Для применения переходов к выборам (а не для получения переходов с параметрами по умолчанию) не является широко известной функцией.