Работа с временными рядами

Библиотека визуализации данных Nivo ориентирована на работу с декларативными компонентами React и предоставляет мощные инструменты для построения графиков, включая поддержку временных рядов через компоненты линейных и площадных диаграмм. Основная особенность работы с временными данными заключается в корректной подготовке дат, настройке временных шкал и выборе подходящего формата структурирования данных.

Типичный временной ряд в Nivo строится вокруг массивов объектов, где каждое значение привязано к конкретному моменту времени.

const data = [
  {
    id: "temperature",
    data: [
      { x: "2024-01-01", y: 10 },
      { x: "2024-01-02", y: 12 },
      { x: "2024-01-03", y: 8 }
    ]
  }
];

Поле x может быть строкой, числом или объектом Date, однако при работе с временными шкалами предпочтение отдается объекту Date, что обеспечивает корректную интерпретацию временной оси.


Использование временной шкалы (time scale)

В Nivo настройка временной шкалы осуществляется через параметр xScale с типом time. Это ключевой элемент для корректного отображения временных рядов, так как он определяет способ интерпретации значений оси X.

xScale={{
  type: "time",
  format: "%Y-%m-%d",
  useUTC: false,
  precision: "day"
}}

Основные параметры:

  • type: “time” — включает обработку временных данных
  • format — формат входной строки даты (если используется парсинг)
  • precision — точность временной шкалы (day, hour, minute)
  • useUTC — управление временной зоной

При использовании объектов Date форматирование строки не требуется, но параметр precision остаётся важным для корректного распределения точек по оси.


Подготовка данных для временных рядов

Корректная подготовка данных критична для стабильного отображения графиков. Временные значения должны быть либо строго отсортированы, либо гарантированно приводимы к хронологическому порядку.

Пример преобразования строк в Date:

const rawData = [
  { date: "2024-01-01", value: 5 },
  { date: "2024-01-03", value: 8 }
];

const formattedData = [
  {
    id: "series-1",
    data: rawData.map(d => ({
      x: new Date(d.date),
      y: d.value
    }))
  }
];

Ключевые моменты подготовки:

  • единый формат дат во всём наборе
  • отсутствие пропусков или некорректных значений
  • сортировка по возрастанию времени
  • согласованность временной зоны

Линейные временные графики (Line Time Series)

Компонент ResponsiveLine является основным инструментом для визуализации временных рядов. Он поддерживает множественные серии данных и позволяет гибко управлять отображением линий.

import { ResponsiveLine } from '@nivo/line';

<ResponsiveLine
  data={data}
  xScale={{
    type: "time",
    format: "native",
    precision: "day"
  }}
  yScale={{
    type: "linear",
    min: "auto",
    max: "auto",
    stacked: false
  }}
  axisBottom={{
    format: "%b %d",
    tickValues: "every 2 days",
    legend: "Время",
    legendOffset: 36
  }}
/>

Особенности:

  • поддержка нескольких временных рядов
  • автоматическая интерполяция оси X
  • возможность сглаживания линий
  • кастомизация точек данных

Площадные временные графики (Area Time Series)

Площадные графики используются для отображения накопительных или сравнительных временных значений. В Nivo они реализуются через ResponsiveAreaBump или ResponsiveArea.

<ResponsiveArea
  data={data}
  xScale={{
    type: "time",
    format: "native",
    precision: "day"
  }}
  yScale={{
    type: "linear",
    stacked: true
  }}
  curve="monotoneX"
/>

Ключевые особенности:

  • поддержка stacked-режима
  • визуализация накопленных значений
  • сглаживание кривых через curve
  • высокая читаемость трендов

Интерполяция и сглаживание данных

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

Основные варианты:

  • linear — прямые сегменты
  • monotoneX — сглаживание без пересечений
  • basis — плавные кривые
  • cardinal — усиленное сглаживание
curve="monotoneX"

Выбор интерполяции влияет на восприятие динамики данных. Для финансовых и научных данных чаще применяется monotoneX, так как он сохраняет монотонность.


Работа с пропущенными значениями

Временные ряды часто содержат пропуски. Nivo обрабатывает их в зависимости от структуры данных:

  • отсутствие точки — разрыв линии
  • y: null — явный пропуск
  • undefined — игнорирование точки

Пример обработки:

data.map(d => ({
  x: new Date(d.date),
  y: d.value ?? 0
}));

Или сохранение разрывов:

data.map(d => ({
  x: new Date(d.date),
  y: d.value ?? null
}));

Разрывы визуально фиксируются и позволяют анализировать неполные периоды.


Масштабирование осей и диапазоны времени

Для временных рядов критически важно корректно настроить масштаб оси X. В Nivo используется комбинация min, max и автоматического определения диапазона.

xScale={{
  type: "time",
  min: new Date("2024-01-01"),
  max: new Date("2024-12-31")
}}

Особенности:

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

Форматирование оси времени

Отображение времени на оси X требует форматирования, особенно при высокой плотности данных.

axisBottom={{
  format: "%d %b",
  tickRotation: -45,
  tickValues: "every 7 days"
}}

Часто используемые форматы:

  • %Y — год
  • %m — месяц
  • %d — день
  • %H:%M — время

Правильная настройка предотвращает наложение подписей и улучшает читаемость графика.


Несколько временных серий

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

const data = [
  {
    id: "product A",
    data: [
      { x: new Date("2024-01-01"), y: 10 },
      { x: new Date("2024-01-02"), y: 15 }
    ]
  },
  {
    id: "product B",
    data: [
      { x: new Date("2024-01-01"), y: 8 },
      { x: new Date("2024-01-02"), y: 12 }
    ]
  }
];

Особенности многосерийных графиков:

  • автоматическое разделение цветов
  • независимая обработка каждой серии
  • единая временная шкала
  • синхронизированные tooltips

Tooltip и взаимодействие с временными данными

Tooltip в временных графиках Nivo играет ключевую роль в анализе значений.

tooltip={({ point }) => (
  <div>
    <strong>{point.data.xFormatted}</strong>
    <div>{point.data.y}</div>
  </div>
)}

Функциональные возможности:

  • отображение точных дат
  • форматирование значений
  • сравнение нескольких серий в одной точке времени
  • кастомные визуальные компоненты

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

При работе с большими массивами данных важны оптимизации:

  • ограничение количества точек (downsampling)
  • использование мемоизации данных
  • отключение лишних анимаций
  • применение упрощённых интерполяций

Пример отключения анимации:

animate={false}
motionConfig="stiff"

Адаптивность временных графиков

Компоненты Nivo полностью адаптивны, что особенно важно для временных рядов с плотной осью X.

<ResponsiveLine
  data={data}
  margin={{ top: 50, right: 110, bottom: 50, left: 60 }}
/>

Адаптивность включает:

  • автоматическое масштабирование
  • перерасчёт осей при изменении контейнера
  • скрытие части подписей при нехватке места

Практика комбинирования временных рядов и агрегирования

Часто временные данные требуют агрегации по интервалам:

  • по дням
  • по неделям
  • по месяцам

Пример агрегации:

const grouped = rawData.reduce((acc, item) => {
  const key = item.date.slice(0, 10);
  acc[key] = (acc[key] || 0) + item.value;
  return acc;
}, {});

После агрегации данные приводятся к формату Nivo и визуализируются как единый временной ряд.