GrChartWaterfall
Machine-translated from the Russian original, not yet reviewed. Read the original
When to take it
- movement from balance to balance — subscriptions, liabilities, a warehouse: not only every change is visible but also how the end of the month came out of its beginning;
- checking whether the balance adds up —
kind: 'total'steps put the real values at the start and at the end, and a discrepancy with the sum of the movements becomes visible to the eye rather than in one’s head; - breaking down the delta between two numbers — “revenue grew by 12 %” and the four reasons for that growth read as one story;
- increases and decreases mixed together — the colour follows the sign, and the direction of every step is visible before the labels are read;
- there are few steps — up to fifteen or twenty; beyond that the labels of the axis run into one another, and the bridge is worth folding down to large items.
When to take something else
| Need | Take |
|---|---|
| Compare quantities across categories, with no succession | GrChartBar |
| Show the composition of one whole at one moment | GrChartPie |
| Show the course of a quantity over time | GrChartLine |
| Show where users are lost between stages | GrChartFunnel |
| Show one number with a trend | GrStatistic |
A `total` step declares the accumulation rather than adding to it
kind: 'delta' (the default) is a change from the current accumulation, and kind: 'total' an
absolute value: the column is drawn from zero, and the accumulation is reset to it. That is what
makes it possible to put “At the start” and “At the end” as real numbers from the backend: if the
bridge does not add up, the last column will not match the top of the one before it, and the error in
the data will be visible.
A connector to such a step is not drawn. It does not continue the accumulation but declares it, and a “from here to here” line would lie about the succession.
The colour follows the sign rather than the index of the series
A bridge is a single series, and the palette of series distinguishes nothing here: what has to be
distinguished is an increase (--gr-success) from a decrease (--gr-danger). The total and the
declared accumulation are coloured neutrally (--gr-chart-1) — that is not a movement. An explicit
color on a step is stronger than any of those rules.
A zero step is drawn as a rule
“There was no movement” is a fact rather than an absence of data. A column of zero height would
disappear from the drawing, and the reader would see a story in which such a step does not exist at
all. Instead a rule of --gr-chart-waterfall-zero-step thickness stands at the level of the
accumulation.
The table carries the accumulation rather than a single delta
The hidden table gives three numbers per step: the change, the accumulation before and the accumulation after. From a single delta the bridge cannot be reconstructed — the height of a column is set precisely by the accumulation, and a reader without sight is obliged to see the same as a sighted one sees from the position of the band.
The category of a step is its index rather than its label
Two “Adjustments” in a row in a bridge are an ordinary matter, and normalisation collapses identical categories inside a series. The index of the step therefore goes inside the frame, and the real labels arrive on the axis separately: otherwise there would be fewer positions than steps, and the cursor and the keyboard would travel over the wrong data.
Limits
The bridge does not compute what its steps consist of — they are given by the consumer. It does not group small steps into “Other” either: only the caller knows what counts as small. There are no nested (two-level) bridges.
Install
npm i @feugene/granularity-chartsImport
import { GrChartWaterfall } from '@feugene/granularity-charts/components/GrChartWaterfall'API
The API for this component has not been generated yet: the showcase generator only covers the core so far. Until it does, the reference lives in the package documentation.
Examples 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>Accessibility
- APG pattern
При orientation: 'horizontal' шаги идут сверху вниз, и по ним ходят ↓/↑