В основе интерактивности Chart.js лежит система обработки событий холста и сопоставления координат курсора с элементами графика. Библиотека не просто отображает данные, а строит слой взаимодействия, в котором каждый пиксель может быть интерпретирован как часть данных, осей или визуальных элементов.
График в Chart.js рендерится на HTML5 <canvas>, а
значит, все взаимодействие происходит через стандартные DOM-события:
mousemovemouseoutclicktouchstarttouchmovetouchendChart.js абстрагирует эти события через собственный механизм обработки, привязывая их к экземпляру графика и преобразуя координаты мыши в данные области графика.
Ключевая настройка:
options: {
events: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'],
}
Ограничение списка событий позволяет снизить нагрузку и контролировать уровень интерактивности.
Chart.js использует централизованную систему определения активных
элементов графика. Она задаётся через interaction:
options: {
interaction: {
mode: 'nearest',
intersect: false
}
}
nearest Определяет ближайший элемент к курсору по расстоянию в пикселях.
index Выбирает все элементы с одинаковым индексом по оси X (например, все серии в одной точке времени).
dataset Активирует весь набор данных, к которому принадлежит ближайший элемент.
point Фокусируется строго на точках данных.
x / y Работает по одной оси, полезно для линейных графиков и временных рядов.
true — активный элемент определяется только при точном
наведении на негоfalse — допускается выбор ближайшего элемента даже без
пересеченияПри визуализации плотных данных false значительно
улучшает UX, позволяя пользователю взаимодействовать без необходимости
попадать точно в точку.
Chart.js предоставляет API для ручного определения элементов под курсором:
const points = chart.getElementsAtEventForMode(
event,
'nearest',
{ intersect: false },
true
);
Также доступны:
getElementsAtEventgetDatasetMeta(index)getActiveElements()Эти методы используются при построении кастомных tooltip’ов и сложных интерактивных слоёв.
Canvas по умолчанию не изменяет стиль курсора. Это необходимо делать вручную через обработчики событий:
options: {
onHover: (event, activeElements, chart) => {
const canvas = chart.canvas;
canvas.style.cursor = activeElements.length ? 'pointer' : 'default';
}
}
Подобный подход применяется для сигнализации кликабельности элементов.
Распространённые состояния курсора:
default — отсутствие взаимодействияpointer — активный элементcrosshair — точное позиционированиеgrab / grabbing — перетаскивание (в
кастомных реализациях)Chart.js поддерживает встроенные свойства, изменяющие внешний вид элементов при наведении.
data: {
datasets: [{
pointRadius: 4,
pointHoverRadius: 8,
pointHoverBorderWidth: 2
}]
}
Поведение:
pointRadius — базовый размерpointHoverRadius — увеличение при наведенииpointHoverBorderWidth — усиление обводкиПри большом количестве точек увеличение радиуса используется умеренно, чтобы избежать визуального шума.
Для линейных графиков визуальная реакция чаще реализуется через толщину и цвет:
datasets: [{
borderWidth: 2,
hoverBorderWidth: 4,
borderColor: '#4e79a7',
hoverBorderColor: '#1f3a93'
}]
Изменение толщины линии создаёт эффект «подсветки» активной серии.
datasets: [{
backgroundColor: '#74b9ff',
hoverBackgroundColor: '#0984e3'
}]
Для bar charts наиболее эффективен именно цветовой контраст, а не изменение геометрии.
Chart.js поддерживает внутреннее состояние активных элементов, которое можно получить через:
chart.getActiveElements();
Активный элемент содержит:
Это состояние используется системой tooltip и может быть переопределено для кастомного поведения.
Tooltip в Chart.js тесно связан с системой interaction:
options: {
plugins: {
tooltip: {
mode: 'index',
intersect: false
}
}
}
Согласование tooltip.mode и
interaction.mode критично: расхождение этих параметров
приводит к несинхронному поведению интерфейса.
Для глубокой кастомизации используются обработчики:
options: {
onClick: (event, activeElements, chart) => {
if (activeElements.length > 0) {
const { datasetIndex, index } = activeElements[0];
const value = chart.data.datasets[datasetIndex].data[index];
}
}
}
Типичные сценарии:
Chart.js преобразует координаты курсора в систему координат графика и определяет попадание в элементы через:
Для оптимизации используется кэширование метаданных графика
(meta) и индексированные структуры данных.
При необходимости более сложного визуального отклика применяется plugin API:
plugins: [{
id: 'highlightActiveDataset',
afterDatasetsDraw(chart, args, pluginOptions) {
const active = chart.getActiveElements();
if (active.length) {
const datasetIndex = active[0].datasetIndex;
const meta = chart.getDatasetMeta(datasetIndex);
meta.dataset.options.borderWidth = 5;
}
}
}]
Такой подход позволяет изменять поведение на уровне рендера.
При работе с несколькими экземплярами Chart.js часто требуется синхронное взаимодействие:
Реализуется через обработку событий и передачу состояния между экземплярами:
onHover: (event, elements) => {
syncCharts(elements[0]?.index);
}
Touch-события обрабатываются с особенностями:
Оптимизация достигается через:
options: {
responsive: true,
maintainAspectRatio: false
}
и уменьшение плотности событий в events.
Визуальная реакция не ограничивается hover-состоянием. Анимации усиливают ощущение отклика:
options: {
animation: {
duration: 400,
easing: 'easeOutQuart'
}
}
Типичные эффекты:
Ключевой аспект взаимодействия — предсказуемость реакции:
Конфигурация interaction и визуальных параметров должна рассматриваться как единая система, а не набор независимых опций.