d3 — солнечные лучи — переход с учетом обновленных данных, пытающихся анимировать, а не привязать

Я работаю над солнечными лучами на основе масштабируемых солнечных лучей Майка Бостока.

Я хочу иметь возможность изменять базовые данные, используя совершенно новый JSON (который имеет ту же структуру, но разные значения «размера»), и чтобы солнечные лучи анимировали переход, чтобы отразить обновленные данные.

Если я изменю данные элементов пути с помощью .data(), а затем попытаюсь обновить следующим образом:

path.data(partition.nodes(transformed_json))
    .transition()
    .duration(750)
    .attrTween("d", arcTween(transformed_json));

(.. это почти тот же код, что и щелчок fn)

function click(d) {
   path.transition()
       .duration(750)
       .attrTween("d", arcTween(d));
}

... Я обнаружил, что солнечные лучи правильно меняются, отражая новые данные, но они встают на место, а не плавно переходят, как это происходит при увеличении.

http://jsfiddle.net/jTV2y/ ‹-- Вот jsfiddle с изолированной проблемой (переход происходит через одну секунду после того, как вы нажмете «Выполнить»)

Я предполагаю, что мне нужно создать другой arcTween() fn, но моего понимания d3 еще нет. Большое спасибо!


person Stu Blair    schedule 10.03.2014    source источник


Ответы (1)


Ваш пример очень похож на пример с разделом Sunburst, который также обновляет данные с переходом. Разница в том, что в этом примере это одни и те же базовые данные с разными методами доступа к значениям. Это означает, что вы не можете сохранить предыдущее значение в данных (поскольку оно будет другим), а нужно поместить его куда-то еще (например, в элемент DOM).

Обновленная функция анимации выглядит следующим образом:

function arcTweenUpdate(a) {
  var i = d3.interpolate({x: this.x0, dx: this.dx0}, a);
  return function(t) {
    var b = i(t);
    this.x0 = b.x;
    this.dx0 = b.dx;
    return arc(b);
  };
}

Для этого требуется, как и в исходном примере, сохранить исходные значения x и dx:

.enter().append("path")
.each(function(d) {
      this.x0 = d.x;
      this.dx0 = d.dx;
  });

Полный пример здесь. У этого есть какой-то странный переход, вызванный другим порядком данных в макете. Вы можете отключить это, вызвав .sort(null), см. здесь.

person Lars Kotthoff    schedule 11.03.2014