В D3.js переходы (transitions) реализуют механизм плавного изменения
свойств DOM-элементов во времени. Каждый вызов
.transition() создаёт новый объект перехода, который
управляет интерполяцией значений атрибутов и стилей.
Ключевая особенность системы — переходы не модифицируют элементы напрямую, а создают временный слой анимации, привязанный к выбранной коллекции DOM-узлов.
Каждый переход характеризуется:
duration)delay)ease)attr,
style, text, tween).transition()При вызове:
d3.select("circle")
.transition()
.attr("r", 50);
создаётся переход первого уровня. Он захватывает текущее состояние элемента и вычисляет промежуточные значения до конечного состояния.
Если после этого добавить второй .transition(),
возникает важный эффект:
d3.select("circle")
.transition()
.attr("r", 50)
.transition()
.attr("fill", "red");
Здесь формируется цепочка последовательных переходов.
.transition().transition()Каждый вызов .transition() на результате предыдущего
перехода создаёт новый независимый переход,
который:
Таким образом формируется последовательность анимационных фаз.
Механизм можно представить как конвейер:
Transition A → Transition B → Transition C
Каждый следующий переход ждёт завершения предыдущего.
При цепочке:
d3.select("rect")
.transition()
.duration(1000)
.attr("width", 200)
.transition()
.duration(500)
.attr("height", 100);
поведение следующее:
width за 1000 мсheight за 500 мсВажно, что второй .transition() создаёт новый объект
перехода, а не расширяет первый.
Каждый переход фиксирует стартовое состояние в момент своего запуска. Это означает:
Это принципиально отличает D3-переходы от CSS-анимаций, где возможны кумулятивные эффекты трансформаций.
.transition()Рассмотрим расширенную цепочку:
d3.select("circle")
.transition()
.attr("r", 20)
.transition()
.attr("cx", 100)
.transition()
.style("fill", "blue");
Формируется линейная последовательность из трёх фаз:
Каждый этап выполняется строго после завершения предыдущего.
Цепочка:
selection
.transition()
.attr("r", 10)
.transition()
.attr("r", 20);
Последовательное выполнение.
Параллельные переходы:
selection
.transition("a")
.attr("r", 10);
selection
.transition("b")
.attr("fill", "red");
Здесь создаются независимые переходы с разными именами. Они могут выполняться одновременно, если не конфликтуют по атрибутам.
Если два последовательных перехода изменяют один и тот же атрибут, применяется последний активный переход:
d3.select("rect")
.transition()
.attr("width", 100)
.transition()
.attr("width", 300);
Результат:
Фактически итоговое значение определяется последним переходом в цепочке.
Каждый .transition() создаёт объект типа Transition,
который:
t0tПри цепочке:
T1.start → T1.end → T2.start → T2.end
D3 автоматически ставит T2 в очередь исполнения, используя завершение T1 как триггер.
delay на
цепочкиЗадержка применяется к каждому переходу независимо:
d3.select("circle")
.transition()
.delay(500)
.attr("r", 30)
.transition()
.delay(200)
.attr("fill", "green");
Фактическое время исполнения:
Важно: delay второго перехода не суммируется с первым, а применяется отдельно к его старту.
duration на последовательностьДлительность каждого перехода формирует общую временную структуру цепочки:
Ttotal = duration1 + duration2 + ... + durationN
При этом переходы не перекрываются, если явно не заданы независимые таймеры.
Каждый переход вычисляет интерполяцию заново:
t → valueПри переходе к следующему .transition() предыдущая
функция уничтожается и заменяется новой.
Если в процессе выполнения цепочки вызывается новый переход на тот же selection:
const sel = d3.select("circle");
sel.transition()
.attr("r", 10);
setTimeout(() => {
sel.transition()
.attr("r", 50);
}, 200);
поведение:
Это разрушает цепочку и создаёт новую ветку анимации.
d3.select("g")
.transition()
.attr("transform", "translate(100,0)")
.transition()
.style("opacity", 1)
.transition()
.attr("transform", "translate(200,0)");
Используется для поэтапного раскрытия визуализации.
d3.selectAll("circle")
.transition()
.attr("r", 5)
.transition()
.style("opacity", 1);
Каждый этап отвечает за отдельную фазу визуального появления.
d3.select("path")
.transition()
.attr("d", line1)
.transition()
.attr("d", line2)
.transition()
.attr("d", line3);
Используется для морфинга форм.
.transition().transition()selection.transition и
transition.transitionЦепочка:
selection.transition().transition()
отличается от:
const t = selection.transition();
t.transition();
В обоих случаях создаётся новый переход, но контекст выполнения может отличаться при работе с именованными переходами и группами элементов.
Цепочка .transition().transition() в D3.js представляет
собой последовательный исполнительный механизм, где:
.transition() перезапускает модель
времениТакая структура позволяет строить детерминированные анимационные сценарии с чётко заданной последовательностью изменений.