Группировка столбцов: grouped и stacked

В библиотеке Nivo механизм отображения столбчатых диаграмм поддерживает два основных режима компоновки многосерийных данных: grouped и stacked. Эти режимы определяют способ визуального представления нескольких наборов значений, относящихся к одним и тем же категориям по оси X.

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

const data = [
  {
    country: 'Kazakhstan',
    sales: 120,
    profit: 45,
    loss: 10,
  },
  {
    country: 'Russia',
    sales: 180,
    profit: 60,
    loss: 20,
  },
];

Поля sales, profit, loss выступают как серии. Поле country используется как индекс категории.

При передаче данных в компонент важно явно указать:

  • indexBy — поле категории
  • keys — массив серий
keys={['sales', 'profit', 'loss']}
indexBy="country"

Режим grouped: группировка столбцов

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

Конфигурация grouped

import { ResponsiveBar } from '@nivo/bar';

<ResponsiveBar
  data={data}
  keys={['sales', 'profit', 'loss']}
  indexBy="country"
  groupMode="grouped"
  margin={{ top: 50, right: 130, bottom: 50, left: 60 }}
  padding={0.3}
  colors={{ scheme: 'nivo' }}
/>

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

  • Каждая категория содержит набор отдельных столбцов
  • Высота каждого столбца отражает абсолютное значение
  • Сравнение выполняется горизонтально внутри группы
  • Количество визуальных элементов растёт пропорционально числу серий

Поведение масштабирования

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

Типичные сценарии применения

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

Режим stacked: составные столбцы

Режим stacked объединяет серии в один столбец на категорию. Значения суммируются, образуя составную структуру.

Конфигурация stacked

<ResponsiveBar
  data={data}
  keys={['sales', 'profit', 'loss']}
  indexBy="country"
  groupMode="stacked"
  margin={{ top: 50, right: 130, bottom: 50, left: 60 }}
  padding={0.3}
  colors={{ scheme: 'nivo' }}
/>

Механика построения

Каждая категория формирует один столбец, разбитый на сегменты:

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

Математически высота столбца выражается как:

y = _{i=1}^{n} x_i

где (x_i) — значения серий в пределах одной категории.

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

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

Применение stacked

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

Сравнение grouped и stacked на уровне поведения данных

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

grouped

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

stacked

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

Обработка отрицательных значений

Оба режима поддерживают отрицательные числа, но поведение различается.

grouped

Отрицательные значения отображаются ниже нулевой оси независимо от других серий. Пересечения отсутствуют.

stacked

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

Цветовое кодирование серий

Цвета назначаются на уровне keys и сохраняются между режимами. Это обеспечивает сопоставимость восприятия при переключении между grouped и stacked.

colors={{ scheme: 'category10' }}

При необходимости используется кастомная функция:

colors={(bar) => {
  if (bar.id === 'sales') return '#4f46e5';
  if (bar.id === 'profit') return '#22c55e';
  return '#ef4444';
}}

Легенды и интерпретация серий

В stacked режиме легенда отражает вклад компонентов в общий итог. В grouped режиме — отдельные независимые значения.

legends={[
  {
    dataFrom: 'keys',
    anchor: 'bottom-right',
    direction: 'column',
  },
]}

Анимация и переключение режимов

Nivo поддерживает плавный переход между grouped и stacked при изменении свойства groupMode. При этом:

  • сохраняется структура данных
  • пересчитывается позиционирование столбцов
  • применяется интерполяция высоты и координат
const [mode, setMode] = useState('grouped');

<ResponsiveBar groupMode={mode} />

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

При увеличении числа серий различия между режимами становятся критичнее:

  • grouped увеличивает ширину диаграммы
  • stacked сохраняет плотность, но теряет детализацию внутренних значений

При высокой кардинальности серий stacked режим обеспечивает более компактное представление.

Комбинация с другими настройками Bar-компонента

padding

В grouped режиме padding влияет на расстояние между группами и внутри группы:

padding={0.2}

innerPadding

Используется для увеличения расстояния между столбцами внутри группы, особенно при большом числе keys.

axis scaling

Ось автоматически пересчитывается в зависимости от выбранного режима, однако при stacked значения часто требуют более широкого диапазона из-за суммирования.

Поведение tooltip

Tooltip в grouped режиме показывает отдельное значение серии. В stacked режиме дополнительно доступна информация о суммарном значении категории и доле каждого сегмента относительно общего стека.

Практическая структура данных для масштабируемых сценариев

При работе с динамическими наборами данных используется нормализация keys:

const keys = Object.keys(data[0]).filter(k => k !== 'country');

Такой подход обеспечивает автоматическую адаптацию диаграммы при изменении структуры входных данных.

Переключаемые визуализации как модель анализа

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

  • grouped — анализ компонент
  • stacked — анализ агрегатов

Совмещение этих режимов в интерфейсных решениях повышает информативность без изменения структуры данных.