Ось времени: форматы, парсинг, единицы

Общая модель временной оси

Ось времени в Chart.js реализуется через шкалу type: 'time', которая предназначена для работы с датами, временными интервалами и их визуализацией на графиках.

Ключевая особенность временной шкалы заключается в том, что она не оперирует строками как категориями и не требует заранее подготовленных индексов. Вместо этого используется нормализованное представление времени, которое затем преобразуется в координаты на оси X или Y.

Основные задачи временной шкалы:

  • преобразование входных данных в внутренний формат даты;
  • равномерное распределение точек по временной шкале;
  • форматирование отображаемых подписей;
  • адаптация единиц измерения под масштаб графика.

Поддерживаемые форматы времени

Chart.js принимает несколько типов входных данных, которые могут быть интерпретированы как дата.

ISO 8601 строки

Наиболее предпочтительный формат:

{
  x: '2026-01-01',
  y: 10
}

Также поддерживаются расширенные варианты:

  • 2026-01-01T10:30:00
  • 2026-01-01T10:30:00Z
  • 2026-01-01T10:30:00+06:00

ISO формат обеспечивает минимальное количество ошибок при парсинге и является стандартом для большинства адаптеров времени.


UNIX timestamp

Поддерживаются числовые значения времени:

{
  x: 1704067200000,
  y: 15
}

Значение интерпретируется как миллисекунды с 1 января 1970 года (UTC).

Важно:

  • секундные timestamps требуют умножения на 1000;
  • миллисекунды используются по умолчанию.

JavaScript Date объект

{
  x: new Date('2026-01-01'),
  y: 20
}

Chart.js автоматически вызывает valueOf() у объекта Date, преобразуя его в timestamp.


Объектные данные (x/y формат)

Наиболее универсальный формат для временной шкалы:

data: [
  { x: '2026-01-01', y: 10 },
  { x: '2026-01-02', y: 12 }
]

Такой подход предпочтителен при работе с time scale, так как исключает необходимость использования labels.


Парсинг временных значений

Парсинг — процесс преобразования входных значений в внутренний формат времени (обычно timestamp).

Автоматический парсинг

По умолчанию Chart.js пытается определить тип входных данных автоматически:

  • строки → через адаптер даты;
  • числа → как UNIX timestamp;
  • Date → через valueOf().

Явный парсер (parser)

В конфигурации можно задать правило интерпретации строк:

options: {
  scales: {
    x: {
      type: 'time',
      time: {
        parser: 'yyyy-MM-dd'
      }
    }
  }
}

Парсер особенно важен, если формат даты нестандартный:

  • dd.MM.yyyy
  • yyyy/MM/dd HH:mm
  • MM-dd-yyyy

Адаптеры времени

Chart.js не включает собственный движок дат. Он использует внешние адаптеры:

  • date-fns adapter
  • Luxon adapter
  • Moment adapter (устаревший, но всё ещё встречается)

Адаптер отвечает за:

  • разбор строк;
  • форматирование;
  • локализацию;
  • вычисление единиц времени.

Единицы времени (time units)

Ось времени автоматически масштабируется в зависимости от диапазона данных. Используются стандартные единицы:

  • millisecond
  • second
  • minute
  • hour
  • day
  • week
  • month
  • quarter
  • year

Автоматический выбор единицы

Если явно не указано unit, Chart.js анализирует диапазон:

  • миллисекунды/секунды → second
  • минуты → minute
  • часы → hour
  • дни → day
  • месяцы → month

Явное задание единицы

time: {
  unit: 'day'
}

Это фиксирует шаг оси независимо от плотности данных.


stepSize

Позволяет задать интервал между делениями:

time: {
  unit: 'day',
  stepSize: 2
}

Результат: метки будут отображаться через каждые 2 дня.


Формат отображения значений

Отображение подписей регулируется через displayFormats.

time: {
  unit: 'month',
  displayFormats: {
    month: 'MMM yyyy'
  }
}

Типичные форматы

  • yyyy-MM-dd — дата
  • HH:mm — время
  • MMM yyyy — месяц и год
  • dd MMM — день и месяц

Форматирование зависит от адаптера:

  • Luxon использует токены Luxon;
  • date-fns использует токены date-fns;
  • Moment использует moment-формат.

Диапазоны и масштабирование

Chart.js автоматически определяет диапазон оси по данным:

  • минимальная дата → начало оси;
  • максимальная дата → конец оси.

Можно задать вручную:

scales: {
  x: {
    min: '2026-01-01',
    max: '2026-12-31'
  }
}

Это фиксирует область отображения независимо от данных.


Формат входных данных и влияние на ось

Без временной оси (категориальная модель)

labels: ['2026-01-01', '2026-01-02']

Это строковые категории, не временная шкала.


С временной осью

data: [
  { x: '2026-01-01', y: 10 },
  { x: '2026-01-02', y: 20 }
]

Разница принципиальная:

  • категории равномерно распределены;
  • время распределяется пропорционально интервалам.

Тики (ticks) и их формирование

Источник тиков

ticks: {
  source: 'auto'
}

Возможные значения:

  • auto — автоматически;
  • data — только по данным;
  • labels — только по меткам (редко используется с time scale).

Ограничение количества тиков

ticks: {
  maxTicksLimit: 8
}

Позволяет избежать перегруженности оси при длинных временных рядах.


Локализация времени

Адаптеры поддерживают локализацию:

  • форматирование месяцев;
  • названия дней недели;
  • региональные форматы дат.

Пример (Luxon):

options: {
  locale: 'ru'
}

Частые ошибки парсинга

Несовпадение формата строки

parser: 'yyyy-MM-dd'
dat a: '01/02/2026' // ошибка интерпретации

Использование секунд вместо миллисекунд

x: 1704067200 // неверно без преобразования
x: 1704067200000 // корректно

Смешивание типов данных

[
  { x: '2026-01-01', y: 10 },
  { x: 1704067200000, y: 12 }
]

Такой подход допустим, но усложняет отладку и может давать неожиданные смещения при разных адаптерах.


Взаимодействие формата и производительности

При больших объёмах данных критично учитывать:

  • предварительный парсинг дат быстрее, чем строковый;
  • числовые timestamp обрабатываются быстрее всего;
  • ISO строки удобны, но требуют дополнительного разбора.

Оптимальная модель для больших датасетов:

{ x: 1704067200000, y: value }

Синхронизация нескольких временных рядов

При нескольких datasets Chart.js использует общую временную шкалу:

datasets: [
  {
    label: 'A',
    data: [{ x: '2026-01-01', y: 5 }]
  },
  {
    label: 'B',
    data: [{ x: '2026-01-01', y: 10 }]
  }
]

Все серии приводятся к единой временной оси, независимо от плотности данных в каждом наборе.