Waterfall
Waterfall chart showing sequential positive and negative changes from a starting value.
import { Waterfall } from "metricui";Use Waterfall for sequential change analysis — showing how an initial value is affected by a series of positive and negative changes. Perfect for P&L breakdowns, MRR bridges, and budget analysis. Supports subtotals, totals, connector lines, per-bar color overrides, and custom positive/negative/total colors. For categorical comparison, use BarChart instead.
Basic Example
Pass an array of items with label, value, and type. Use type: "total" for the final computed sum.
<Waterfall
data={[
{ label: "Starting MRR", value: 85000, type: "value" },
{ label: "New Sales", value: 28400, type: "value" },
{ label: "Expansion", value: 12600, type: "value" },
{ label: "Churn", value: -8200, type: "value" },
{ label: "Contraction", value: -3100, type: "value" },
{ label: "Ending MRR", value: 0, type: "total" },
]}
title="MRR Bridge"
format="currency"
connectors
height={320}
/>With Subtotals
Use type: "subtotal" to insert intermediate running-total markers. Great for P&L statements where you need gross income before expenses.
<Waterfall
data={[
{ label: "Revenue", value: 120000, type: "value" },
{ label: "Services", value: 34000, type: "value" },
{ label: "Gross Income", value: 0, type: "subtotal" },
{ label: "Salaries", value: -62000, type: "value" },
{ label: "Marketing", value: -18000, type: "value" },
{ label: "Rent", value: -9500, type: "value" },
{ label: "Operating Income", value: 0, type: "subtotal" },
{ label: "Tax", value: -13000, type: "value" },
{ label: "Net Income", value: 0, type: "total" },
]}
title="P&L Breakdown"
format="currency"
connectors
height={360}
/>Custom Colors
Override colors per-bar with the color property on individual data items, or set positiveColor, negativeColor, and totalColor globally.
<Waterfall
data={[
{ label: "Q1 Target", value: 50000 },
{ label: "Outperformance", value: 8200, color: "#6366f1" },
{ label: "Seasonality", value: -3400 },
{ label: "New Market", value: 12800, color: "#6366f1" },
{ label: "Refunds", value: -2100 },
{ label: "Q1 Actual", value: 0, type: "total" },
]}
title="Q1 Revenue Bridge"
format="currency"
positiveColor="#10b981"
negativeColor="#f43f5e"
totalColor="#8b5cf6"
height={320}
/>Without Connectors
Set connectors={false} to hide the dashed connector lines between bars for a cleaner look.
<Waterfall
data={[
{ label: "Budget", value: 200000 },
{ label: "Personnel", value: -82000 },
{ label: "Equipment", value: -34000 },
{ label: "Software", value: -21000 },
{ label: "Travel", value: -8500 },
{ label: "Remaining", value: 0, type: "total" },
]}
title="Budget Allocation"
format="currency"
connectors={false}
height={320}
/>Quarterly Changes
Show how periodic changes contribute to a final total. Each bar represents the delta for that period, and the total bar shows the cumulative result.
<Waterfall
data={[
{ label: "Q1", value: 120000 },
{ label: "Q2", value: 45000 },
{ label: "Q3", value: -30000 },
{ label: "Q4", value: 65000 },
{ label: "FY Total", type: "total" },
]}
title="Quarterly Revenue"
format="currency"
connectors
height={320}
/>Data States
Every component handles loading, empty, and error states. Pass individual props or use the grouped state prop.
Loading
Error
Failed to load data
// Loading state
<Waterfall data={[]} title="Revenue Bridge" loading />
// Error state
<Waterfall data={[]} title="Revenue Bridge" error={{ message: "Failed to load" }} />Props
| Prop | Type | Default | Description |
|---|---|---|---|
data* | WaterfallItem[] | — | Array of waterfall items with label, value, optional type and color. |
title | string | — | Chart card title. |
subtitle | string | — | Chart card subtitle. |
description | string | React.ReactNode | — | Description popover. |
footnote | string | — | Footnote. |
action | React.ReactNode | — | Action slot. |
format | FormatOption | — | Format for axis labels, bar value labels, and tooltips. |
height | number | 300 | Chart height in px. |
positiveColor | string | — | Color for positive (increase) bars. Default: theme positive color. |
negativeColor | string | — | Color for negative (decrease) bars. Default: theme negative color. |
totalColor | string | — | Color for subtotal/total bars. Default: theme accent. |
connectors | boolean | true | Show dashed connector lines between bars. |
enableLabels | boolean | true | Show value labels on bars. |
borderRadius | number | 3 | Corner radius on bars. |
padding | number | 0.35 | Padding between bars (0-1). |
enableGridY | boolean | true | Show Y-axis grid lines. |
yAxisLabel | string | — | Y-axis label. |
animate | boolean | true | Enable/disable animation. |
variant | CardVariant | — | Card variant. |
dense | boolean | — | Compact layout. |
className | string | — | Additional CSS class names. |
classNames | { root?: string; header?: string; chart?: string } | — | Sub-element class name overrides. |
id | string | — | HTML id attribute. |
data-testid | string | — | Test id. |
loading | boolean | — | Loading state. |
empty | EmptyState | — | Empty state. |
error | ErrorState | — | Error state. |
stale | StaleState | — | Stale indicator. |
drillDown | boolean | ((event: { label: string; value: number; runningTotal: number }) => React.ReactNode) | — | Enable drill-down on bar click. `true` auto-generates a summary KPI row + filtered DataTable from the chart's source data. Pass a render function for full control over the panel content. Requires DrillDown.Root wrapper. |
drillDownMode | DrillDownMode | "slide-over" | Presentation mode for the drill-down panel. "slide-over" (default) slides from the right, full height. "modal" renders centered and compact. |
Data Shape
interface WaterfallItem {
label: string; // Display label
value?: number; // Positive for increase, negative for decrease. Ignored for subtotal/total.
type?: "value" | "subtotal" | "total"; // Default: "value". subtotal/total are auto-computed.
color?: string; // Custom color override for this bar
}Notes
- Uses forwardRef.
- Uses a stacked spacer technique — transparent spacer bars create the floating effect.
- Positive values show in green, negative in red, subtotal/total bars use the accent color.
- Connector lines (dashed) link adjacent bar tops. Disabled for total bars that start from zero.
- Items with type 'subtotal' show the running total without resetting. Items with type 'total' show and reset.
- Tooltips show item value plus running total for non-total items.
- Custom colors per bar override the default positive/negative/total coloring.
- drillDown={true} auto-generates a summary KPI row + filtered DataTable from the chart's source data. Pass a render function for custom panel content. Requires DrillDown.Root wrapper.