D3: attrTween не работает

1

Я создаю Sunburst в d3 v3 на примере здесь. Я не могу понять, почему attrTween() не работает в следующем случае.

path.transition()
  .duration(750)
  .attrTween("d", function(d) {
    var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
        yd = d3.interpolate(y.domain(), [d.y, 1]),
        yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]);
    return function(d, i) {
      var p = i
          ? function(t) { return arc(d); }
          : function(t) { x.domain(xd(t)); y.domain(yd(t)).range(yr(t)); return arc(d); };
      return p
    };
  })

При нажатии любой из дуги появляется следующая ошибка.

Ошибка: атрибут d: ожидаемая команда пути moveto ('M' или 'm'), "function (t) {x...".

Однако, определяя функцию arcTween() как следующую и вызывающую как это .attrTween("d", arcTween(d)) работает нормально.

function arcTween(d) {
  var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
      yd = d3.interpolate(y.domain(), [d.y, 1]),
      yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]);
  return function(d, i) {
    return i
        ? function(t) { return arc(d); }
        : function(t) { x.domain(xd(t)); y.domain(yd(t)).range(yr(t));return arc(d); };
 };
}
Теги:
d3.js

1 ответ

2
Лучший ответ

Рабочий код использует объявление функции для определения function arcTween(d) { }. Использование этой функции в .attrTween("d", arcTween(d)) фактически выполнит эту функцию, проходящую в аргументе d из закрывающей функции click(d), которая является привязкой к элементу, на который пользователь нажал. Этот вызов используется для захвата/закрытия этого значения d в интерполяторах xd, yd и yr, которые, в свою очередь, используются в возвращенной внутренней функции. Эта возвращаемая функция является той, которая выполняется с помощью .attrTween() чтобы вернуть интерполятор, используемый для перехода.

В вашем коде при попытке встроить объявление функции вы упускаете вышеупомянутый вызов внешней функции. Следовательно, вы получаете недопустимое возвращаемое значение, потому что ваши функции слишком глубоко вложены.

Тем не менее, есть простой способ заставить ваш код работать: просто добавьте (d) после встроенной функции, чтобы выполнить ее так же, как и предыдущий код.

function click(d) {             // This d is what needs to be captured

  path.transition()
    .duration(750)
    .attrTween("d", function(d) {
      // var...                // This is where the outer d is closed over/captured
      return function(d, i) {  // This is another d not to be confused with the outer one
        // ...
      };
    }(d))                      // This will execute the function passing in click d

}

Посмотрите обновленный Plunk для рабочей демонстрации.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню