Цветовая шкала по значениям (choropleth)

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

Ключевой механизм заключается в отображении диапазона значений → диапазон цветов, где:

  • минимальные значения соответствуют более «холодным» или светлым оттенкам
  • максимальные значения — более «тёплым» или насыщенным
  • промежуточные значения интерполируются или попадают в диапазоны (в зависимости от типа шкалы)

В Nivo это реализуется через комбинацию:

  • colorScale
  • domain
  • colors
  • unknownColor
  • valueFormat

Базовая структура Choropleth в Nivo

Компонент строится вокруг геоданных (TopoJSON или GeoJSON) и набора данных:

import { ResponsiveChoropleth } from '@nivo/geo'
import worldCountries from './world_countries.json'

const data = [
  { id: 'FRA', value: 123 },
  { id: 'USA', value: 456 },
  { id: 'RUS', value: 78 }
]

Ключевой момент: поле id должно совпадать с идентификатором в геоданных (feature.id или заданное поле через match).


Настройка цветовой шкалы

Основная конфигурация задаётся через colors и colorScale.

<ResponsiveChoropleth
  data={data}
  features={worldCountries.features}
  match={d => d.id}
  colors="YlOrRd"
/>

Здесь используется готовая палитра ColorBrewer. Nivo поддерживает множество схем:

  • Sequential (последовательные)
  • Diverging (дивергентные)
  • Cyclical (циклические)
  • Custom arrays

Типы цветовых шкал

Последовательная шкала

Используется для монотонно возрастающих данных.

colors={{
  scheme: 'blues'
}}

Поведение:

  • низкие значения → светло-синие
  • высокие значения → тёмно-синие

Такая шкала применяется для:

  • плотности населения
  • количества заказов
  • температурных карт

Дивергентная шкала

Используется, когда важно выделить центр (нулевое или среднее значение).

colors={{
  scheme: 'spectral'
}}

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

  • центр шкалы — нейтральный цвет
  • крайние значения расходятся в разные оттенки

Применяется для:

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

Пользовательская шкала

Можно задать собственные цвета:

colors={[
  '#f7fbff',
  '#c6dbef',
  '#6baed6',
  '#2171b5',
  '#08306b'
]}

В этом случае Nivo автоматически интерполирует значения между цветами.


Пороговая (threshold) шкала

Один из наиболее точных способов управления визуализацией.

<ResponsiveChoropleth
  data={data}
  features={worldCountries.features}
  domain={[0, 100, 200, 500, 1000]}
  colors={['#edf8fb', '#b3cde3', '#8c96c6', '#8856a7', '#810f7c']}
  unknownColor="#666666"
/>

Механика работы

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

Когда использовать

  • отчётные дашборды
  • KPI с порогами
  • классифицированные данные (низкий/средний/высокий)

Непрерывная шкала

При непрерывной шкале цвет вычисляется через интерполяцию.

colors={{
  type: 'sequential',
  scheme: 'greens'
}}

Или через кастом:

colors={{
  type: 'sequential',
  colors: ['#e5f5e0', '#31a354']
}}

Особенность

Каждое значение преобразуется в число от 0 до 1, затем интерполируется цвет.


Логарифмическая шкала

Используется для данных с сильной асимметрией.

colors={{
  type: 'sequential',
  scale: 'log',
  scheme: 'oranges'
}}

Подходит для:

  • экономики (доходы стран)
  • вирусной статистики
  • данных с экспоненциальным ростом

Обработка отсутствующих значений

Если данные не содержат значения для региона, используется unknownColor.

unknownColor="#d3d3d3"

Типичные стратегии:

  • серый цвет для отсутствующих данных
  • прозрачность
  • отдельная категория «no data»

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

Ключевая часть choropleth — сопоставление данных и географии.

match={(feature) => feature.id}

Варианты:

  • feature.id
  • feature.properties.code
  • кастомная функция поиска

При несовпадении данных регион будет окрашен в unknownColor.


Управление диапазоном значений

Nivo позволяет явно задать домен:

domain={[0, 1000]}

Если домен не задан:

  • он вычисляется автоматически
  • по минимуму и максимуму данных

Форматирование значений

Для отображения значений в tooltip используется valueFormat:

valueFormat=" >-.2f"

Примеры:

  • >-.0f — целые числа
  • .2f — два знака после запятой
  • +,.0f — с плюсом и разделителями

Легенда цветовой шкалы

Легенда критична для интерпретации choropleth.

legends={[
  {
    anchor: 'bottom-left',
    direction: 'column',
    translateX: 20,
    itemWidth: 80,
    itemHeight: 18,
    symbolSize: 12
  }
]}

Типы легенд:

  • градиентная шкала
  • дискретные диапазоны
  • интерактивные фильтры (в кастомных реализациях)

Стилизация границ регионов

Цветовая шкала усиливается визуально через контуры:

borderWidth={0.5}
borderColor="#152538"

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


Анимация цветовых переходов

Nivo поддерживает плавную интерполяцию:

motionConfig="gentle"

Эффекты:

  • плавная перекраска при обновлении данных
  • интерполяция между цветами
  • анимация hover-состояний

Паттерны и текстуры как дополнение к цвету

Помимо цветовой шкалы можно использовать defs:

defs={[
  {
    id: 'dots',
    type: 'patternDots',
    background: 'inherit',
    color: '#ffffff',
    size: 4,
    padding: 1,
    stagger: true
  }
]}

И применение:

fill={[
  {
    match: { id: 'USA' },
    id: 'dots'
  }
]}

Это позволяет:

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

Практика выбора цветовой схемы

Выбор шкалы зависит от характера данных:

Монотонные данные

  • blues, greens, purples
  • sequential

Сравнение отклонений

  • red-blue, spectral
  • diverging

Категоризация по порогам

  • threshold шкала

Сильно перекошенные данные

  • log scale

Типичные ошибки при настройке шкалы

  • несовпадение id между данными и географией
  • отсутствие обработки undefined значений
  • слишком близкие оттенки (низкий контраст)
  • неправильный домен (искажение распределения)
  • использование diverging шкалы для монотонных данных

Поведение при динамическом обновлении данных

При изменении data Nivo:

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

При этом фиксированный domain стабилизирует визуализацию и предотвращает «скачки» цветов между обновлениями.