Алгоритмы укладки: wiggle, expand, none

В библиотеке Nivo визуализация накопительных рядов данных в областных графиках строится на механизме стековой компоновки. Он определяет, как значения нескольких серий накладываются друг на друга по оси Y, формируя итоговую форму графика. Ключевой параметр, отвечающий за это поведение, — stackOffset.

При построении стековых графиков каждая серия данных рассматривается как слой. Алгоритм компоновки определяет:

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

В Nivo для stackOffset доступны несколько стратегий, среди которых три фундаментальные: none, expand, wiggle.


stackOffset: none

Режим none задаёт классическую стековую компоновку без нормализации и дополнительных трансформаций.

Каждое значение серии суммируется с предыдущими слоями, формируя абсолютную высоту.

Математическая модель

Для серии ( i ) и точки ( x ):

[ y_{i}(x) = {k=0}^{i} v{k}(x)]

где:

  • ( v_k(x) ) — исходное значение серии,
  • ( y_i(x) ) — накопленное значение на текущем уровне.

Характер поведения

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

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

import { ResponsiveArea } from '@nivo/area';

const MyChart = ({ data }) => (
    <ResponsiveArea
        data={data}
        keys={['seriesA', 'seriesB', 'seriesC']}
        indexBy="time"
        stackOffset="none"
    />
);

stackOffset: expand

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

Математическая модель

[ y_{i}(x) = ]

где знаменатель — сумма всех серий в точке ( x ).

Особенности алгоритма

  • каждая точка нормируется относительно общей суммы;
  • абсолютные значения теряют смысл;
  • отображается структура долей;
  • суммарная высота фиксирована и равна 1 (или 100%).

Поведение визуализации

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

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

import { ResponsiveArea } from '@nivo/area';

const MyChart = ({ data }) => (
    <ResponsiveArea
        data={data}
        keys={['seriesA', 'seriesB', 'seriesC']}
        indexBy="time"
        stackOffset="expand"
    />
);

stackOffset: wiggle

Режим wiggle реализует алгоритм, известный как streamgraph-компоновка. Его задача — минимизировать «дрожание» центральной линии и создать визуально плавное течение слоёв.

Этот метод используется для построения потоковых диаграмм, где важна эстетика формы и восприятие динамики.

Принцип работы

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

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

Интуитивная модель

В отличие от none, где стек растёт вверх от нуля, и expand, где всё нормируется, wiggle использует адаптивную базовую линию, которая «плавает» между слоями.

Цель — минимизация функции:

[ (y_i(x) - y_{i-1}(x))^2]

в упрощённой форме, что приводит к более равномерному распределению изгибов.

Характер визуализации

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

Пример использования в Nivo

import { ResponsiveArea } from '@nivo/area';

const StreamChart = ({ data }) => (
    <ResponsiveArea
        data={data}
        keys={['seriesA', 'seriesB', 'seriesC']}
        indexBy="time"
        stackOffset="wiggle"
    />
);

Сравнение поведения алгоритмов

Сохранение абсолютных значений

  • none — сохраняет полностью
  • expand — полностью нормирует
  • wiggle — частично искажает ради формы

Визуальная цель

  • none — аналитическая точность
  • expand — долевое распределение
  • wiggle — потоковая эстетика

Поведение базовой линии

  • none — фиксированный ноль
  • expand — фиксированная единица
  • wiggle — динамическая адаптивная линия

Практические сценарии использования

Аналитика абсолютных значений

Использование none оправдано при необходимости отображения реальных объёмов данных:

  • продажи по категориям;
  • нагрузка на систему;
  • финансовые показатели.

В таких сценариях важна точная высота стеков и их суммарное значение.


Анализ структуры и долей

Режим expand применяется при исследовании относительных вкладов:

  • доли рынка;
  • распределение ресурсов;
  • процентные изменения в составе.

Здесь ключевым является сравнение пропорций, а не абсолютных чисел.


Потоковые визуализации

wiggle используется для визуально сложных временных рядов:

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

Основная задача — не точность, а восприятие динамики.


Особенности вычислений и производительности

Внутренние алгоритмы стековой компоновки в Nivo выполняются на этапе подготовки данных перед рендерингом SVG или Canvas.

Общие этапы обработки

  1. агрегация значений по ключам;
  2. вычисление стековых смещений;
  3. применение выбранного stackOffset;
  4. генерация координат кривых;
  5. передача данных в слой отрисовки.

Различия по вычислительной сложности

  • none — минимальная нагрузка, простое суммирование;
  • expand — дополнительная операция нормализации на каждую точку;
  • wiggle — наиболее затратный режим из-за расчёта сглаженной базовой линии.

Влияние на рендеринг

При больших наборах данных:

  • none масштабируется наиболее предсказуемо;
  • expand требует стабильного суммирования для каждой оси X;
  • wiggle может увеличивать время подготовки данных из-за вычисления оптимальной формы слоя.

Поведение при разреженных данных

  • none корректно отображает пропуски как нули или разрывы;
  • expand перераспределяет доли даже при малых значениях;
  • wiggle может усиливать визуальные искажения при нерегулярных рядах.

Взаимодействие с интерполяцией кривых

Алгоритмы stackOffset работают совместно с типами кривых (curve), влияя на итоговую форму:

  • при линейной интерполяции изменения выглядят угловато;
  • при сглаженных кривых усиливается эффект wiggle;
  • при плотных данных expand даёт наиболее стабильную геометрию.