Bonnard

Bonnard draws an area chart for a trend over time, and stacks the areas to show a total and its parts.

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 orders, with order_date 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:

render_chartjson

JSON

{
  "charts": [
    {
      "sql": "SELECT date_trunc('month', order_date) AS month, SUM(revenue) / 1000 AS revenue FROM orders WHERE order_date >= DATE '2026-01-01' GROUP BY 1 ORDER BY 1",
      "chartType": "area",
      "title": "Revenue by month, 2026 (£k)",
      "encode": { "x": "month", "y": "revenue" },
      "fields": [
        { "name": "month", "label": "Month" },
        { "name": "revenue", "label": "Revenue (£k)", "format": "number" }
      ]
    }
  ]
}

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/area.

Stacked areas

Prompt

Revenue by channel for the last 12 months, as a stacked area.

render_chartjson

JSON

{
  "sql": "SELECT date_trunc('month', order_date) AS month, channel, SUM(revenue) / 1000 AS revenue FROM orders WHERE order_date >= DATE '2025-10-01' GROUP BY 1, 2 ORDER BY 1",
  "chartType": "area",
  "stacking": "stacked",
  "title": "Revenue by channel, by month (£k)",
  "encode": { "x": "month", "y": "revenue", "series": "channel" },
  "fields": [
    { "name": "month", "label": "Month" },
    { "name": "revenue", "label": "Revenue (£k)", "format": "number" }
  ]
}

The top edge is each month’s total, and each layer is one channel’s part of it.

A share of the total

Prompt

Revenue by channel for the last 12 months, as a share of the total.

render_chartjson

JSON

{
  "sql": "SELECT date_trunc('month', order_date) AS month, channel, SUM(revenue) / 1000 AS revenue FROM orders WHERE order_date >= DATE '2025-10-01' GROUP BY 1, 2 ORDER BY 1",
  "chartType": "area",
  "stacking": "stacked100",
  "title": "Revenue share by channel, by month",
  "encode": { "x": "month", "y": "revenue", "series": "channel" },
  "fields": [
    { "name": "month", "label": "Month" },
    { "name": "revenue", "label": "Revenue (£k)", "format": "number" }
  ],
  "axes": { "y": { "title": "Share of revenue" } }
}

Each month stacks to 100%, so each layer is that channel’s share. The call names the value axis, since a share is not in £k.

Overlapping areas

Prompt

Weekly revenue for the UK and Germany since July, as overlapping areas.

render_chartjson

JSON

{
  "sql": "SELECT week_label AS week, region, revenue / 1000 AS revenue FROM weekly_region_revenue WHERE region IN ('UK', 'Germany') AND week_start >= DATE '2026-06-29' ORDER BY week_start",
  "chartType": "area",
  "xAxisType": "categorical",
  "title": "Weekly revenue, UK and Germany (£k)",
  "encode": { "x": "week", "y": "revenue", "series": "region" },
  "fields": [
    { "name": "week", "label": "Week" },
    { "name": "revenue", "label": "Revenue (£k)", "format": "number" }
  ]
}

Without “stacked”, each region fills down to zero and the two overlap. Bonnard draws a split this way unless the question says otherwise. Keep overlapping areas to a few series.

A running total

Prompt

Cumulative revenue this year, by month.

render_chartjson

JSON

{
  "sql": "SELECT month, SUM(revenue) OVER (ORDER BY month) / 1000000 AS revenue FROM (SELECT date_trunc('month', order_date) AS month, SUM(revenue) AS revenue FROM orders WHERE order_date >= DATE '2026-01-01' GROUP BY 1) AS m ORDER BY month",
  "chartType": "area",
  "title": "Revenue to date, 2026 (£m)",
  "encode": { "x": "month", "y": "revenue" },
  "fields": [
    { "name": "month", "label": "Month" },
    { "name": "revenue", "label": "Revenue to date (£m)", "format": "number" }
  ]
}

The running total comes from the SQL, a window sum over the months. The area fills under it, so its top edge is revenue to date.

A target line

Prompt

UK weekly revenue since July as an area, with a line at the £150K target.

render_chartjson

JSON

{
  "sql": "SELECT week_label AS week, revenue / 1000 AS revenue FROM weekly_region_revenue WHERE region = 'UK' AND week_start >= DATE '2026-06-29' ORDER BY week_start",
  "chartType": "area",
  "xAxisType": "categorical",
  "title": "UK weekly revenue against target (£k)",
  "encode": { "x": "week", "y": "revenue" },
  "fields": [
    { "name": "week", "label": "Week" },
    { "name": "revenue", "label": "Revenue (£k)", "format": "number" }
  ],
  "reference": [
    { "y": 150, "label": "Target £150K" }
  ]
}

Targets, budgets, shaded bands and average or median lines work the same way, up to six on one chart. On a stacked area, an average or median is of the total.

Options and limits

What an area chart takes
Ask forWhat Bonnard draws
”stacked”Series stacked, the top edge the total
”as a share of the total”A 100% stack, each series as its share at every point
”overlapping”Each series filled from zero, the default for a split
”cumulative” or “a running total”A running total from the SQL, filled underneath
”with conversion on the right”A second axis for a measure in other units, drawn as a line
”a target line” or “the average”Reference lines and bands, up to six
”a 4-week moving average” or “a trend line”A dashed line over each series, or over the stack’s total
”make the UK stand out”Up to three series highlighted
”on a timeline”Dates spaced by the time between them, the default when unstacked
”start the axis at 100”A fixed axis range, or one fitted to the data
”missing months as zero”Gaps filled with zero or the last value, or left as a break
  • There is no cap on series.
  • A chart query returns up to 5,000 rows by default.
  • Stacked areas keep one slot per row unless the call asks for a timeline. A 100% stack never takes one.
  • In a stack, a missing value counts as zero, so the layers stay aligned.
  • Each measure on the left axis is filled. A measure on the right axis sits outside the stack, as a line with no fill.
  • A 100% stack has no total, so it takes no moving average or trend line.
  • An area whose axis starts above zero says so under the chart.
  • Labels and axis titles run to 60 characters.
  • Lines run straight between points. An area chart draws no data labels. No chart draws a log scale, custom hex colours or zoom.

When Bonnard draws something else

  • A target that changes month by month comes from the SQL as a measure, and the agent draws it as a line over bars.