d3-transition
Переход — это интерфейс, похожий на выбор, для анимации изменений в DOM. Вместо мгновенного применения изменений, переходы плавно интерполируют DOM от текущего состояния к целевому состоянию в течение заданной длительности.
Для применения перехода выберите элементы, вызовите выбор.transition, а затем внесите необходимые изменения. Например:
d3.select("body")
.transition()
.style("background-color", "red"); Переходы поддерживают большинство методов выбора (например, переход.attr и переход.style вместо выбор.attr и выбор.style), но не все методы поддерживаются; например, вы должны добавить элементы или связать данные перед началом перехода. Оператор переход.remove предназначен для удобного удаления элементов по завершении перехода.
Для вычисления промежуточного состояния переходы используют различные встроенные интерполяторы. Цвета, числа и преобразования автоматически обнаруживаются. Строки с вложенными числами также обнаруживаются, что часто встречается во многих стилях (таких как отступы или размеры шрифтов) и путях. Чтобы указать пользовательский интерполятор, используйте переход.attrTween, переход.styleTween или переход.tween.
Установка
Если вы используете NPM, npm install d3-transition. В противном случае загрузите последнюю версию. Вы также можете загрузить напрямую с d3js.org, как отдельную библиотеку или как часть D3 4.0. Поддерживаются среды AMD, CommonJS и vanilla. В vanilla экспортируется глобальная переменная d3:
<script src="https://d3js.org/d3-color.v1.min.js"></script> <script src="https://d3js.org/d3-dispatch.v1.min.js"></script> <script src="https://d3js.org/d3-ease.v1.min.js"></script> <script src="https://d3js.org/d3-interpolate.v1.min.js"></script> <script src="https://d3js.org/d3-selection.v1.min.js"></script> <script src="https://d3js.org/d3-timer.v1.min.js"></script> <script src="https://d3js.org/d3-transition.v1.min.js"></script> <script> var transition = d3.transition(); </script>
Попробуйте d3-transition в вашем браузере.
Справочник API
Выбор элементов
Переходы выводятся из выборов через выбор.transition. Вы также можете создать переход для корневого элемента документа с помощью d3.transition.
выбор.transition([имя]) Исходный код
Возвращает новый переход для данного выбора с указанным именем. Если имя не указано, используется null. Новый переход эксклюзивный только для других переходов с тем же именем.
Если имя — экземпляр перехода, возвращаемый переход имеет тот же идентификатор и имя, что и указанный переход. Если переход с тем же идентификатором уже существует для выбранного элемента, возвращается существующий переход для этого элемента. В противном случае временные параметры возвращаемого перехода наследуются от существующего перехода с тем же идентификатором в ближайшем предке каждого выбранного элемента. Таким образом, этот метод можно использовать для синхронизации перехода через несколько выборов или для повторного выбора перехода для определенных элементов и изменения его конфигурации. Например:
var t = d3.transition()
.duration(750)
.ease(d3.easeLinear);
d3.selectAll(".apple").transition(t)
.style("fill", "red");
d3.selectAll(".orange").transition(t)
.style("fill", "orange"); Если указанный переход не найден в выбранном узле или его предках (например, если переход уже завершен), используются параметры тайминга по умолчанию; однако в будущей версии это, вероятно, будет изменено на ошибку. См. #59.
выбор.interrupt([имя]) Исходный код
Прерывает активный переход указанного имени для выбранных элементов и отменяет любые ожидающие переходы с указанным именем, если таковые имеются. Если имя не указано, используется null.
Прерывание перехода для элемента не влияет на любые переходы для дочерних элементов. Например, переход оси состоит из нескольких независимых, синхронизированных переходов для потомков элемента оси G (линии делений, метки делений, путь области значений и т. д.). Следовательно, для прерывания перехода оси необходимо прервать переходы для дочерних элементов:
selection.selectAll("*").interrupt(); Универсальный селектор , *, выбирает все дочерние элементы. Если вы также хотите прервать сам элемент G:
selection.interrupt().selectAll("*").interrupt(); d3.interrupt(узел[, имя]) Исходный код
Прерывает активный переход указанного имени для указанного узла и отменяет любые ожидающие переходы с указанным именем, если таковые имеются. Если имя не указано, используется null. См. также выбор.interrupt.
d3.transition([имя]) Исходный код
Возвращает новый переход для корневого элемента, document.documentElement, с указанным именем. Если имя не указано, используется null. Новый переход эксклюзивный только для других переходов с тем же именем. Имя также может быть экземпляром перехода; см. выбор.transition. Этот метод эквивалентен:
d3.selection() .transition(name)
Эта функция также может использоваться для проверки наличия переходов (instanceof d3.transition) или для расширения прототипа перехода.
переход.select(селектор) Исходный код
Для каждого выбранного элемента выбирает первый дочерний элемент, соответствующий указанной строке селектора, если таковой есть, и возвращает переход для получившегося выбора. Селектор может быть указан как строка селектора или как функция. Если это функция, она вычисляется для каждого выбранного элемента в порядке, принимая текущие данные d и индекс i, с контекстом this в качестве текущего DOM-элемента. Новый переход имеет тот же идентификатор, имя и временные параметры, что и этот переход; однако, если переход с тем же идентификатором уже существует для выбранного элемента, возвращается существующий переход для этого элемента.
Этот метод эквивалентен получению выбора для этого перехода через переход.selection, созданию подвыбора с помощью выбор.select и затем созданию нового перехода с помощью выбор.transition:
transition .selection() .select(selector) .transition(transition)
переход.selectAll(селектор) Исходный код
Для каждого выбранного элемента выбирает все дочерние элементы, соответствующие указанной строке селектора, если таковые есть, и возвращает переход для получившегося выбора. Селектор может быть указан как строка селектора или как функция. Если это функция, она вычисляется для каждого выбранного элемента в порядке, принимая текущие данные d и индекс i, с контекстом this в качестве текущего DOM-элемента. Новый переход имеет тот же идентификатор, имя и временные параметры, что и этот переход; однако, если переход с тем же идентификатором уже существует для выбранного элемента, возвращается существующий переход для этого элемента.
Этот метод эквивалентен получению выбора для этого перехода через переход.selection, созданию подвыбора с помощью выбор.selectAll и затем созданию нового перехода с помощью выбор.transition:
transition .selection() .selectAll(selector) .transition(transition)
переход.filter(фильтр) Исходный код
Для каждого выбранного элемента выбирает только те элементы, которые соответствуют указанному фильтру, и возвращает переход для получившегося выбора. Фильтр может быть указан как строка селектора или как функция. Если это функция, она вычисляется для каждого выбранного элемента в порядке, принимая текущие данные d и индекс i, с контекстом this в качестве текущего DOM-элемента. Новый переход имеет тот же идентификатор, имя и временные параметры, что и этот переход; однако, если переход с тем же идентификатором уже существует для выбранного элемента, возвращается существующий переход для этого элемента.
Этот метод эквивалентен получению выбора для этого перехода через переход.selection, созданию подвыбора с помощью выбор.filter и затем созданию нового перехода с помощью выбор.transition:
transition .selection() .filter(filter) .transition(transition)
переход.merge(другой) Исходный код
Возвращает новый переход, объединяющий этот переход с указанным переходом другой, который должен иметь тот же идентификатор, что и этот переход. Возвращаемый переход имеет то же количество групп, тех же родителей, то же имя и тот же идентификатор, что и этот переход. Любые отсутствующие (null) элементы в этом переходе заполняются соответствующим элементом, если он присутствует (не null), из перехода другой.
Этот метод эквивалентен получению выбора для данного перехода через переход.выбор, слиянию с выбором, полученным аналогичным образом из другого перехода через выбор.слияние, и затем созданию нового перехода через выбор.переход:
transition .selection() .merge(other.selection()) .transition(transition)
переход.переход() Источник
Возвращает новый переход по тем же выбранным элементам, что и этот переход, запланированный на начало по завершении этого перехода. Новый переход наследует временную метку, равную времени этого перехода плюс его задержку и длительность. Новый переход также наследует имя, длительность и метод сглаживания этого перехода. Этот метод можно использовать для планирования последовательности цепочечных переходов. Например:
d3.selectAll(".apple")
.transition() // First fade to green.
.style("fill", "green")
.transition() // Then red.
.style("fill", "red")
.transition() // Wait one second. Then brown, and remove.
.delay(1000)
.style("fill", "brown")
.remove(); Задержка каждого перехода относительна к предыдущему переходу. Таким образом, в приведенном выше примере яблоки останутся красными в течение одной секунды, прежде чем начнется последний переход к коричневому цвету.
переход.выбор() Источник
Возвращает выбор, соответствующий данному переходу.
d3.активный(узел[, имя]) Источник
Возвращает активный переход на указанном узле с указанным именем, если таковой имеется. Если имя не указано, используется null. Возвращает null, если на указанном узле нет такого активного перехода. Этот метод полезен для создания цепочечных переходов. Например, чтобы начать режим дискотеки:
d3.selectAll("circle").transition()
.delay(function(d, i) { return i * 50; })
.on("start", function repeat() {
d3.active(this)
.style("fill", "red")
.transition()
.style("fill", "green")
.transition()
.style("fill", "blue")
.transition()
.on("start", repeat);
}); См. цепочечные переходы для примера.
Модификация элементов
После выбора элементов и создания перехода с помощью выбор.переход, используйте методы преобразования перехода для изменения содержимого документа.
переход.атрибут(имя, значение) Источник
Для каждого выбранного элемента назначается интерполяция атрибута для атрибута с указанным именем целевому значению. Начальное значение интерполяции — значение атрибута при запуске перехода. Целевое значение может быть задано как константой, так и функцией. Если это функция, она сразу оценивается для каждого выбранного элемента в порядке, получая текущий элемент данных d и индекс i, с this контекстом как текущий элемент DOM.
Если целевое значение равно null, атрибут удаляется при запуске перехода. В противном случае интерполятор выбирается на основе типа целевого значения, используя следующий алгоритм:
- Если значение — число, используйте interpolateNumber.
- Если значение — цвет или строка, преобразуемая в цвет, используйте interpolateRgb.
- Используйте interpolateString.
Для применения другого интерполятора используйте переход.attrTween.
переход.attrTween(имя[, фабрика]) Источник
Если фабрика задана и не равна null, назначается атрибут tween для атрибута с указанным именем заданному интерполятору фабрика. Фабрика интерполятора — функция, возвращающая интерполятор; при запуске перехода фабрика вычисляется для каждого выбранного элемента в порядке, получая текущий элемент данных d и индекс i, с this контекстом как текущий элемент DOM. Возвращённый интерполятор будет вызываться для каждой фазы перехода в порядке, получая значение сглаженного времени t, обычно в диапазоне [0, 1]. Наконец, возвращаемое значение интерполятора будет использоваться для установки значения атрибута. Интерполятор должен возвращать строку. (Чтобы удалить атрибут в начале перехода, используйте переход.атрибут; чтобы удалить атрибут в конце перехода, используйте переход.on для прослушивания события end.)
Если заданная фабрика равна null, удаляется ранее назначенная интерполяция атрибута указанного имени, если таковая имеется. Если фабрика не задана, возвращается текущий интерполятор для атрибута с указанным именем или undefined, если такого tween не существует.
Например, для интерполяции атрибута fill от красного до синего:
transition.attrTween("fill", function() {
return d3.interpolateRgb("red", "blue");
}); Или для интерполяции от текущего значения fill до синего, как в переход.атрибут:
transition.attrTween("fill", function() {
return d3.interpolateRgb(this.getAttribute("fill"), "blue");
}); Или для применения пользовательского интерполятора радуги:
transition.attrTween("fill", function() {
return function(t) {
return "hsl(" + t * 360 + ",100%,50%)";
};
}); Этот метод полезен для указания пользовательского интерполятора, например, такого, который понимает SVG пути. Полезная техника — интерполяция данных, где d3.interpolateObject используется для интерполяции двух значений данных, а полученное значение затем используется (например, с формой) для вычисления нового значения атрибута.
переход.стиль(имя, значение[, приоритет]) Источник
Для каждого выбранного элемента назначается интерполяция стиля для стиля с указанным именем целевому значению с указанным приоритетом. Начальное значение интерполяции — значение стиля в строке, если оно присутствует, а в противном случае — вычисленное значение при запуске перехода. Целевое значение может быть задано как константой, так и функцией. Если это функция, она сразу оценивается для каждого выбранного элемента в порядке, получая текущий элемент данных d и индекс i, с this контекстом как текущий элемент DOM.
Если целевое значение равно null, стиль удаляется при запуске перехода. В противном случае интерполятор выбирается на основе типа целевого значения, используя следующий алгоритм:
- Если значение — число, используйте interpolateNumber.
- Если значение — цвет или строка, преобразуемая в цвет, используйте interpolateRgb.
- Используйте interpolateString.
Для применения другого интерполятора используйте переход.styleTween.
переход.styleTween(имя[, фабрика[, приоритет]])) Источник
Если фабрика задана и не равна null, назначается интерполяция стиля для стиля с указанным именем, заданному интерполятору фабрика. Фабрика интерполятора — функция, возвращающая интерполятор; при запуске перехода фабрика вычисляется для каждого выбранного элемента в порядке, получая текущий элемент данных d и индекс i, с this контекстом как текущий элемент DOM. Возвращённый интерполятор будет вызываться для каждой фазы перехода в порядке, получая значение сглаженного времени t, обычно в диапазоне [0, 1]. Наконец, возвращаемое значение интерполятора будет использоваться для установки значения стиля с указанным приоритетом. Интерполятор должен возвращать строку. (Чтобы удалить стиль в начале перехода, используйте переход.стиль; чтобы удалить стиль в конце перехода, используйте переход.on для прослушивания события end.)
Если заданная фабрика равна null, удаляется ранее назначенная интерполяция стиля указанного имени, если таковая имеется. Если фабрика не задана, возвращается текущий интерполятор для стиля с указанным именем или undefined, если такого tween не существует.
Например, для интерполяции стиля fill от красного до синего:
transition.styleTween("fill", function() {
return d3.interpolateRgb("red", "blue");
}); Или для интерполяции от текущего значения fill до синего, как в переход.стиль:
transition.styleTween("fill", function() {
return d3.interpolateRgb(this.style.fill, "blue");
}); Или для применения пользовательского интерполятора радуги:
transition.styleTween("fill", function() {
return function(t) {
return "hsl(" + t * 360 + ",100%,50%)";
};
}); Этот метод полезен для указания пользовательского интерполятора, например, с интерполяцией данных, где d3.interpolateObject используется для интерполяции двух значений данных, а полученное значение затем используется для вычисления нового значения стиля.
переход.текст(значение) Источник
Для каждого выбранного элемента устанавливается содержимое текста целевому значению при запуске перехода. Значение может быть задано как константой, так и функцией. Если это функция, она сразу оценивается для каждого выбранного элемента в порядке, получая текущий элемент данных d и индекс i, с this контекстом как текущий элемент DOM. Возвращаемое значение функции затем используется для установки содержимого текста каждого элемента. Значение null очищает содержимое.
Чтобы интерполировать текст, а не установить его при запуске, используйте переход.tween (например) или добавьте заменяющий элемент и перекрестное затемнение непрозрачности (например). Текст по умолчанию не интерполируется, потому что это обычно нежелательно.
переход.удалить() Источник
Для каждого выбранного элемента, удаляет элемент по завершении перехода, при условии, что у элемента нет других активных или ожидающих переходов. Если у элемента есть другие активные или ожидающие переходы, ничего не происходит.
transition.tween(name[, value]) Source
Для каждого выбранного элемента назначает интерполяцию со значением name и функцией value. value должно быть функцией, возвращающей функцию. Когда переход начинается, функция value оценивается для каждого выбранного элемента, в порядке следования, принимая текущее значение данных d и индекс i, с контекстом this в качестве текущего элемента DOM. Возвращаемая функция вызывается для каждой итерации перехода, в порядке следования, принимая значение времени t, интерполированное с помощью функции eased, обычно в диапазоне [0, 1]. Если заданное значение value равно null, удаляет ранее назначенную интерполяцию указанного name, если таковая была.
Например, для интерполяции атрибута fill до синего цвета, как в transition.attr:
transition.tween("attr.fill", function() {
var node = this, i = d3.interpolateRgb(node.getAttribute("fill"), "blue");
return function(t) {
node.setAttribute("fill", i(t));
};
}); Этот метод полезен для задания пользовательской интерполяции или для выполнения побочных эффектов, например, для анимации смещения прокрутки.
Временные параметры
Функция сглаживания easing, задержка delay и продолжительность duration перехода настраиваются. Например, задержка для каждого элемента может быть использована для последовательного переупорядочения элементов, улучшая восприятие. Смотрите Animated Transitions in Statistical Data Graphics для рекомендаций.
transition.delay([value]) Source
Для каждого выбранного элемента устанавливает задержку перехода в миллисекундах, заданную значением value. Значение value может быть задано либо как константа, либо как функция. Если это функция, она сразу же оценивается для каждого выбранного элемента, в порядке следования, принимая текущее значение данных d и индекс i, с контекстом this в качестве текущего элемента DOM. Возвращаемое значение функции используется для установки задержки перехода каждого элемента. Если задержка не указана, она по умолчанию равна нулю.
Если value не указано, возвращает текущее значение задержки для первого (не равного null) элемента в переходе. Это обычно полезно только если известно, что переход содержит ровно один элемент.
Установка задержки, кратной индексу i — удобный способ выполнить последовательный переход для набора элементов. Например:
transition.delay(function(d, i) { return i * 10; }); Конечно, вы также можете вычислить задержку как функцию данных или отсортировать выборку перед вычислением задержки, основанной на индексе.
transition.duration([value]) Source
Для каждого выбранного элемента устанавливает продолжительность перехода в миллисекундах, заданную значением value. Значение value может быть задано либо как константа, либо как функция. Если это функция, она сразу же оценивается для каждого выбранного элемента, в порядке следования, принимая текущее значение данных d и индекс i, с контекстом this в качестве текущего элемента DOM. Возвращаемое значение функции используется для установки продолжительности перехода каждого элемента. Если продолжительность не указана, она по умолчанию равна 250 мс.
Если value не указано, возвращает текущее значение продолжительности для первого (не равного null) элемента в переходе. Это обычно полезно только если известно, что переход содержит ровно один элемент.
transition.ease([value]) Source
Устанавливает функцию сглаживания перехода easing function для всех выбранных элементов. Значение value должно быть задано как функция. Функция сглаживания вызывается для каждой итерации анимации, принимая нормированное время t в диапазоне [0, 1]; она должна вернуть значение сглаженного времени tʹ, которое также обычно находится в диапазоне [0, 1]. Хорошая функция сглаживания должна возвращать 0, если t = 0, и 1, если t = 1. Если функция сглаживания не указана, она по умолчанию равна d3.easeCubic.
Если value не указано, возвращает текущую функцию сглаживания для первого (не равного null) элемента в переходе. Это обычно полезно только если известно, что переход содержит ровно один элемент.
Управление потоком
Для расширенного использования переходы предоставляют методы для пользовательского управления потоком.
transition.on(typenames[, listener]) Source
Добавляет или удаляет обработчик событий listener для каждого выбранного элемента для указанных событий typenames. typenames — это один из следующих типов событий:
-
start— когда переход начинается. -
end— когда переход заканчивается. -
interrupt— когда переход прерывается.
См. Жизненный цикл перехода для получения дополнительной информации. Обратите внимание, что это не собственные события DOM, как реализовано в selection.on и selection.dispatch, а события перехода!
Тип может быть необязательно после точки (.) и имени; необязательное имя позволяет зарегистрировать несколько обратных вызовов для получения событий одного типа, таких как start.foo и start.bar. Для задания нескольких имен типов, разделяйте их пробелами, например, interrupt end или start.foo start.bar.
Когда событие перехода, указанное в аргументе, отправляется в выбранный узел, заданный обработчик событий listener будет вызван для переходящего элемента, получив в качестве аргументов текущие данные d и индекс i, с контекстом this в качестве текущего элемента DOM. Обработчики событий всегда видят самые последние данные для своего элемента, но индекс — это свойство выбора и фиксируется при назначении обработчика событий; для обновления индекса необходимо назначить обработчик событий заново.
Если обработчик событий был ранее зарегистрирован для того же typename в выбранном элементе, старый обработчик удаляется перед добавлением нового. Для удаления обработчика событий передайте null в качестве listener. Для удаления всех обработчиков событий для данного имени, передайте null в качестве listener и .foo в качестве typename, где foo — это имя; для удаления всех обработчиков без имени, укажите . в качестве typename.
Если listener не указан, возвращает текущий обработчик событий для указанного события typename на первом (не равном null) выбранном элементе, если таковой имеется. Если указано несколько имен типов, возвращается первый соответствующий обработчик событий.
transition.each(function) Source
Вызывает указанную функцию function для каждого выбранного элемента, передавая в неё текущие данные d и индекс i, а также контекст this текущего элемента DOM. Этот метод может быть использован для вызова произвольного кода для каждого выбранного элемента и полезен для создания контекста для одновременного доступа к родительским и дочерним данным. Эквивалентно selection.each.
transition.call(function[, arguments…]) Source
Вызывает указанную функцию function ровно один раз, передавая в неё этот переход вместе с любыми необязательными аргументами. Возвращает этот переход. Это эквивалентно вызову функции вручную, но облегчает цепочки методов. Например, для установки нескольких атрибутов в переиспользуемой функции:
function color(transition, fill, stroke) {
transition
.style("fill", fill)
.style("stroke", stroke);
} Теперь скажем:
d3.selectAll("div").transition().call(color, "red", "blue"); Это эквивалентно:
color(d3.selectAll("div").transition(), "red", "blue"); Эквивалентно selection.call.
transition.empty() Source
Возвращает true, если этот переход не содержит элементов (не равных null). Эквивалентно selection.empty.
transition.nodes() Source
Возвращает массив всех элементов в этом переходе (не равных null). Эквивалентно selection.nodes.
transition.node() Source
Возвращает первый элемент в этом переходе (не равный null). Если переход пуст, возвращает null. Эквивалентно selection.node.
transition.size() Source
Возвращает общее количество элементов в этом переходе. Эквивалентно selection.size.
Жизненный цикл перехода
Сразу после создания перехода, например, с помощью selection.transition или transition.transition, вы можете настроить переход, используя методы, такие как transition.delay, transition.duration, transition.attr и transition.style. Методы, которые задают целевые значения (например, transition.attr), оцениваются синхронно; однако, методы, которые требуют начального значения для интерполяции, такие как transition.attrTween и transition.styleTween, должны быть отложены до начала перехода.
Вскоре после создания, либо в конце текущей фазы, либо в течение следующей фазы, переход планируется. На этом этапе задержка и start обработчики событий больше не могут быть изменены; попытка сделать это приводит к ошибке с сообщением «слишком поздно: уже запланировано» (или, если переход завершен, «переход не найден»).
Когда переход впоследствии запускается, он прерывает активный переход с тем же именем на том же элементе, если таковой имеется, отправляя interrupt событие зарегистрированным обработчикам. (Обратите внимание, что прерывания происходят при запуске, а не при создании, и поэтому даже переход с нулевой задержкой немедленно не прервет активный переход: старому переходу дается конечная фаза. Используйте selection.interrupt для немедленного прерывания.) Запускаемый переход также отменяет любые ожидающие переходы с тем же именем на том же элементе, созданные до запускаемого перехода. Затем переход отправляет start событие зарегистрированным обработчикам. Это последний момент, когда переход может быть изменен: после запуска временные параметры, интерполяции и обработчики перехода больше нельзя изменить; попытка сделать это приводит к ошибке с сообщением «слишком поздно: уже начато» (или, если переход завершен, «переход не найден»). Переход инициализирует свои интерполяции сразу после запуска.
В течение фазы, когда переход запускается, но после запуска всех переходов, начатых в этой фазе, переход вызывает свои интерполяции впервые. Объединение инициализации интерполяции, которое обычно включает чтение из DOM, повышает производительность, избегая перекрестных чтений и записей в DOM.
В каждой фазе, когда переход активен, он вызывает свои интерполяции с сглаженным значением t, изменяющимся от 0 до 1. В каждой фазе переход вызывает свои интерполяции в том порядке, в котором они были зарегистрированы.
Когда переход завершается, он вызывает свои интерполяции в последний раз со значением t (без сглаживания) равным 1. Затем он отправляет end событие зарегистрированным обработчикам. Это последний момент, когда можно проверить переход: после завершения переход удаляется из элемента, а его конфигурация уничтожается. (Конфигурация перехода также уничтожается при прерывании или отмене.) Попытка проверить переход после его уничтожения приводит к ошибке с сообщением «переход не найден».
© 2010–2018 Michael Bostock
Licensed under the BSD License.
https://github.com/d3/d3-transition