Система анимаций в Chart.js построена вокруг двух ключевых уровней:
глобальной конфигурации animation и точечной анимации
отдельных элементов графика (секторов, точек, линий, столбцов).
Библиотека использует внутренний цикл перерисовки, в котором каждый кадр
пересчитываются свойства графических элементов, а затем выполняется
рендер на canvas.
Анимации применяются не как внешняя надстройка, а как часть процесса построения графика: любое изменение данных или конфигурации инициирует переходное состояние, в рамках которого значения интерполируются от старого состояния к новому.
Основной принцип: все визуальные изменения — это переход между двумя состояниями данных.
Параметр animation задаётся в объекте конфигурации
графика и управляет поведением всех анимаций:
const config = {
type: 'line',
data,
options: {
animation: {
duration: 1200,
easing: 'easeOutQuart'
}
}
};
Ключевые параметры:
Важно понимать, что duration влияет не только на
первичную отрисовку, но и на любые обновления данных через
chart.update().
Easing определяет характер изменения значения во времени. Chart.js поддерживает набор предустановленных кривых:
Пример использования:
options: {
animation: {
easing: 'easeInOutCubic'
}
}
Поведение easing критически влияет на восприятие графика. Например,
easeOutQuart создаёт эффект «замедляющегося движения», что
особенно естественно для появления данных.
Chart.js позволяет управлять анимацией на уровне отдельных элементов
(точек, баров, дуг). Это делается через объект animation с
ключами, соответствующими типам элементов.
options: {
animation: {
x: {
duration: 1000,
from: 0
},
y: {
duration: 1200,
from: 0
}
}
}
Здесь:
x и y контролируют анимацию координатfrom задаёт стартовое значениеТакой подход позволяет создавать эффект «построения графика из нуля».
Chart.js предоставляет возможность вмешиваться в процесс анимации через callback-функции:
options: {
animation: {
onProgress: function(animation) {
console.log(animation.currentStep / animation.numSteps);
},
onComplete: function() {
console.log('Анимация завершена');
}
}
}
Вызывается на каждом кадре анимации. Используется для:
Срабатывает после завершения анимации. Часто используется для:
Одним из мощных инструментов является параметр from,
позволяющий задавать начальное состояние для интерполяции.
options: {
animation: {
y: {
from: 0
}
}
}
Это даёт возможность явно контролировать стартовую точку появления элементов.
Также можно использовать функцию:
from: (context) => {
return context.datasetIndex === 0 ? 0 : 100;
}
Контекст позволяет создавать условные анимации в зависимости от набора данных.
Помимо обычных анимаций обновления данных, Chart.js поддерживает систему transitions — переходов между состояниями графика.
Состояния могут включать:
Пример конфигурации:
options: {
transitions: {
show: {
animations: {
x: {
duration: 800,
easing: 'easeOutQuart'
},
y: {
duration: 800
}
}
},
hide: {
animations: {
x: {
duration: 500,
easing: 'easeInQuart'
}
}
}
}
}
Transitions позволяют разделять поведение анимации в зависимости от типа изменения состояния графика.
animation — глобальное поведение при любых
обновленияхtransitions — специализированные сценарии для
конкретных состоянийПри конфликте приоритет отдается более специфичному правилу transitions.
При вызове:
chart.update();
анимация запускается автоматически. Однако можно управлять режимом:
chart.update('none');
или:
chart.update('active');
Режим none полностью отключает анимацию, что полезно при
массовых обновлениях данных.
Каждый dataset может иметь собственную анимацию:
data: {
datasets: [
{
data: [10, 20, 30],
animation: {
duration: 2000
}
}
]
}
Это позволяет создавать разноскоростные слои анимации внутри одного графика.
Внутри Chart.js каждый визуальный элемент проходит через систему состояний:
Анимация между этими состояниями интерполирует свойства:
Пример влияния hover:
options: {
hover: {
animationDuration: 300
}
}
Глубокая кастомизация возможна через плагины Chart.js, где можно вмешиваться в жизненный цикл рендера:
const customPlugin = {
id: 'customAnimation',
beforeDraw(chart) {
const ctx = chart.ctx;
ctx.save();
},
afterDraw(chart) {
const ctx = chart.ctx;
ctx.restore();
}
};
Комбинируя плагины с onProgress, можно реализовать:
При работе с большими массивами данных анимации могут стать узким местом производительности.
Рекомендуемые подходы:
duration при частых обновленияхrequestAnimationFrame во внешней
логикеupdate('none') для batch-обновленийТакже важно учитывать, что canvas перерисовывается полностью при каждом кадре, поэтому сложные кастомные эффекты могут быть дорогостоящими.
При необходимости синхронизации анимации нескольких экземпляров Chart.js используется единое управление временем:
const commonOptions = {
animation: {
duration: 1000,
easing: 'easeOutQuart'
}
};
Или внешняя координация:
charts.forEach(chart => chart.update());
С помощью onProgress можно добиться параллельного
изменения нескольких графиков в едином темпе.
При динамическом изменении массива данных Chart.js автоматически интерполирует изменения:
chart.data.datasets[0].data.push(50);
chart.update();
Удаление элементов также анимируется, если не отключена глобальная анимация.
Особенность: элементы не «пересоздаются», а плавно изменяют позицию и прозрачность, что создаёт непрерывное визуальное восприятие.
Chart.js использует числовую интерполяцию для большинства свойств. Для сложных структур (например, stacked datasets) применяется поэлементное вычисление, что обеспечивает корректные переходы между состояниями без визуальных разрывов.