# Waterfall charts in your AI client

> The words that change a waterfall chart in Bonnard, and the options and limits the product enforces.

Updated: 2026-10-12

Bonnard draws a waterfall chart to walk a total from one level to another through signed changes.

[Image: A chat with the question "Revenue from August to September by type of customer, as a waterfall chart.", three tool calls, and the waterfall Bonnard drew: August's £2.8M, a £1.8M drop from lapsed customers, a £1.8M rise from new ones, then September's £2.9M]

The examples use Acme, a demo retailer that reports in pounds. Each variant is a few words in the question. A follow-up changes a chart already drawn.

## How an agent draws it

The chat above ran three tools, in this order:

1. `explore_schema` finds the tables and their columns: here `customer_months`, with `customer_id`, `month` and `revenue`.
2. `sql_query` runs a read-only query, so the agent can check the numbers first.
3. `render_chart` takes the SQL and the chart options. It runs the query and returns the chart the chat draws.

The `render_chart` call behind the chart above:

```json
{
  "charts": [
    {
      "sql": "WITH c AS (SELECT customer_id, SUM(CASE WHEN month = DATE '2026-08-01' THEN revenue END) AS aug, SUM(CASE WHEN month = DATE '2026-09-01' THEN revenue END) AS sep FROM customer_months WHERE month >= DATE '2026-08-01' GROUP BY customer_id) SELECT step, amount, kind FROM (SELECT 1 AS n, 'Aug' AS step, SUM(aug) AS amount, 'opening' AS kind FROM c UNION ALL SELECT 2, 'Lapsed', -SUM(aug), 'change' FROM c WHERE sep IS NULL UNION ALL SELECT 3, 'Repeat', SUM(sep - aug), 'change' FROM c UNION ALL SELECT 4, 'New', SUM(sep), 'change' FROM c WHERE aug IS NULL UNION ALL SELECT 5, 'Sep', SUM(sep), 'closing' FROM c) AS w ORDER BY n",
      "chartType": "waterfall",
      "title": "Revenue, August to September 2026, by customer",
      "encode": { "x": "step", "y": "amount" },
      "fields": [
        { "name": "step", "label": "Customers" },
        { "name": "amount", "label": "Revenue", "format": "currency", "currency": "GBP" }
      ]
    }
  ]
}
```

The query returns one row per bar, in order: each change signed, and a `kind` column that marks the opening and closing totals.

A call takes up to 10 charts, shown as a carousel. Each example below shows its one entry. A connected agent reads the full option reference with `explore_docs`, topic `charts/waterfall`.

## Subtotals

```prompt
September from gross sales to gross profit, with net revenue as a subtotal.
```

[Image: September's gross sales less returns, net revenue as a grey subtotal, then cost of goods down to gross profit]

```json
{
  "sql": "SELECT line AS step, amount, CASE line WHEN 'Gross sales' THEN 'total' WHEN 'Net revenue' THEN 'subtotal' WHEN 'Gross profit' THEN 'total' ELSE 'change' END AS kind FROM monthly_pnl WHERE month = DATE '2026-09-01' ORDER BY line_no",
  "chartType": "waterfall",
  "title": "September 2026, gross sales to gross profit",
  "encode": { "x": "step", "y": "amount" },
  "fields": [
    { "name": "step", "label": "P&L line" },
    { "name": "amount", "label": "Amount", "format": "currency", "currency": "GBP" }
  ]
}
```

A subtotal row holds the level at that point, drawn from zero. The changes after it start again from that level.

## A variance walk

```prompt
Q3 revenue by region against the £150K weekly target, as a variance walk.
```

[Image: Q3 revenue walking from a £9.8M target down to £8.3M actual, the UK the one region above target]

```json
{
  "sql": "WITH q AS (SELECT region, revenue FROM weekly_region_revenue WHERE week_start >= DATE '2026-06-29') SELECT step, amount, kind FROM (SELECT 0 AS n, 'Target' AS step, COUNT(*) * 150000 AS amount, 'opening' AS kind FROM q UNION ALL SELECT 1, region, SUM(revenue - 150000), 'change' FROM q GROUP BY region UNION ALL SELECT 2, 'Actual', SUM(revenue), 'closing' FROM q) AS w ORDER BY n, amount DESC",
  "chartType": "waterfall",
  "title": "Q3 2026 revenue against target, by region",
  "encode": { "x": "step", "y": "amount" },
  "fields": [
    { "name": "step", "label": "Region" },
    { "name": "amount", "label": "Revenue", "format": "currency", "currency": "GBP" }
  ]
}
```

The target opens the walk, and each region adds its gap above or below it. Steps keep the query's row order, so the SQL sorts the regions.

## A running total

```prompt
Revenue so far this year, month by month, as a running total.
```

[Image: Each month of 2026 a green step up from the one before, to a grey total of £23.3M]

```json
{
  "sql": "SELECT step, amount, kind FROM (SELECT month_start AS n, month_label AS step, revenue AS amount, 'change' AS kind FROM monthly_revenue WHERE month_start >= DATE '2026-01-01' UNION ALL SELECT DATE '2026-12-31', 'Total', SUM(revenue), 'total' FROM monthly_revenue WHERE month_start >= DATE '2026-01-01') AS w ORDER BY n",
  "chartType": "waterfall",
  "title": "Revenue by month, 2026 to date",
  "encode": { "x": "step", "y": "amount" },
  "fields": [
    { "name": "step", "label": "Month" },
    { "name": "amount", "label": "Revenue", "format": "currency", "currency": "GBP" }
  ]
}
```

The query marks only the last row as a total, so the walk starts from zero with January.

## Options and limits

Table: What a waterfall chart takes

| Ask for | What Bonnard draws |
| --- | --- |
| "a waterfall" or "a bridge" | Steps in row order: gains green, losses red, totals grey |
| "from opening to closing" | Total bars at each end, with the changes between |
| "with a subtotal" | A total bar inside the walk, which the next change starts from |
| "in pounds" or "as a percentage" | Currency, percent or compact values on the axis and bars |
| "start the axis at £1M" | A fixed value axis, with a note under the chart when it starts above zero |
| "call the axis Revenue" | Axis titles in place of the column labels |

- A total is a row whose marker column reads total, subtotal, opening, closing, start, end, net or balance.
- With no marker column, the first and last rows become the totals, and Bonnard tells the agent it guessed.
- A waterfall draws one measure: a list of measures draws only the first.
- It needs at least two rows: a starting total and one change.
- Bars carry their values up to 12 steps. At phone width, when one value does not fit its bar, only the totals keep theirs.
- The colours are fixed. A waterfall takes no series colours, highlight, legend, target lines or trend lines.
- Labels and axis titles run to 60 characters.
- No chart draws a log scale, custom hex colours or zoom.
