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), из перехода другой.
Этот метод эквивалентен выводу выбора для этого перехода с помощью переход.selection, объединению с выбором, аналогичным образом выведенным из перехода другой с помощью выбор.merge, и затем созданию нового перехода с помощью выбор.transition:
transition .selection() .merge(other.selection()) .transition(transition)
transition.transition() Source
Возвращает новую анимацию на тех же выбранных элементах, что и эта анимация, запланированную на запуск по окончании этой анимации. Новая анимация наследует значение времени, равное времени этой анимации плюс её задержка и продолжительность. Новая анимация также наследует имя, продолжительность и способ сглаживания этой анимации. Этот метод может быть использован для планирования последовательности связанных анимаций. Например:
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(); Задержка каждой анимации относится к предыдущей анимации. Таким образом, в приведённом примере яблоки останутся красными в течение одной секунды, прежде чем начнется последняя анимация перехода в коричневый цвет.
transition.selection() Source
Возвращает выбор, соответствующий этой анимации.
d3.active(node[, name]) Source
Возвращает активную анимацию на указанном узле с указанным именем, если таковая имеется. Если имя не указано, используется 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);
}); См. связанные анимации для примера.
Изменение элементов
После выбора элементов и создания анимации с помощью выбор.transition, используйте методы преобразования анимации для изменения содержимого документа.
transition.attr(name, value) Source
Для каждого выбранного элемента, назначает интерполяцию атрибута для атрибута с указанным именем к заданному целевому значению. Начальное значение интерполяции — значение атрибута в момент запуска анимации. Целевое значение может быть задано либо как константа, либо как функция. Если функция, она вычисляется немедленно для каждого выбранного элемента, по порядку, получая текущее значение данных d и индекс i, с this контекстом как текущий элемент DOM.
Если целевое значение равно null, атрибут удаляется в начале анимации. В противном случае интерполятор выбирается на основе типа целевого значения, используя следующий алгоритм:
- Если значение — число, используется interpolateNumber.
- Если значение — цвет или строка, преобразуемая в цвет, используется interpolateRgb.
- Используется interpolateString.
Для применения другого интерполятора используйте transition.attrTween.
transition.attrTween(name[, factory]) Source
Если factory указан и не равен null, назначает интерполяцию атрибута для атрибута с указанным именем указанному интерполятору factory. Фабрика интерполятора — функция, возвращающая интерполятор; при запуске анимации factory вычисляется для каждого выбранного элемента, по порядку, получая текущее значение данных d и индекс i, с this контекстом как текущий элемент DOM. Возвращаемый интерполятор затем вызывается для каждой фазы анимации, по порядку, получая сглаженное время t, обычно в диапазоне [0, 1]. Наконец, возвращаемое значение интерполятора используется для установки значения атрибута. Интерполятор должен возвращать строку. (Чтобы удалить атрибут в начале анимации, используйте transition.attr; чтобы удалить атрибут в конце анимации, используйте transition.on для прослушивания события end.)
Если указанный factory равен null, удаляется ранее назначенная интерполяция атрибута с указанным именем, если таковая имеется. Если factory не указан, возвращается текущая фабрика интерполятора для атрибута с указанным именем или undefined, если такая интерполяция не существует.
Например, для интерполяции атрибута заполнения от красного до синего:
transition.attrTween("fill", function() {
return d3.interpolateRgb("red", "blue");
}); Или для интерполяции от текущего заполнения до синего, как в transition.attr:
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 используется для интерполяции двух значений данных, а полученное значение затем используется (скажем, с формой) для вычисления нового значения атрибута.
transition.style(name, value[, priority]) Source
Для каждого выбранного элемента назначает интерполяцию стиля для стиля с указанным именем к заданному целевому значению со значением приоритета. Начальное значение интерполяции — значение стиля внутри, если оно присутствует, а в противном случае — его вычисленное значение, в момент запуска анимации. Целевое значение может быть задано либо как константа, либо как функция. Если функция, она вычисляется немедленно для каждого выбранного элемента, по порядку, получая текущее значение данных d и индекс i, с this контекстом как текущий элемент DOM.
Если целевое значение равно null, стиль удаляется в начале анимации. В противном случае интерполятор выбирается на основе типа целевого значения, используя следующий алгоритм:
- Если значение — число, используется interpolateNumber.
- Если значение — цвет или строка, преобразуемая в цвет, используется interpolateRgb.
- Используется interpolateString.
Для применения другого интерполятора используйте transition.styleTween.
transition.styleTween(name[, factory[, priority]])) Source
Если factory указан и не равен null, назначает интерполяцию стиля для стиля с указанным именем указанному интерполятору factory. Фабрика интерполятора — функция, возвращающая интерполятор; при запуске анимации factory вычисляется для каждого выбранного элемента, по порядку, получая текущее значение данных d и индекс i, с this контекстом как текущий элемент DOM. Возвращаемый интерполятор затем вызывается для каждой фазы анимации, по порядку, получая сглаженное время t, обычно в диапазоне [0, 1]. Наконец, возвращаемое значение интерполятора используется для установки значения стиля со значением приоритета. Интерполятор должен возвращать строку. (Чтобы удалить стиль в начале анимации, используйте transition.style; чтобы удалить стиль в конце анимации, используйте transition.on для прослушивания события end.)
Если указанный factory равен null, удаляется ранее назначенная интерполяция стиля с указанным именем, если таковая имеется. Если factory не указан, возвращается текущая фабрика интерполятора для стиля с указанным именем или undefined, если такая интерполяция не существует.
Например, для интерполяции стиля заполнения от красного до синего:
transition.styleTween("fill", function() {
return d3.interpolateRgb("red", "blue");
}); Или для интерполяции от текущего заполнения до синего, как в transition.style:
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 используется для интерполяции двух значений данных, а полученное значение затем используется для вычисления нового значения стиля.
transition.text(value) Source
Для каждого выбранного элемента устанавливает содержимое текста на указанное целевое значение в начале анимации. Значение может быть задано либо как константа, либо как функция. Если функция, она вычисляется немедленно для каждого выбранного элемента, по порядку, получая текущее значение данных d и индекс i, с this контекстом как текущий элемент DOM. Возвращаемое значение функции используется для установки содержимого текста каждого элемента. Значение null очистит содержимое.
Для интерполяции текста, а не для его установки в начале, используйте transition.tween (например) или добавьте элемент-замену и скройте прозрачность (например). Текст по умолчанию не интерполируется, потому что это обычно нежелательно.
transition.remove() Source
Для каждого выбранного элемента удаляет элемент по окончании анимации, при условии, что элемент не имеет других активных или ожидающих анимаций. Если у элемента есть другие активные или ожидающие анимации, ничего не происходит.
transition.tween(name[, value]) Source
Для каждого выбранного элемента назначает твины с указанным именем имя со значением функции значение. Значение значение должно быть указано как функция, которая возвращает функцию. Когда начинается переход, функция значение вычисляется для каждого выбранного элемента в порядке, получая текущее данное d и индекс i, с контекстом this как текущим элементом DOM. Возвращаемая функция вызывается для каждой кадр перехода, в порядке, получая сглаженное время t, обычно в диапазоне [0, 1]. Если указанное значение равно null, удаляет ранее назначенный твин указанного имени, если таковой имеется.
Например, чтобы интерполировать атрибут fill в синий, как переход.attr:
transition.tween("attr.fill", function() {
var node = this, i = d3.interpolateRgb(node.getAttribute("fill"), "blue");
return function(t) {
node.setAttribute("fill", i(t));
};
}); Этот метод полезен для указания пользовательского интерполятора или для выполнения побочных эффектов, скажем, для анимации смещения прокрутки.
Временные характеристики
Сглаживание сглаживания, задержка и длительность перехода настраиваются. Например, задержка на элемент может использоваться для последовательного изменения порядка элементов, улучшая восприятие. См. Анимированные переходы в статистических графиках данных для рекомендаций.
переход.задержка([значение]) Источник
Для каждого выбранного элемента устанавливает задержку перехода на указанное значение значение в миллисекундах. Значение значение может быть указано как константа или функция. Если функция, она вычисляется немедленно для каждого выбранного элемента в порядке, получая текущее данное d и индекс i, с контекстом this как текущим элементом DOM. Возвращаемое значение функции используется для установки задержки перехода каждого элемента. Если задержка не указана, она по умолчанию равна нулю.
Если значение не указано, возвращает текущее значение задержки для первого (не-нулевого) элемента в переходе. Это, как правило, полезно только в том случае, если известно, что переход содержит ровно один элемент.
Установка задержки кратной индексу i — удобный способ разнести переходы по набору элементов. Например:
transition.delay(function(d, i) { return i * 10; }); Конечно, вы также можете вычислить задержку как функцию данных или отсортировать выборку перед вычислением задержки, основанной на индексе.
переход.длительность([значение]) Источник
Для каждого выбранного элемента устанавливает длительность перехода на указанное значение значение в миллисекундах. Значение значение может быть указано как константа или функция. Если функция, она вычисляется немедленно для каждого выбранного элемента в порядке, получая текущее данное d и индекс i, с контекстом this как текущим элементом DOM. Возвращаемое значение функции используется для установки длительности перехода каждого элемента. Если длительность не указана, она по умолчанию равна 250 мс.
Если значение не указано, возвращает текущее значение длительности для первого (не-нулевого) элемента в переходе. Это, как правило, полезно только в том случае, если известно, что переход содержит ровно один элемент.
переход.сглаживание([значение]) Источник
Устанавливает функцию сглаживания перехода сглаживания для всех выбранных элементов. Значение значение должно быть указано как функция. Функция сглаживания вызывается для каждого кадра анимации, получая нормированное время t в диапазоне [0, 1]; она должна вернуть сглаженное время tʹ, которое обычно также находится в диапазоне [0, 1]. Хорошая функция сглаживания должна возвращать 0, если t = 0, и 1, если t = 1. Если функция сглаживания не указана, она по умолчанию равна d3.easeCubic.
Если значение не указано, возвращает текущую функцию сглаживания для первого (не-нулевого) элемента в переходе. Это, как правило, полезно только в том случае, если известно, что переход содержит ровно один элемент.
Управление потоком
Для расширенного использования переходы предоставляют методы для пользовательского управления потоком.
переход.on(typenames[, listener]) Источник
Добавляет или удаляет слушатель к каждому выбранному элементу для указанных событий typenames. Тип typenames — это один из следующих типов событий:
-
start— когда начинается переход. -
end— когда переход завершается. -
interrupt— когда переход прерывается.
См. Жизненный цикл перехода для получения дополнительной информации. Обратите внимание, что это не собственные события DOM, реализованные выбор.on и выбор.dispatch, а события перехода!
Тип может быть необязательно последан точкой (.) и именем; необязательное имя позволяет регистрировать несколько обратных вызовов для получения событий того же типа, таких как start.foo и start.bar. Чтобы указать несколько типов имен, разделите типы имен пробелами, например interrupt end или start.foo start.bar.
Когда заданное событие перехода отправляется на выбранный узел, указанный слушатель вызывается для элемента, находящегося в процессе перехода, передавая текущее данное d и индекс i, с контекстом this в качестве текущего элемента DOM. Слушатели всегда видят последние данные для своего элемента, но индекс является свойством выбора и фиксируется при назначении слушателя; чтобы обновить индекс, назначьте слушателя заново.
Если ранее для того же typename на выбранном элементе был зарегистрирован обработчик событий, старый обработчик удаляется перед добавлением нового. Чтобы удалить слушателя, передайте null в качестве слушателя. Чтобы удалить все слушатели для данного имени, передайте null в качестве слушателя и .foo в качестве typename, где foo — имя; чтобы удалить все слушатели без имени, укажите . как typename.
Если слушатель не указан, возвращает текущего назначенного слушателя для указанного события typename на первом (не-нулевом) выбранном элементе, если таковой имеется. Если указано несколько типов имен, возвращается первый соответствующий слушатель.
переход.each(функция) Источник
Вызывает указанную функцию для каждого выбранного элемента, передавая текущее данное d и индекс i, с контекстом this текущего элемента DOM. Этот метод может быть использован для вызова произвольного кода для каждого выбранного элемента и полезен для создания контекста для одновременного доступа к родительским и дочерним данным. Эквивалент выбор.each.
переход.call(функция[, аргументы…]) Источник
Вызывает указанную функцию ровно один раз, передавая в неё этот переход вместе со всеми необязательными аргументами. Возвращает этот переход. Это эквивалентно вызову функции вручную, но упрощает цепочки вызовов. Например, чтобы установить несколько атрибутов в многократно используемой функции:
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"); Эквивалентно выбор.call.
переход.пустой() Источник
Возвращает true, если этот переход не содержит элементов (не-null). Эквивалентно выбор.пустой.
переход.узлы() Источник
Возвращает массив всех элементов (не-null) в этом переходе. Эквивалентно выбор.узлы.
переход.узел() Источник
Возвращает первый (не-null) элемент в этом переходе. Если переход пуст, возвращает null. Эквивалентно выбор.узел.
переход.размер() Источник
Возвращает общее количество элементов в этом переходе. Эквивалентно выбор.размер.
Жизненный цикл перехода
Сразу после создания перехода, например, с помощью выбор.переход или переход.переход, вы можете настроить переход с помощью методов, таких как переход.задержка, переход.длительность, переход.attr и переход.style. Методы, которые задают целевые значения (например, переход.attr), вычисляются синхронно; однако, методы, которые требуют начального значения для интерполяции, такие как переход.attrTween и переход.styleTween, должны быть отложены до начала перехода.
Вскоре после создания, либо в конце текущего кадра, или в течение следующего кадра, переход планируется. На этом этапе задержка и start обработчики событий больше не могут быть изменены; попытка сделать это приводит к ошибке с сообщением «слишком поздно: уже запланировано» (или, если переход завершен, «переход не найден»).
Когда переход впоследствии начинается, он прерывает активный переход с тем же именем на том же элементе, если таковой имеется, отправляя событие interrupt зарегистрированным слушателям. (Обратите внимание, что прерывания происходят при запуске, а не при создании, и поэтому даже переход с нулевой задержкой немедленно не прервет активный переход: старому переходу дается последний кадр. Используйте selection.interrupt, чтобы прервать немедленно.) Начальный переход также отменяет любые ожидающие переходы с тем же именем на том же элементе, которые были созданы до начального перехода. Затем переход отправляет событие start зарегистрированным слушателям. Это последний момент, в который переход может быть изменён: после запуска, временные характеристики, интерполяторы и слушатели перехода больше не могут быть изменены; попытка сделать это приводит к ошибке с сообщением «слишком поздно: уже начато» (или, если переход завершен, «переход не найден»). Переход инициализирует свои интерполяторы сразу после запуска.
В течение кадра, в который начинается переход, но после того, как все переходы, начинающиеся в этом кадре, будут начаты, переход вызывает свои интерполяторы в первый раз. Последовательная инициализация интерполяторов, которая обычно включает чтение из DOM, повышает производительность, избегая чередования операций чтения и записи в DOM.
Для каждого кадра, в котором переход активен, он вызывает свои интерполяторы с значением t, сглаженным с помощью функции сглаживания, изменяющимся от 0 до 1. Внутри каждого кадра переход вызывает свои интерполяторы в том порядке, в котором они были зарегистрированы.
Когда переход завершается, он вызывает свои интерполяторы в последний раз со значением t (без сглаживания) равным 1. Затем он отправляет событие end зарегистрированным слушателям. Это последний момент, когда переход может быть просмотрен: после завершения переход удаляется из элемента, а его конфигурация уничтожается. (Конфигурация перехода также уничтожается при прерывании или отмене.) Попытка просмотреть переход после его уничтожения приводит к ошибке с сообщением «переход не найден».
© 2010–2017 Michael Bostock
Licensed under the BSD License.
https://github.com/d3/d3-transition