WaterfallChart
Explains signed changes and explicit total checkpoints.
← All chart guides · Framework setup · Native counterparts
See it and copy it
Framework example
Explore the live chart, then open its code for Astro, React, or Elements.
What moved the balance
USD, thousands · September 2026
1 series, 7 points. Values range from -55 to 148.
USD, thousands
View chart data
| Category | Start | End | USD, thousands |
|---|---|---|---|
| Opening | 0 | 120 | 120 |
| New sales | 120 | 205 | 85 |
| Expansion | 205 | 237 | 32 |
| Refunds | 237 | 217 | -20 |
| Operating | 217 | 162 | -55 |
| Fees | 162 | 148 | -14 |
| Closing | 0 | 148 | 148 |
View WaterfallChart code
Framework usage
Switch targets to compare the adapter code. This live preview runs the Astro example. React and Elements use their own behavior APIs; complete the matching framework setup before copying an example.---
import { WaterfallChart } from '@santi020k/lumen-astro'
const data = [
{ id: 'opening', label: 'Opening', kind: 'total' as const, value: 120 },
{ id: 'new-sales', label: 'New sales', value: 85 },
{ id: 'expansion', label: 'Expansion', value: 32 },
{ id: 'refunds', label: 'Refunds', value: -20 },
{ id: 'operating', label: 'Operating', value: -55 },
{ id: 'fees', label: 'Fees', value: -14 },
{ id: 'closing', label: 'Closing', kind: 'total' as const, value: 148 }
]
---
<WaterfallChart
aria-label="September opening balance, revenue, costs, and closing balance in thousands of US dollars"
heading="What moved the balance"
description="USD, thousands · September 2026"
caption="Revenue added $117k; refunds and costs used $89k. The closing balance increased by $28k. Illustrative data with explicit opening and closing totals."
valueLabel="USD, thousands"
{data}
/>import { WaterfallChart } from '@santi020k/lumen-react'
const data = [
{ id: 'opening', label: 'Opening', kind: 'total' as const, value: 120 },
{ id: 'new-sales', label: 'New sales', value: 85 },
{ id: 'expansion', label: 'Expansion', value: 32 },
{ id: 'refunds', label: 'Refunds', value: -20 },
{ id: 'operating', label: 'Operating', value: -55 },
{ id: 'fees', label: 'Fees', value: -14 },
{ id: 'closing', label: 'Closing', kind: 'total' as const, value: 148 }
]
export const Example = () => (
<>
<WaterfallChart
aria-label="September opening balance, revenue, costs, and closing balance in thousands of US dollars"
heading="What moved the balance"
description="USD, thousands · September 2026"
caption="Revenue added $117k; refunds and costs used $89k. The closing balance increased by $28k. Illustrative data with explicit opening and closing totals."
valueLabel="USD, thousands"
data={data}
/>
</>
)<script type="module">
import { defineLumenElements } from '@santi020k/lumen-elements/define'
defineLumenElements(['WaterfallChart'])
</script>
<lumen-waterfall-chart id="example-waterfall-chart"
aria-label="September opening balance, revenue, costs, and closing balance in thousands of US dollars"
heading="What moved the balance"
description="USD, thousands · September 2026"
caption="Revenue added $117k; refunds and costs used $89k. The closing balance increased by $28k. Illustrative data with explicit opening and closing totals."
value-label="USD, thousands"></lumen-waterfall-chart>
<script type="module">
"use strict";
const data = [
{ id: 'opening', label: 'Opening', kind: 'total', value: 120 },
{ id: 'new-sales', label: 'New sales', value: 85 },
{ id: 'expansion', label: 'Expansion', value: 32 },
{ id: 'refunds', label: 'Refunds', value: -20 },
{ id: 'operating', label: 'Operating', value: -55 },
{ id: 'fees', label: 'Fees', value: -14 },
{ id: 'closing', label: 'Closing', kind: 'total', value: 148 }
];
const chart = document.getElementById('example-waterfall-chart')
chart?.setAttribute('data', JSON.stringify(data))
</script>When to use WaterfallChart
Use to explain how an opening balance becomes a closing balance through ordered contributions.
- Floating bars show changes from one balance to the next. Total bars start at zero and establish a checkpoint.
- Use valueLabel and formatValue for the common unit. The exact-data table includes each supplied change and its resulting start/end balance.
Prepare the data
import type { LumenWaterfallDatum } from '@santi020k/lumen-core'
const data = [
{ id: 'opening', label: 'Opening', kind: 'total', value: 120 },
{ id: 'sales', label: 'Sales', value: 85 },
{ id: 'expenses', label: 'Expenses', value: -75 },
{ id: 'closing', label: 'Closing', kind: 'total', value: 130 }
] satisfies readonly LumenWaterfallDatum[]- Provide unique ids, labels, and finite signed values in the intended sequence. Omitted kind means delta.
- A delta adds to the running balance. kind="total" resets that balance to the explicit supplied value; it does not calculate a subtotal for you.
- Invalid steps, duplicate ids, or an overflowing running balance invalidate the chart so later balances are not silently misstated.
Avoid misleading comparisons
- Do not pass the final cumulative balance as another delta; mark it as a total.
- A total may reset to a value that differs from preceding arithmetic. Reconcile totals in your application and explain intentional adjustments.
Choose your target
Add this component
Choose the package for your runtime. All adapters share the Lumen stylesheet. Use the matching registry command when you want a local wrapper for that framework.
pnpm add @santi020k/lumen-astropnpm add @santi020k/lumen-astrolumen add WaterfallChartlumen add WaterfallChartpnpm add @santi020k/lumen-reactpnpm add @santi020k/lumen-reactlumen add WaterfallChart --target reactlumen add WaterfallChart --target reactpnpm add @santi020k/lumen-elementspnpm add @santi020k/lumen-elementslumen add WaterfallChart --target elementslumen add WaterfallChart --target elementsAPI reference
Lumen-specific props and runtime attributes for the Astro primitive. Use the framework differences above and the copyable examples for React composition and Elements attributes; the public adapter types define their supported contracts.
| Attribute | Values | Default | Description |
|---|---|---|---|
| data | LumenWaterfallDatum[] | required | Supplies stable IDs, labels, signed changes, and optional explicit total checkpoints. |
| formatValue | formatter function | String | Formats chart values and start/end balances consistently. |
| valueLabel, labels | string, Partial<LumenChartLabels> | localized defaults | Labels the measure and the accessible data table. |
| showTable | boolean | true | Shows each supplied change and the resulting start/end balance. |
| class, className | string | "" | Merges custom classes with the generated ui-* root classes. |
| ...native attributes | HTML attributes | - | Forwards standard attributes to the root element unless the component consumes them. |