В Chart.js временные шкалы (time scale) не работают
автономно с датами JavaScript без дополнительного слоя преобразования.
Библиотека намеренно не включает встроенный механизм парсинга и
форматирования дат, чтобы сохранить лёгкость ядра и дать возможность
выбирать подходящую реализацию под конкретные задачи.
Для этого используется адаптер дат (date adapter) — модуль, который отвечает за:
Без подключённого адаптера попытка использовать
type: 'time' приводит к некорректному отображению или
ошибкам построения шкалы.
Chart.js не ограничивает выбор реализации. На практике используются несколько вариантов:
chartjs-adapter-date-fns — лёгкий и быстрый, основан на
date-fns;chartjs-adapter-luxon — более функциональный,
поддерживает сложные временные зоны;chartjs-adapter-moment — совместимость с
legacy-проектами (Moment.js, устаревающий вариант).Выбор адаптера влияет не на API Chart.js, а на внутреннюю работу парсинга и форматирования дат.
Базовая установка через npm:
npm install chart.js
Подключение адаптера выполняется отдельно:
npm install chartjs-adapter-date-fns
или
npm install chartjs-adapter-luxon
или
npm install chartjs-adapter-moment
Важно, что адаптер должен быть установлен явно — Chart.js его не подтягивает автоматически.
Начиная с Chart.js v3 архитектура перешла на модульную систему. Вместо глобального объекта, который содержал всё сразу, используется явная регистрация компонентов.
Каждый элемент графика должен быть зарегистрирован:
Без регистрации соответствующих модулей график не будет отрисован.
Типовая структура подключения:
import {
Chart,
LineController,
LineElement,
PointElement,
LinearScale,
TimeScale,
Tooltip,
Legend
} from 'chart.js';
Chart.register(
LineController,
LineElement,
PointElement,
LinearScale,
TimeScale,
Tooltip,
Legend
);
Здесь подключается минимальный набор компонентов для линейного графика с временной шкалой.
Адаптеры Chart.js не требуют ручной регистрации через
Chart.register. Они работают как side-effect
import: достаточно импортировать модуль один раз, чтобы он
расширил поведение библиотеки.
import 'chartjs-adapter-date-fns';
После этого Chart.js автоматически получает поддержку работы с датами через date-fns.
После подключения адаптера становится доступна конфигурация оси
time:
const config = {
type: 'line',
data: {
datasets: [{
label: 'Продажи',
data: [
{ x: '2025-01-01', y: 120 },
{ x: '2025-01-02', y: 150 },
{ x: '2025-01-03', y: 90 }
]
}]
},
options: {
scales: {
x: {
type: 'time',
time: {
unit: 'day'
}
}
}
}
};
Без адаптера поле type: 'time' не сможет корректно
интерпретировать значения x.
В модульной системе Chart.js адаптер не входит в граф зависимостей ядра. Его подключение выглядит как расширение глобального контекста.
Механизм можно описать так:
Модульная структура Chart.js позволяет удалять неиспользуемые части библиотеки при сборке.
Регистрация адаптера не влияет на tree-shaking, поскольку:
Chart.register.Однако регистрация графиков и шкал напрямую влияет на итоговый бандл.
Подключение более одного адаптера одновременно технически возможно, но приводит к конфликту глобального состояния.
Последний импортированный адаптер становится активным:
import 'chartjs-adapter-date-fns';
import 'chartjs-adapter-luxon';
В этом случае фактически используется Luxon, так как он перезапишет зарегистрированные функции.
Стабильная архитектура предполагает использование только одного адаптера на приложение.
При использовании временной шкалы без адаптера наблюдаются следующие эффекты:
Это связано с тем, что TimeScale делегирует все операции
внешнему адаптеру.
В сборщиках типа Vite, Webpack или Rollup адаптер подключается как обычный side-effect импорт.
Пример структуры:
import { Chart } from 'chart.js/auto';
import 'chartjs-adapter-date-fns';
Использование chart.js/auto автоматически регистрирует
все базовые компоненты, но адаптер всё равно подключается отдельно.
В TypeScript адаптеры не требуют дополнительных типов регистрации. Однако важно учитывать:
Разные адаптеры предоставляют разный уровень поддержки:
Выбор адаптера влияет на точность временных вычислений при кросс-региональной аналитике данных.
Обобщённая модель работы выглядит следующим образом:
Это разделение позволяет заменять реализацию времени без изменения логики графиков.