GrChartWaterfall
Берут, когда движение от остатка к остатку.
Когда брать
- движение от остатка к остатку — подписки, обязательства, склад: видно не только каждое изменение, но и то, как из начала месяца получился конец;
- проверить, сходится ли баланс — шаги
kind: 'total'ставят реальные значения на начало и на конец, и расхождение с суммой движений становится видно глазом, а не в уме; - разложить дельту между двумя числами — «выручка выросла на 12 %» и четыре причины этого роста читаются как одна история;
- прибавления и убавления вперемешку — цвет идёт по знаку, и направление каждого шага видно до чтения подписей;
- шагов немного — до полутора-двух десятков; дальше подписи оси налезают друг на друга, и мост стоит свернуть до крупных статей.
Когда взять другое
| Нужно | Берите |
|---|---|
| Сравнить величины по категориям, без преемственности | GrChartBar |
| Показать состав одного целого на один момент | GrChartPie |
| Показать ход величины во времени | GrChartLine |
| Показать, где теряются пользователи между ступенями | GrChartFunnel |
| Показать одно число с динамикой | GrStatistic |
Шаг `total` объявляет накопление, а не прибавляется к нему
kind: 'delta' (по умолчанию) — изменение от текущего накопления,
kind: 'total' — абсолютное значение: столбец рисуется от нуля, а накопление
сбрасывается на него. Это и позволяет поставить «На начало» и «На конец»
реальными числами с бэкенда: если мост не сходится, последний столбец не
совпадёт с вершиной предпоследнего, и ошибку в данных будет видно.
Соединитель к такому шагу не рисуется. Он не продолжает накопление, а объявляет его, и линия «отсюда сюда» соврала бы о преемственности.
Цвет идёт по знаку, а не по индексу серии
Мост — один ряд, и палитра серий здесь ничего не различает: различать надо
прибавление (--gr-success) и убавление (--gr-danger). Итог и объявленное
накопление красятся нейтрально (--gr-chart-1) — это не движение. Явный color
шага сильнее любого из этих правил.
Нулевой шаг рисуется чертой
«Движения не было» — это факт, а не отсутствие данных. Столбец нулевой высоты
пропал бы с рисунка, и читатель увидел бы историю, в которой такого шага нет
вовсе. Вместо этого на уровне накопления встаёт черта толщиной
--gr-chart-waterfall-zero-step.
Таблица несёт накопление, а не одну дельту
Скрытая таблица даёт три числа на шаг: изменение, накопление до и накопление после. По одной дельте мост не восстановить — высоту столбца задаёт именно накопление, и читающий без зрения обязан видеть то же, что зрячий видит по положению полосы.
Категория шага — его индекс, а не подпись
Две «Корректировки» подряд в мосте — обычное дело, а нормализация схлопывает одинаковые категории внутри серии. Поэтому внутрь рамы уходит индекс шага, а настоящие подписи приезжают на ось отдельно: иначе позиций стало бы меньше, чем шагов, и курсор с клавиатурой поехали бы по чужим данным.
Границы
Мост не считает, из чего состоят его шаги, — их даёт потребитель. Мелкие шаги в «Прочее» он тоже не группирует: только вызывающий знает, что считать мелким. Вложенных (двухуровневых) мостов нет.
Установка
npm i @feugene/granularity-chartsИмпорт
import { GrChartWaterfall } from '@feugene/granularity-charts/components/GrChartWaterfall'API
API этого компонента ещё не посчитан: генератор витрины пока обходит только ядро. Пока его нет, справочник — в документации пакета.
Примеры 2
Basic
<script setup lang="ts">
/**
* Мост отвечает на вопрос, которого нет у расходящихся столбцов: как из начала
* месяца получился конец.
*
* Шаги `total` ставят реальные остатки с бэкенда, и если сумма движений с ними
* не сходится, это видно глазом — последний столбец не совпадёт с вершиной
* предпоследнего.
*/
const steps = [
{ label: 'На начало', value: 1240, kind: 'total' as const },
{ label: 'Новые', value: 318 },
{ label: 'Реактивации', value: 46 },
{ label: 'Заморозки', value: 0 },
{ label: 'Отток', value: -172 },
{ label: 'На конец', value: 1432, kind: 'total' as const },
]
</script>
<template>
<div class="grid gap-3">
<span class="text-[length:var(--gr-control-text-sm)] text-[var(--gr-muted-fg)]">
Движение подписок за октябрь
</span>
<GrChartWaterfall
:steps="steps"
:height="280"
aria-label="Движение подписок за октябрь"
/>
<p class="text-[length:var(--gr-control-text-sm)] text-[var(--gr-muted-fg)]">
Цвет идёт <strong>по знаку шага</strong>, а не по индексу серии: мост это один ряд, и различать
в нём надо прибавление и убавление. «Заморозки» с нулём рисуются чертой — «движения не было»
это факт, и пропадать он не должен.
</p>
</div>
</template>Horizontal
<script setup lang="ts">
import { ref } from 'vue'
/**
* Горизонталь берут, когда подписи шагов длиннее, чем позволяет ширина
* категории: под вертикальной осью они налезли бы друг на друга.
*
* Оси в этом режиме рисует сам компонент — ось значений рамы вертикальна по
* построению, а здесь она внизу.
*/
const steps = [
{ label: 'Обязательство на начало', value: 84_200, kind: 'total' as const },
{ label: 'Начислено по подпискам', value: 31_400 },
{ label: 'Куплено пакетами', value: 12_800 },
{ label: 'Списано', value: -28_900 },
{ label: 'Сгорело', value: -6100 },
]
const orientation = ref<'vertical' | 'horizontal'>('horizontal')
</script>
<template>
<div class="grid gap-3">
<div class="flex flex-wrap items-baseline justify-between gap-4">
<span class="text-[length:var(--gr-control-text-sm)] text-[var(--gr-muted-fg)]">
Экономика кредитов
</span>
<GrSegmented
v-model="orientation"
size="sm"
:options="[
{ value: 'horizontal', label: 'Горизонтально' },
{ value: 'vertical', label: 'Вертикально' },
]"
aria-label="Раскладка моста"
/>
</div>
<GrChartWaterfall
:steps="steps"
:orientation="orientation"
:height="300"
show-total
aria-label="Экономика кредитов за период"
/>
<p class="text-[length:var(--gr-control-text-sm)] text-[var(--gr-muted-fg)]">
<code>showTotal</code> дорисовывает итоговый столбец от нуля. Накопления он не меняет — только
показывает: соединитель к нему не ведёт, потому что он не продолжает мост, а объявляет его результат.
</p>
</div>
</template>Доступность
- Паттерн APG
При orientation: 'horizontal' шаги идут сверху вниз, и по ним ходят ↓/↑- Клавиши
- шаг