# Waterfall Chart

> How a figure gets from one value to another, one change at a time.

Source: https://ngwr.dev/charts/waterfall-chart  
Added in v15.1

## Installation

Import the class, and `@use` the entry point in your global styles: without it the component renders unstyled.

```typescript
import { Component } from '@angular/core';
import { WrWaterfallChart } from 'ngwr/charts/waterfall-chart';

@Component({ imports: [WrWaterfallChart] })
export class MyComponent {}
```

```scss
@use 'ngwr/charts/waterfall-chart';
```

## Basic

A change floats from the running total. A total is a bar from zero. Up, down and total each have their own colour, sign and direction.

```angular-html
<wr-waterfall-chart
  ariaLabel="Profit bridge"
  [steps]="[
    { label: 'Opening', value: 4200, total: true },
    { label: 'Sales', value: 1800 },
    { label: 'Refunds', value: -350 },
    { label: 'Payroll', value: -900 },
    { label: 'Closing', value: 4750, total: true }
  ]"
/>
```

## Totals

A total shows the running total, and its `value` is checked rather than drawn: in dev mode, a value the steps above do not add up to warns. A total before every change opens the chart at its value.

```angular-html
<wr-waterfall-chart [steps]="months" />
```

```angular-ts
months: WrWaterfallStep[] = [
  { label: 'Start', value: 1200, total: true }, // opens the chart
  { label: 'Jan', value: 300 },
  { label: 'Feb', value: -150 },
  { label: 'Mar', value: 420 },
  { label: 'Q1', value: 1770, total: true }, // checked: 1200 + 300 − 150 + 420
  { label: 'Apr', value: -80 },
  { label: 'May', value: 260 },
  { label: 'Jun', value: 190 },
  { label: 'H1', value: 2140, total: true },
];
```

## Below zero

The value axis always includes zero. A running total below it hangs under the zero line.

```angular-html
<wr-waterfall-chart [steps]="cash" />
```

## Colours

`increaseColor`, `decreaseColor` and `totalColor` take any CSS colour. Success, danger and primary by default.

```angular-html
<wr-waterfall-chart totalColor="var(--wr-color-on-surface-muted)" [steps]="bridge" />
```

## Number format

Numbers follow `LOCALE_ID`. `valueFormat` replaces it, and is told where each figure goes: `'label'` past a bar, `'tick'` on the axis, `'value'` in the tooltip, the names and the data table. So the drawing can go compact and the rest stay exact. Every figure arrives as its magnitude, and the chart writes the sign. A figure too wide for its column is left out, never cut.

```angular-html
<wr-waterfall-chart [steps]="bridge" [valueFormat]="format" />
```

```angular-ts
const usd = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0 });
const compactUsd = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', notation: 'compact' });

// Compact past the bars ('label'), whole on the axis and in the tooltip, names and table.
// Every figure arrives as its magnitude; the chart writes + or − in front.
format = (value: number, where: WrWaterfallValueContext): string =>
  (where === 'label' ? compactUsd : usd).format(value);
```

## Quieter

`showValues`, `showGrid` and `showConnectors` each turn one layer off. Keep the figures or the connectors: with both off, only colour tells up from down. The names, the tooltip and the data table keep every figure.

```angular-html
<wr-waterfall-chart [steps]="bridge" [showValues]="false" [showGrid]="false" />
```

## Data table

`dataTable` renders every figure as a table only screen readers reach: a row per step, with its change and the running total. Nothing changes on screen.

```angular-html
<wr-waterfall-chart ariaLabel="Profit bridge" dataTable [steps]="bridge" />
```

## Accessibility

| Part | Behaviour |
| --- | --- |
| Chart | A `role="group"`, named by `ariaLabel`. No tab stop. |
| Steps | One `role="img"` each, named with the change and the running total. |
| Up, down, total | Told apart by direction, by a `+` or `−` sign and by a heavier total label, not only colour. Turning off both `showValues` and `showConnectors` leaves only colour. |
| Zero change | A neutral hairline, printed `0`. Not an increase. |
| Tooltip | Pointer only. `Escape` closes it. |
| Forced colours | Bars keep their colours. Lines take system colours. |

## API

