Waterfall Chart
WaterfallChart renders a local (single-prediction) explanation: it shows how each feature moved a model's output away from the average base value E[f(x)] toward the final prediction f(x). It matches the look of shap.waterfall_plot — arrow bars, sign colors, and a feature-labeled axis.
- Takes a single
ShapExplanationobject ({ features, fx, efx, otherFactorsProb?, otherFactorsValue?, text? }) with no transform — it maps 1:1 to the model output. - Bars accumulate from
efx(E[f(x)]) to the top; the prediction marker is drawn atfx(f(x)). - Features are sorted by
|prob|(largest first) and sign-colored: blue pushes the prediction higher, red pushes it lower. Both are overridable viacolors. - The pre-aggregated
otherFactorsbucket renders as a single "N other features" row, always pinned to the bottom — matching the native SHAP layout. maxFeaturesfurther collapses the tail into one "N other features" row — the dropped count is surfaced, never silently truncated.compactswaps long axis labels for letter codes (324 = A) plus an expandable legend; it defaults on for narrow screens.- Base
E[f(x)]and predictionf(x)are marked on the x-axis with dashed reference lines.
Import
import { WaterfallChart } from "h2o-library/charts";Usage
Structured object
The recommended shape: a ShapExplanation object with nested features[] (each { name, prob, value }), fx, efx, and an optional pre-aggregated otherFactorsProb / otherFactorsValue bucket. It maps 1:1 — no client-side reshaping. The other-factors bucket renders as a pinned "N other features" row.
Deterioration risk — structured explanation
const explanation = {
fx: 0.678, // f(x)
efx: 0.367, // E(f(x))
otherFactorsProb: 0.13,
otherFactorsValue: 415,
features: [
{
name: "maximum daily general orders since admission",
prob: 0.05,
value: 85,
},
{ name: "fall risk score in last 24 hours", prob: 0.05, value: 6 },
// …up to 10, sorted by |prob| desc…
],
};
<WaterfallChart data={explanation} />;Net-negative explanation
When fx < efx, most drivers push the prediction lower — the bars run down and to the left from the base. Nothing special to configure; the same ShapExplanation shape handles it.
Deterioration risk — net negative
const explanation = {
fx: 0.006, // f(x) below the base…
efx: 0.021, // …E(f(x))
otherFactorsProb: -0.36,
otherFactorsValue: 388,
features: [
{
name: "service in last 24 hours (Vascular Surgery)",
prob: 0.26,
value: 1,
},
{
name: "number of unique order types in last 24 hours",
prob: -0.09,
value: 1,
},
// …
],
};
<WaterfallChart data={explanation} />;Collapsing the tail
maxFeatures keeps the strongest N features and aggregates the rest into one "N other features" row.
Top 4 drivers
<WaterfallChart data={explanation} maxFeatures={4} />;Compact mode
compact replaces feature names on the axis with short letter codes and lists A = feature name in an expandable legend below the chart — useful on narrow layouts. It defaults to true on screens ≤ 640px and false above; pass an explicit value to force it.
Compact — letter codes + legend
Feature legend
- A
- maximum daily general orders since admission
- B
- fall risk score in last 24 hours
- C
- age at admission
- D
- change in AHFS28 medication count in last 24 hours
- E
- maximum daily order type count since admission
- F
- days since last surgery date
- G
- IPA difficulty ambulating assessment in last 24 hours
- H
- IPA independent activities in last 24 hours
- I
- cumulative consultation orders since admission
- J
- 415 other features
<WaterfallChart data={explanation} compact />;Custom colors
Override the sign colors with any CSS color. Each key is independently optional.
Custom sign colors
<WaterfallChart
data={explanation}
colors={{
positive: "hsl(var(--success))",
negative: "hsl(var(--muted-200))",
}}
/>;Click events
Pass onBarClick to make each feature bar interactive. The handler receives the feature datum ({ feature, code, value, contribution }), its row index, and the native mouse event — bars only become pointer-interactive when a handler is provided.
Click a feature bar
No feature selected yet.
<WaterfallChart
data={explanation}
onBarClick={(datum, index, e) => {
e.stopPropagation();
console.log(datum.feature, datum.contribution);
}}
/>;
WaterfallChartis also reachable through the high-levelChartwrapper withtype="waterfall"— see that page for the wrapped version with title, info tooltip, and legend.
Data shape
The chart maps the model output 1:1 with no transform layer — serialize the ShapExplanation to JSON and pass it straight to data:
{
"fx": 0.678,
"efx": 0.367,
"otherFactorsProb": 0.13,
"otherFactorsValue": 415,
"text": "…optional explanation…",
"features": [
{ "name": "fall risk score in last 24 hours", "prob": 0.05, "value": 6 }
]
}prob/valuemust be numbers, not strings.featuresshould be sorted by|prob|descending (the chart re-sorts anyway) and capped to the top ~10; put the rest in theotherFactors*bucket.- Contributions (
Σ prob+otherFactorsProb) should sum tofx − efx. textis ignored by the chart — render it beside the chart yourself.
Playground
Props
WaterfallChart
| Prop | Type | Default | Description |
|---|---|---|---|
data* | ShapExplanation | — | The SHAP explanation object: { features, fx, efx, otherFactorsProb?, otherFactorsValue?, text? }. |
maxFeatures | number | undefined | Keep the top-N features by |prob| and aggregate the rest into one "N other features" row. |
compact | boolean | true on ≤640px, else false | Replace axis feature names with letter codes and show an expandable legend below the chart. |
colors | { positive?: string; negative?: string } | { positive: primary, negative: destructive } | Override the sign colors. positive = pushes prediction higher, negative = pushes it lower. |
height | number | 400 | Height of the chart in pixels. |
className | string | undefined | Additional CSS class for the container div. |
onBarClick | (datum: WaterfallBarDatum, index, event) => void | undefined | Fired when a feature bar is clicked. Receives { feature, code, value, contribution }, the row index, and the native mouse event. Bars become pointer-interactive only when provided. |
* Required
ShapExplanation
| Prop | Type | Default | Description |
|---|---|---|---|
features* | ShapFeature[] | — | Top influencing features ({ name, prob, value }), sorted by |prob| desc (max 10). |
fx* | number | — | f(x) — the model output probability. Marks the prediction reference line. |
efx* | number | — | E(f(x)) — the baseline (expected) probability the bars start from. |
otherFactorsProb | number | undefined | Summed contribution of all features not individually listed. Renders as a pinned bottom row. |
otherFactorsValue | number | undefined | Count of features grouped into otherFactors — used to label the "N other features" row. |
text | string | undefined | Human-readable model explanation. Ignored by the chart — render it alongside. |
recordId / losRecordId / probabilityDischargeNext2Days | number | undefined | Passthrough identifiers/metadata; not used for rendering. |
* Required
ShapFeature
| Prop | Type | Default | Description |
|---|---|---|---|
name* | string | — | Feature name shown on the axis label and tooltip. |
prob* | number | — | Signed SHAP contribution. Positive pushes the prediction higher, negative lower. |
value | number | string | undefined | The feature's raw clinical value, shown in the row label and tooltip. |
* Required
Design Guidelines
- Use a waterfall to explain one prediction (local explanation) — not global feature importance across a dataset.
- Keep the visible feature count readable; use
maxFeatures(or the model's own "other factors" row) to collapse the tail. - Render the model's
Textsummary next to the chart, not inside it. - Prefer the
Chartwrapper when you want the title, info tooltip, and legend for free.
Accessibility
- Tooltips appear on hover and are not keyboard-accessible; for critical data provide a companion table.
- Compact mode's legend is a native
<details>element — fully keyboard-operable. - Sign is encoded by both color and arrow direction, so the chart does not rely on color alone.