Цветовые системы в визуализации данных на базе Nivo строятся вокруг идеи предсказуемого сопоставления значений и визуальных характеристик. Цвет здесь выступает не декоративным элементом, а семантическим кодом, который должен сохранять стабильность при изменении данных, масштабировании и переключении режимов отображения. В экосистеме Nivo это реализуется через комбинацию шкал (scales), палитр и интерполяторов, заимствованных из подходов d3-scale и d3-scale-chromatic, с дополнительными абстракциями библиотеки.
Цветовая модель в Nivo опирается на три базовых подхода:
Во всех случаях ключевым параметром выступает свойство
colors, которое присутствует практически во всех визуальных
компонентах: ResponsiveBar, ResponsivePie,
ResponsiveHeatMap, ResponsiveChoropleth и
других.
Формат colors в Nivo допускает несколько стратегий:
(datum) => color@nivo/colorsТакой полиморфизм позволяет унифицировать цветовое поведение для разных типов графиков.
Категориальные шкалы применяются для дискретных данных, где каждое значение не имеет числового смысла в контексте цвета.
Типичная конфигурация:
colors: { scheme: 'nivo' }
или использование предустановленных схем:
nivocategory10accentdark2pairedЭти схемы основаны на фиксированных наборах оттенков, где каждый следующий элемент массива данных получает следующий цвет по индексу.
Пример поведения:
colors: ['#e8c1a0', '#f47560', '#f1e15b', '#e8a838']
Если элементов больше, чем цветов в палитре, происходит циклическое повторение.
Внутри Nivo используется механизм индексного маппинга:
color = palette[index % palette.length]
Такой подход обеспечивает стабильность визуализации при отсутствии явной привязки к ключам.
Для предотвращения «скачков» цветов при обновлении данных применяется ключевая стабилизация по идентификатору:
colors: { datum: 'id' }
В этом случае цвет назначается не по индексу, а по хешированию или
внутреннему индексному реестру значений id.
Последовательные шкалы применяются для числовых данных, где цвет должен отражать интенсивность или величину.
Типичный вариант:
colors: { scheme: 'blues' }
или:
colors: { scheme: 'greens' }
Эти схемы построены на интерполяции оттенков одного цветового диапазона.
В основе лежит функция:
t ∈ [0, 1] → color
где t — нормализованное значение данных.
В d3 используется набор интерполяторов:
interpolateRgbinterpolateHslinterpolateLabinterpolateHclinterpolateViridisNivo абстрагирует это через @nivo/colors, позволяя
задавать схемы без прямого обращения к интерполяторам.
Пример логики:
value → normalize → t → interpolate(t) → color
Хотя Nivo не всегда явно задаёт тип шкалы в пропсе
colors, поведение интерполяции зависит от нормализации
входных данных. Для сильно распределённых данных применяется
логарифмическая или экспоненциальная подготовка до передачи в цветовую
шкалу.
Дивергентные палитры используются в случаях, когда существует центральное значение и отклонения в обе стороны.
Примеры схем:
RdBuPiYGSpectralТакие шкалы задаются через центр:
min → colorA → center → colorB → max
Логика интерполяции:
if (t < 0.5) interpolate(A, center)
else interpolate(center, B)
В Nivo это применяется в компонентах тепловых карт и географических визуализаций.
Центральное значение может быть фиксированным или вычисляемым:
Помимо предустановленных схем, Nivo поддерживает передачу функций, определяющих цвет вручную.
Пример:
colors: (bar) => bar.value > 100 ? '#ff4d4d' : '#4dff88'
Такой подход полностью отключает шкалирование и передаёт контроль пользователю.
Возможна интеграция с интерполяторами:
import { interpolatePlasma } from 'd3-scale-chromatic'
И применение:
colors: (d) => interpolatePlasma(d.value / max)
Это даёт доступ к непрерывным спектрам высокой плотности.
При необходимости можно строить собственные градиентные функции:
f(t) = mix(colorA, colorB, t)
где mix реализует линейную интерполяцию по RGB или HSL
каналам.
Разные компоненты Nivo используют цветовые шкалы по-разному.
В столбчатых и линейных графиках цвет обычно зависит от серии данных:
Возможна переопределённая логика:
colors: { scheme: 'set2' }
Круговые диаграммы используют категориальную шкалу с сильной визуальной различимостью.
Особенность:
idТепловые карты используют последовательные или дивергентные шкалы.
Пример:
colors: { scheme: 'reds' }
или кастомная функция:
colors: (cell) => interpolateViridis(cell.value / max)
Географические карты используют нормализованные шкалы:
naColor)Стабильность цветовой системы критична при динамических данных.
Основные принципы:
Использование id вместо индекса:
color = map[id]
Избегание динамических генераторов без seed:
palette = ['#...','#...']
При превышении палитры возникает повторение, что снижает читаемость.
Один и тот же id должен иметь одинаковый цвет во всех
визуализациях.
Цвета в Nivo могут модифицироваться через альфа-канал:
rgba(244, 117, 96, 0.5)
или через HSL:
hsla(12, 80%, 60%, 0.4)
Также возможна динамическая регулировка:
colors: (d) => hexToRgba(baseColor, d.opacity)
Полупрозрачность используется для:
При большом количестве элементов прозрачность становится инструментом предотвращения перегрузки визуального канала.
Через HSL-модель возможно управление:
Пример логики:
if (selected) increase saturation
else decrease lightness
Такие подходы часто применяются в интерактивных графиках, где состояние элемента влияет на его визуальный вес.
Цветовая система Nivo формируется как комбинация детерминированных палитр, математических интерполяций и функциональных переопределений, обеспечивая баланс между предсказуемостью и гибкостью при визуализации сложных данных.