| Name | Description | Type | Default |
| --- | --- | --- | --- |
| `steps` | The steps, in order. A step without `total` is a change to the running total; a step with it is a bar from zero showing the running total. See {@link WrWaterfallStep} for what a total's `value` does. | `readonly WrWaterfallStep[]` | `[]` |
| `ariaLabel` | Accessible name of the chart, and the data table's caption. Each step names itself, so say what the chart shows. Falls back to `waterfallChart.label` ("Waterfall chart"). | `string \| null` | `null` |
| `increaseColor` | The colour of a change up. Any CSS colour, `var(--wr-…)` included. | `string` | `'var(--wr-color-success)'` |
| `decreaseColor` | The colour of a change down. Any CSS colour. | `string` | `'var(--wr-color-danger)'` |
| `totalColor` | The colour of a total. Any CSS colour. | `string` | `'var(--wr-color-primary)'` |
| `height` | The plot's height in px, at least 80. | `number` | `240` |
| `showGrid` | Show the gridlines and the value axis' tick labels. | `boolean` | `true` |
| `showValues` | Print each step's figure past the end of its bar: a change with its sign, over the bar when it runs up and under it when it runs down, and a total with no `+`. Compact from a thousand up (`+1.2K`) by default; with `valueFormat`, whatever it writes for `'label'`, so a formatter can go compact here and stay exact everywhere else. A figure is printed whole or not at all: one wider than its column and a quarter of the gap on either side — which keeps it clear of its neighbours' — is left out rather than cut, since `+$1,…` is not a figure and `−$9…` reads as −$9. The tooltip, the names and the data table carry every figure in full. The sign is one of the two cues besides colour that tell a change up from a change down; the connectors are the other. Off together with `showConnectors`, colour is the only one left on screen. | `boolean` | `true` |
| `showConnectors` | Draw the thin line that carries each running total across the gap to the next bar, which starts from it. None leads into a total that starts a running total of its own — one before every change, at a value the line would not meet. A change up leaves the line at its bottom and a change down at its top, so the line is one of the two cues besides colour that tell them apart; the signed figures are the other. Off together with `showValues`, colour is the only one left on screen. | `boolean` | `true` |
| `tooltip` | Show a tooltip with the step's change and the running total after it on hover. Pointer only — each step's accessible name already carries both. | `boolean` | `true` |
| `dataTable` | Render the chart's figures as a table only assistive technology reaches, beside the drawing: a row per step, headed by its label, with its change (empty on a total) and the running total after it, each written as the tooltip writes it. Each step's accessible name already carries both figures; the table is for a reader who wants to move through them cell by cell, with the column headings read out. It is clipped to nothing: it takes no room, draws nothing and holds no tab stop. | `boolean` | `false` |
| `valueFormat` | Writes every number the chart shows: the figures on the drawing, the axis ticks, the tooltip, the accessible names and the data table. Every figure is handed over as its MAGNITUDE, never below zero, and the chart writes the sign in front: `+` or `−` (U+2212 MINUS SIGN) on a change, `−` on a running total, a total or a tick below zero. So one formatter writes every figure, and one minus sign appears throughout. It is told where the figure goes (see {@link WrWaterfallValueContext}): `'label'` past a bar, where a compact form fits a narrow column; `'tick'` on the value axis; `'value'` in the tooltip, the names and the data table, which a reader goes to for the exact figure. A `(value) => string` written for another chart fits too, and writes all three alike. `null` uses `Intl.NumberFormat` in `LOCALE_ID`: compact past the bars from a thousand up, compact ticks (`1.2K`, `3.4M`) unless the full numbers are shorter, and the exact figure everywhere else. | `((value: number, context: WrWaterfallValueContext) => string) \| null` | `null` |

## Types

```angular-ts
interface WrWaterfallStep {
  label: string;
  value: number;
  total?: boolean;
}

type WrWaterfallValueContext = 'label' | 'tick' | 'value';
```

| Name | Description | Type | Default |
| --- | --- | --- | --- |
| `WrWaterfallStep` | One step: a change, or a total. | `interface` | — |
| `label`required | The step name: under the bar, tooltip, data table. | `string` | — |
| `value`required | The change. Zero, or not a number, is a neutral hairline. On a total, the expected total: checked, not drawn. A total before every change opens the chart at it. | `number` | — |
| `total` | Draw a bar from zero to the running total. | `boolean` | `false` |
| `WrWaterfallValueContext` | Where `valueFormat` is writing: `'label'` past a bar, `'tick'` on the axis, `'value'` in the tooltip, the names and the data table. | `'label' \| 'tick' \| 'value'` | — |

