Прокрутка (pan) в Chart.js реализуется через дополнительный плагин, расширяющий стандартные возможности визуализации — обычно используется библиотека zoom/pan plugin (chartjs-plugin-zoom). Панорамирование позволяет перемещать область видимых данных по осям X и Y без изменения масштаба, что особенно важно при работе с плотными временными рядами, финансовыми графиками и телеметрией.
Механизм прокрутки опирается на взаимодействие с масштабами (scales)
графика. Внутри Chart.js каждая ось представляет собой независимую
систему преобразования данных в координаты. Панорамирование изменяет
диапазон отображаемых значений (min и max) у
соответствующих шкал.
Основной принцип:
Это обеспечивает высокую производительность даже при больших наборах данных.
Функциональность панорамирования не входит в ядро Chart.js и подключается через плагин:
import { Chart } from 'chart.js';
import zoomPlugin from 'chartjs-plugin-zoom';
Chart.register(zoomPlugin);
После регистрации плагина становятся доступны параметры
pan и zoom в конфигурации графика.
Настройка выполняется в разделе
options.plugins.zoom:
const config = {
type: 'line',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
datasets: [{
label: 'Данные',
data: [10, 30, 20, 50, 40]
}]
},
options: {
plugins: {
zoom: {
pan: {
enabled: true,
mode: 'x'
}
}
}
}
};
Ключевой параметр:
Панорамирование поддерживает несколько режимов работы:
Перемещение только по горизонтальной оси. Используется для временных рядов, где X — время.
pan: {
enabled: true,
mode: 'x'
}
Перемещение только по вертикальной оси. Применяется для анализа амплитудных изменений.
pan: {
enabled: true,
mode: 'y'
}
Свободное перемещение по обеим осям.
pan: {
enabled: true,
mode: 'xy'
}
Этот режим характерен для графиков рассеяния (scatter plots), где обе оси несут равнозначную нагрузку.
Панорамирование может быть привязано к разным типам пользовательского ввода:
Основной режим работы:
pan: {
enabled: true,
mode: 'x',
modifierKey: null
}
Ограничение панорамирования по клавише-модификатору:
pan: {
enabled: true,
mode: 'xy',
modifierKey: 'ctrl'
}
Поддерживаются значения:
ctrlshiftaltmetaИспользование модификатора предотвращает случайное перемещение графика при обычном взаимодействии.
Параметр speed регулирует масштаб смещения при движении
мыши:
pan: {
enabled: true,
mode: 'x',
speed: 10
}
В некоторых версиях плагина также применяется threshold,
определяющий минимальное смещение для активации pan-жеста.
Для предотвращения выхода за пределы данных используются ограничения шкал.
options: {
scales: {
x: {
min: 0,
max: 100
}
}
}
При панорамировании Chart.js изменяет эти значения, но не позволяет выйти за заданные пределы, если включены ограничения.
Более гибкий механизм:
zoom: {
pan: {
enabled: true,
mode: 'x',
limits: {
x: {
min: 0,
max: 1000
}
}
}
}
Это обеспечивает контроль над диапазоном даже при динамическом обновлении данных.
Панорамирование часто используется совместно с масштабированием. В этом случае оба действия работают с одним состоянием шкал.
Пример конфигурации:
plugins: {
zoom: {
pan: {
enabled: true,
mode: 'x'
},
zoom: {
wheel: {
enabled: true
},
pinch: {
enabled: true
},
mode: 'x'
}
}
}
Внутри происходит единое обновление scale.min и
scale.max, что предотвращает рассинхронизацию состояния
графика.
Chart.js предоставляет API для управления состоянием через плагин:
Сброс положения графика:
chart.resetZoom();
Фактически возвращает шкалы к исходным значениям.
Прямое изменение диапазона:
chart.options.scales.x.min = 20;
chart.options.scales.x.max = 80;
chart.update();
Такой способ используется для внешнего управления видимой областью без пользовательского ввода.
При работе с потоковыми данными (streaming charts) pan может конфликтовать с автообновлением.
Типичный подход:
Пример логики:
let isPanning = false;
pan: {
enabled: true,
mode: 'x',
onPanStart: () => isPanning = true,
onPanComplete: () => isPanning = false
}
При этом внешняя логика обновления данных проверяет флаг состояния.
При использовании категорий (labels) pan изменяет индексный диапазон:
Для числовых данных:
Для time-scale:
Панорамирование оптимизировано за счёт:
Однако при больших датасетах возникают узкие места:
update() при кастомной логикеРешение — ограничение частоты обновлений и отключение анимаций:
options: {
animation: false,
responsiveAnimationDuration: 0
}
В дополнение к мыши pan может быть привязан к touch-событиям:
Это особенно важно для мобильных интерфейсов, где drag является основным способом навигации.
При обновлении dataset:
Рекомендуется контролировать состояние шкал вручную при динамических обновлениях.
При наличии нескольких X или Y шкал:
scales: {
x: { type: 'linear' },
x2: { position: 'top' }
}
Панорамирование может быть:
Настройка задаётся через scale или mode с
уточнением имени оси:
pan: {
enabled: true,
mode: 'x',
scale: 'x2'
}
Корректная настройка всегда требует явного определения mode, limits и стратегии взаимодействия с zoom.