Компонент TimeRange

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

Использование TimeRange характерно для систем мониторинга, планирования, аналитики процессов и отображения активности во времени. Визуализация строится вокруг двух ключевых измерений: временной оси и диапазонов значений, привязанных к этой оси.

Установка и подключение

Компонент входит в отдельный пакет экосистемы Nivo:

npm install @nivo/timerange

или

yarn add @nivo/timerange

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

import { TimeRange } from '@nivo/timerange'

Библиотека требует наличия React и зависимостей Nivo Core, обеспечивающих работу с d3-таймлайнами и внутренними утилитами масштабирования.

Структура входных данных

Данные для TimeRange формируются в виде массива объектов, каждый из которых описывает один временной интервал.

Базовая структура:

const data = [
  {
    id: 'task-1',
    start: new Date('2026-01-01T08:00:00'),
    end: new Date('2026-01-01T12:00:00'),
    group: 'A'
  },
  {
    id: 'task-2',
    start: new Date('2026-01-01T11:00:00'),
    end: new Date('2026-01-01T15:30:00'),
    group: 'B'
  }
]

Ключевые поля:

  • id — уникальный идентификатор интервала
  • start — начало временного диапазона
  • end — окончание временного диапазона
  • group — логическая группировка (опционально)

Временные значения могут передаваться как объекты Date, ISO-строки или timestamp, в зависимости от конфигурации парсинга.

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

TimeRange настраивается через набор пропсов, управляющих поведением оси, внешним видом и интерактивностью.

data

Основной источник данных:

<TimeRange data={data} />

xScale

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

xScale={{
  type: 'time',
  format: 'native',
  precision: 'minute'
}}

Типы масштабов:

  • time — непрерывное время
  • linear — числовая шкала (используется редко)
  • point — дискретные значения

yScale

Отвечает за вертикальное размещение интервалов:

yScale={{
  type: 'band',
  padding: 0.2
}}

Каждая группа или элемент получает свою строку на диаграмме.

margin

Контроль отступов вокруг графика:

margin={{
  top: 50,
  right: 30,
  bottom: 50,
  left: 80
}}

Работа с временной осью

Временная ось в TimeRange основана на d3-time масштабировании. Она автоматически адаптируется под диапазон данных.

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

  • автоматическое определение интервалов (секунды, минуты, часы, дни)
  • поддержка локализации формата времени
  • масштабирование при зуме (если включено)
  • сглаживание плотных интервалов

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

xFormat="time:%H:%M"

или через функцию:

format={(value) => value.toLocaleTimeString()}

Цветовая модель и стилизация

Цвета интервалов задаются через функцию colors, массив или шкалу:

colors={{ scheme: 'nivo' }}

или

colors={(d) => {
  if (d.group === 'A') return '#4f46e5'
  if (d.group === 'B') return '#16a34a'
  return '#6b7280'
}}

Дополнительные параметры оформления:

  • borderWidth — толщина границ
  • borderColor — цвет границ
  • opacity — прозрачность элементов
  • rounded — скругление углов полос

Tooltip и интерактивность

Tooltip отображает подробности при наведении на временной интервал.

Базовая настройка:

tooltip={({ data }) => (
  <div>
    <div>ID: {data.id}</div>
    <div>Start: {data.start.toString()}</div>
    <div>End: {data.end.toString()}</div>
  </div>
)}

Интерактивные события:

  • onClick — клик по интервалу
  • onMouseEnter — наведение
  • onMouseLeave — уход курсора

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

onCl ick={(bar) => {
  console.log(bar.data.id)
}}

Анимации

TimeRange использует встроенную систему анимаций Nivo на базе react-spring.

Настройка анимации:

animate={true}
motionConfig="gentle"

Параметры:

  • gentle — плавные переходы
  • wobbly — более выраженные движения
  • stiff — быстрые реакции

Анимации применяются к:

  • появлению интервалов
  • изменению размеров
  • пересчету шкалы
  • фильтрации данных

Кастомные слои

Архитектура слоев позволяет расширять график без изменения ядра компонента.

Доступные слои:

  • axes
  • grid
  • bars
  • markers
  • legends

Добавление собственного слоя:

layers={[
  'grid',
  'axes',
  'bars',
  ({ innerHeight, innerWidth }) => (
    <g>
      <line
        x1={0}
        x2={innerWidth}
        y1={innerHeight / 2}
        y2={innerHeight / 2}
        stroke="#000"
      />
    </g>
  )
]}

Кастомные слои позволяют добавлять:

  • линии SLA
  • маркеры текущего времени
  • зоны активности
  • выделенные интервалы

Группировка и многорядное отображение

При наличии поля group данные распределяются по строкам.

Пример группировки:

const data = [
  { id: 'a1', group: 'backend', start, end },
  { id: 'a2', group: 'frontend', start, end }
]

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

Масштабирование и производительность

При большом количестве интервалов применяется оптимизация рендеринга:

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

Рекомендации по структуре данных:

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

Пример конфигурации компонента

<TimeRange
  data={data}
  margin={{ top: 40, right: 40, bottom: 40, left: 100 }}
  xScale={{
    type: 'time',
    format: 'native',
    precision: 'minute'
  }}
  yScale={{
    type: 'band',
    padding: 0.3
  }}
  colors={{ scheme: 'category10' }}
  borderWidth={1}
  borderColor="#333"
  animate={true}
  motionConfig="gentle"
  tooltip={({ data }) => (
    <div>
      <strong>{data.id}</strong>
    </div>
  )}
  layers={['grid', 'axes', 'bars']}
/>

Обработка пересечений интервалов

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

Логика включает:

  • сортировку по времени начала
  • проверку пересечений start/end
  • назначение доступного уровня размещения

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

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

Гибкость форматирования реализуется через d3-time-format:

xFormat="%d %b %H:%M"

Поддерживаются:

  • локальные форматы
  • кастомные функции преобразования
  • адаптивное отображение в зависимости от масштаба

События масштабирования

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

  • изменение диапазона времени
  • перерасчет оси X
  • перераспределение элементов

Механизм позволяет анализировать узкие временные окна без потери детализации.