## CSS variables

Set these on the component's selector or a wrapper, not on `:root`: the defaults are declared on `ngwr/charts/waterfall-chart`'s own element.

| Variable | Default | Declared on |
| --- | --- | --- |
| `--wr-waterfall-chart-active-bg` | `color-mix(in srgb, var(--wr-color-on-surface) 6%, transparent)` | `.wr-waterfall-chart` |
| `--wr-waterfall-chart-bar-radius` | `calc(var(--wr-border-radius-sm) / 3)` | `.wr-waterfall-chart` |
| `--wr-waterfall-chart-baseline-color` | `var(--wr-border-base)` | `.wr-waterfall-chart` +1 variant override |
| `--wr-waterfall-chart-color` | `var(--wr-color-on-surface)` | `.wr-waterfall-chart` |
| `--wr-waterfall-chart-connector-color` | `var(--wr-color-on-surface-muted)` | `.wr-waterfall-chart` +1 variant override |
| `--wr-waterfall-chart-connector-width` | `1px` | `.wr-waterfall-chart` |
| `--wr-waterfall-chart-flat-color` | `var(--wr-color-on-surface-muted)` | `.wr-waterfall-chart` +1 variant override |
| `--wr-waterfall-chart-font-family` | `var(--wr-font-family-base)` | `.wr-waterfall-chart` |
| `--wr-waterfall-chart-gap` | `var(--wr-space-sm)` | `.wr-waterfall-chart` |
| `--wr-waterfall-chart-grid-color` | `color-mix(in srgb, var(--wr-border-base) 70%, transparent)` | `.wr-waterfall-chart` +1 variant override |
| `--wr-waterfall-chart-label-color` | `var(--wr-color-on-surface-muted)` | `.wr-waterfall-chart` |
| `--wr-waterfall-chart-label-font-size` | `var(--wr-text-xs)` | `.wr-waterfall-chart` |
| `--wr-waterfall-chart-labels-margin-top` | `var(--wr-space-sm)` | `.wr-waterfall-chart` |
| `--wr-waterfall-chart-plot-inset-y` | `var(--wr-space-sm)` | `.wr-waterfall-chart` |
| `--wr-waterfall-chart-tick-color` | `var(--wr-color-on-surface-muted)` | `.wr-waterfall-chart` |
| `--wr-waterfall-chart-tick-font-size` | `var(--wr-text-xs)` | `.wr-waterfall-chart` |
| `--wr-waterfall-chart-tick-gap` | `var(--wr-space-xs)` | `.wr-waterfall-chart` |
| `--wr-waterfall-chart-tick-line-height` | `var(--wr-text-xs-leading)` | `.wr-waterfall-chart` |
| `--wr-waterfall-chart-total-font-weight` | `var(--wr-font-weight-medium)` | `.wr-waterfall-chart` |
| `--wr-waterfall-chart-value-color` | `var(--wr-color-on-surface)` | `.wr-waterfall-chart` |
| `--wr-waterfall-chart-value-font-size` | `var(--wr-text-xs)` | `.wr-waterfall-chart` |
| `--wr-waterfall-chart-value-gap` | `var(--wr-space-xs)` | `.wr-waterfall-chart` |
| `--wr-waterfall-chart-value-line-height` | `var(--wr-text-xs-leading)` | `.wr-waterfall-chart` |

## Dependencies

| Built on | [Popover](https://ngwr.dev/reference/components/popover) |
| --- | --- |

## See also

- [Bar Chart](https://ngwr.dev/charts/bar-chart) — Bars for one or several series, grouped or stacked, standing up or lying along a row, with lines over them.
- [Funnel Chart](https://ngwr.dev/charts/funnel-chart) — How many reached each stage of a sequence, and how many of them went on to the next.
- [Line Chart](https://ngwr.dev/charts/line-chart) — One or more series of values as lines or as an area chart, overlaid or stacked.
- [Popover](https://ngwr.dev/reference/components/popover) — Show a template, or a text tooltip, next to its trigger.
