Nivo построена как модульная система поверх React и D3-экосистемы,
где визуализация декомпозирована на независимые пакеты, единое ядро
абстракций и слой провайдеров, отвечающих за контекст, адаптивность и
поведение рендеринга. Такая архитектура позволяет поддерживать множество
типов графиков при минимальном дублировании логики и высокой
согласованности API.
Монорепозиторий и пакетная
структура
Архитектура библиотеки основана на монорепозитории, в котором каждый
тип визуализации выделен в отдельный пакет. Это обеспечивает:
- изоляцию зависимостей конкретных графиков;
- независимое версионирование компонентов внутри общей системы;
- переиспользование ядра без дублирования логики;
- единый стиль API при различии внутренних реализаций.
Структура пакетов обычно делится на несколько категорий:
1. Ядро
@nivo/core — фундаментальная библиотека абстракций
2. Графики
@nivo/bar
@nivo/line
@nivo/pie
@nivo/radar
@nivo/heatmap
@nivo/geo
@nivo/sankey
@nivo/treemap
@nivo/scatterplot
@nivo/stream
Каждый из этих пакетов содержит:
- компонент верхнего уровня (например,
Bar,
Line);
- внутренние примитивы (оси, сетки, слои);
- адаптер данных;
- набор вычислительных функций (layout, stacking, scaling).
Ядро @nivo/core
Пакет @nivo/core является центром архитектуры. Он не
содержит конкретных графиков, но определяет:
Абстракции масштаба и
координат
Используются обёртки над D3-scale:
- linear scale
- band scale
- time scale
- ordinal scale
Эти абстракции унифицируют поведение всех графиков и позволяют
переключать типы шкал без изменения логики рендера.
Система слоёв (layers)
Каждый график в Nivo строится как композиция слоёв:
- оси (axes)
- сетка (grid)
- маркеры данных (bars, dots, arcs)
- аннотации (markers, annotations)
- оверлеи (tooltips, crosshair)
Слои описываются декларативно и могут переопределяться пользователем
через API компонентов.
Общие утилиты
- форматирование данных
- вычисление цветов
- генерация паттернов
- обработка событий (hover, click, mouse move)
- утилиты для анимации
Пакетная специализация
графиков
Каждый график реализует собственную модель данных и геометрии,
сохраняя единый интерфейс React-компонента.
Bar chart (@nivo/bar)
- преобразует категории в band-scale
- строит прямоугольники через вычисление высоты/ширины
- поддерживает stacking и grouped layout
Line chart (@nivo/line)
- использует time/linear scales
- преобразует точки в SVG-path
- поддерживает interpolation (linear, monotone, basis)
Pie chart (@nivo/pie)
- переводит данные в угловые сегменты
- использует arc generator
- управляет радиусами через центрированную систему координат
Geo charts (@nivo/geo)
- интеграция с geo-projection
- работа с GeoJSON
- проекции (mercator, natural earth)
Рендереры: SVG, Canvas
и гибридная модель
Одной из ключевых архитектурных особенностей является поддержка
нескольких рендеринговых стратегий.
SVG-рендеринг
SVG является основным режимом:
- декларативная модель React идеально совпадает с SVG DOM
- удобство стилизации через CSS
- простота взаимодействия (hover, click)
Используется в большинстве стандартных компонентов.
Canvas-рендеринг
Canvas применяется для:
- больших объёмов данных (тысячи точек)
- оптимизации перерисовок
- снижения нагрузки на DOM
Особенности:
- императивное рисование
- контроль через requestAnimationFrame
- отдельные canvas-слои для разных элементов
Гибридный подход
Некоторые графики комбинируют SVG и Canvas:
- Canvas для геометрии
- SVG для интерактивных оверлеев
Это позволяет сохранять интерактивность без потери
производительности.
Провайдеры и контекстная
архитектура
В основе управления состоянием лежит React Context API, через который
передаются глобальные настройки визуализации.
ResponsiveProvider
Отвечает за адаптивность:
- отслеживание размеров контейнера
- пересчёт графика при resize
- автоматическое масштабирование
Ключевая идея — график не знает своих размеров заранее.
ThemeProvider
Централизует визуальный стиль:
- цвета
- типографика
- сетки
- стили осей и подписей
Позволяет переопределять визуальный язык без изменения логики
графика.
MotionProvider
Контролирует анимации:
- включение/выключение motion
- длительность переходов
- easing-функции
Анимации реализуются через библиотеку react-motion или аналоги,
интегрированные в слой рендера.
Контексты данных обеспечивают:
- доступ к текущему элементу графика
- передачу данных в tooltip
- синхронизацию hover-состояний
Поток данных в архитектуре
Nivo
Внутренний pipeline визуализации можно разложить на последовательные
стадии:
1. Входные данные
Исходный массив данных поступает в компонент графика:
- нормализация структуры
- проверка ключей
- маппинг значений
2. Построение шкал
На основе данных формируются scales:
- domain вычисляется автоматически
- range зависит от размеров контейнера
- тип scale выбирается конфигурацией
3. Layout-слой
На этом этапе данные преобразуются в геометрию:
- bar → прямоугольники
- line → точки + path
- pie → arcs
- treemap → иерархические прямоугольники
4. Generators
Используются генераторы:
- d3-shape (arc, line, area)
- кастомные функции для сеток и маркеров
5. Rendering layer
Финальный этап:
- SVG элементы или Canvas draw calls
- применение цветов и стилей
- привязка событий
Компонентная композиция
React
Архитектура строится на композиции:
- верхнеуровневый компонент графика
- внутренние слои
- переиспользуемые примитивы
Компоненты разделяются на:
- presentational (визуальные)
- container (логика и данные)
- hooks-based utilities
Это позволяет заменять части графика без изменения ядра.
Хуки и внутренние утилиты
Используются кастомные React hooks:
useDimensions — измерение контейнера
useScale — работа со шкалами
useAnimatedProps — анимации
useTheme — доступ к теме
useTooltip — управление подсказками
Хуки обеспечивают переносимость логики между разными типами
графиков.
Система слоёв как
ключевая абстракция
Layer model является одной из центральных концепций:
- каждый слой — независимая функция рендера
- слои можно добавлять/удалять
- порядок слоёв влияет на визуальную композицию
Пример типичного набора:
- grid
- axes
- bars/lines/arcs
- markers
- legends
- annotations
Такая структура позволяет расширять графики без модификации исходного
кода.
Производительность и
оптимизации
Архитектура учитывает высокие нагрузки:
- мемоизация вычислений (React.memo, useMemo)
- кэширование шкал
- разделение Canvas слоёв
- минимизация DOM-операций
- выборочная перерисовка элементов
Canvas-режим особенно важен для сценариев с десятками тысяч точек,
где SVG становится узким местом.
Расширяемость архитектуры
Система спроектирована так, чтобы новые графики могли добавляться без
изменения ядра:
- переиспользование
@nivo/core
- подключение собственных layers
- кастомные tooltip-реализации
- альтернативные renderers
Архитектура допускает создание полностью новых типов визуализаций при
сохранении стандартного API-компонента React.