For AI agents
Chart spec
An agent, the model in an AI client that acts for a person, calls render_chart to draw charts from read-only SQL. Bonnard refuses an unknown option, or one that does not fit the chart type, and gives the valid options.
Verified 9 Nov 2026.
| Option | line | bar | area | pie | scatter | funnel | waterfall | table |
|---|---|---|---|---|---|---|---|---|
encode | x, y, series, y2 | x, y, series, line, y2 | x, y, series, y2 | x, y | x, y, series, size | x, y | x, y | No |
stacking | Yes | Yes | Yes | No | No | No | No | No |
horizontal | No | Yes | No | No | No | No | No | No |
funnelStyle | No | No | No | No | No | Yes | No | No |
xAxisType | Yes | categorical, time | Yes | No | No | No | No | No |
axes | x, y, y2 (range on y, y2) | x, y, y2 (range on y, y2) | x, y, y2 (range on y, y2) | No | x, y (range on x, y) | No | x, y (range on y) | No |
fields | format, label, additive | format, label, additive | format, label, additive | format | format, label | format | format, label | format, label |
fillGaps | Yes | Yes | Yes | No | No | No | No | No |
series | color, line, marker | color, line, marker | color, line, marker | color | color, marker | No | No | No |
markers | Yes | Yes | Yes | No | No | No | No | No |
highlight | Yes | Yes | Yes | Yes | Yes | No | No | No |
legend | Yes | Yes | Yes | Yes | Yes | No | No | No |
reference | Yes, with y2 | Yes, with y2 | Yes, with y2 | No | Yes, with x | No | No | No |
overlay | Yes | Yes | Yes | No | No | No | No | No |
Bonnard also accepts fields[].label and fields[].additive on all chart types, and they have no effect where the table omits them. It accepts a list in encode.y on all types too, and pie, scatter, funnel, and waterfall draw its first column.
charts
An array of 1 to 10 entries, needed on each call. An entry is a saved chart, { "chart_id": "<id>" }, or a chart drawn from a query, with sql. The two kinds can mix. One entry shows one chart. Two or more show a carousel in the order given.
{"charts":[{"sql":"SELECT region, COUNT(*) AS orders FROM orders GROUP BY region ORDER BY orders DESC","chartType":"bar","title":"Orders by region","encode":{"x":"region","y":"orders"}}]}preview_rows
An integer from 0 to 150, default 10, set beside charts. It sets how many rows of each chart the reply shows the agent. The person gets the whole chart.
sql
A string, needed for a chart drawn from a query. It holds one read-only SELECT. Charts take no params, so write literal values.
chartType
One of line, bar, area, pie, scatter, funnel, waterfall, or table. Omit it and the chart selects a type from the shape of the result. A waterfall needs ordered steps with signed changes, and totals on the start and end rows.
title
A string, the chart’s display name.
encode
An object that maps result columns to the chart. Set x when more than one column can be the x-axis, so the chart does not plot the wrong one.
| Key | Value | Effect |
|---|---|---|
x | One column | The x-axis. On scatter, the numeric x measure. On funnel and waterfall, the stage or step label |
y | One column, or a list on line, bar, and area | The measures on the left axis. A list draws one series for each column |
series | One column | One series for each distinct value. It needs exactly one y measure |
line | One column, or a list | Measures drawn as a line over the bars, on the same axis |
y2 | One column, or a list | Measures on a second axis at the right, drawn as a line |
size | One column | A third numeric column that sets the point size |
stacking
stacked, stacked100 for a 100% stack, or grouped. The default is grouped: bars sit side by side, and lines and areas do not stack. Stacking needs more than one series.
horizontal
A boolean. true runs the bars horizontally, with categories on the y-axis. Bars are vertical by default.
funnelStyle
bars or dropoff, default bars. dropoff draws one column for each stage, with the part lost since the previous stage above it. A dropoff chart too narrow for its columns is drawn as bars.
xAxisType
Omit it and the chart infers the scale. On bar, the default is categorical.
| Value | Use it for |
|---|---|
categorical | A numeric column that is a grouping (a year, a rating, a bucket), drawn as evenly spaced labels |
continuous | A measured quantity whose gaps carry meaning |
time | Dates on a chronological timeline, so a two-week gap is twice as wide as a one-week gap |
axes
An object with x, y, and y2. Each takes title, up to 60 characters, and min and max, each a number or "auto". min must be less than max. x takes a range on scatter only.
fields
An array of up to 100 entries, one for each result column. Bonnard never infers a format from a column name, so declare each format.
| Key | Value | Effect |
|---|---|---|
name | Needed, up to 256 characters | The column’s result name. A name can be in the array one time |
label | Up to 60 characters | Replaces the column’s display name |
format | number, percent, currency, or compact | How values are written |
currency | An ISO 4217 code, three capital letters | The currency, with format: "currency" only |
additive | Boolean | true shows missing time buckets as 0, and false as gaps. Unset leaves fillGaps at none |
fillGaps
How the chart draws periods that have no row. Returned rows never change. A measure’s additive sets the default: true is zero, false is gap, and unset is none.
| Value | Effect |
|---|---|
none | Draws only the returned rows, and a line joins across missing periods |
zero | Draws the period as 0, for counts and sums |
previous | Keeps the last known value, for balances and stock levels |
gap | Breaks the line, for rates, ratios, and averages |
series
A map keyed by series name, for up to 24 series. A series name is its legend label, or else its column name. On pie, and on bar with one series, a key can name a category value.
| Key | Value |
|---|---|
color | blue, sky, green, amber, red, violet, pink, teal, or muted |
line | solid, dashed, or dotted |
width | 1 to 6, where line applies |
marker | circle, emptyCircle, rect, roundRect, triangle, diamond, or none |
markers
auto, all, or none. The default is auto, which marks only a point with no neighbour.
highlight
One series name, or up to 3 in an array, each up to 60 characters. The chart draws them in colour and the rest in grey. On pie, and on bar with one series, a name is a category value.
legend
auto, top, bottom, or none. The default is auto, which draws a legend at the bottom when there are two series. top and bottom draw one even for a single series.
reference
Lines and bands across the value axis. It takes {"target": 40, "average": true}, or an array of up to 6 entries. An entry takes exactly one of y, x, or band.
| Key | Value | Effect |
|---|---|---|
y | A number, "average", or "median" | A line across the value axis |
x | A number, "average", or "median" | A vertical line, on scatter only |
band | [low, high], with low below high | A shaded range |
label | Up to 60 characters | Drawn as written |
axis | "y" or "y2" | "y2" puts a y line or a band on the right axis |
overlay
A computed dashed line over each left-axis series. A 100% stack takes no overlay.
| Form | Effect |
|---|---|
{"kind":"movingAverage","window":4} | The trailing average of the last window points, 2 to 52 |
{"kind":"trend"} | The least-squares line |
"series":["<name>"] | Up to 12 series that get the line. Omit it for all left-axis series |
KPI tile
A KPI is a kind: "kpi" tile in save_dashboard, and render_chart has no KPI type. Bonnard reads only the first row of its query. A KPI counts toward the 16 chart and KPI tiles on a dashboard.
| Field | Value | Effect |
|---|---|---|
kind | Needed, "kpi" | The tile type |
id | Needed, up to 64 characters | Lowercase letters, digits, _, and -, starting with a letter |
sql | Needed, up to 8,000 characters | A read-only SELECT |
title | Needed, up to 200 characters | The display name. It can hold a declared {{param}} |
valueColumn | Up to 256 characters | The column with the value. Without it, the first numeric column |
deltaColumn | Up to 256 characters | The change to show beside the value: this period minus the previous one, as a difference, written in the KPI’s format. Up is always green and down always red. A change of 0 shows no arrow |
format | number, currency, percent, or compact | How the value is written |
currency | Three capital letters | The currency, with format: "currency" only |
caption | Up to 2,000 characters | A short line under the value. It can hold a declared {{param}} |
span | 1 to 4, default 1 | The width on the 4-column grid |
What charts do not draw
The charts guide page names these items. Each row quotes what the agent reads.
| Item | Guide page text |
|---|---|
| Sankey diagrams | ”There is no sankey chart type.” |
| Maps | ”There is no map or geographic chart type.” |
| Gauges | ”There is no gauge chart type.” |
| Treemaps | ”There is no treemap chart type.” |
| Heatmaps | ”There is no heatmap chart type.” |
| Box plots | ”There is no box plot chart type.” |
| Pivot tables | ”There is no pivot table type; encode.series pivots tall rows into one series per value.” |
| Bullet and progress charts | ”There is no bullet or progress chart type.” |
| Radar charts | ”There is no radar chart type.” |
| Candlestick charts | ”There is no candlestick chart type.” |
| Data labels | ”Values are not printed on bars or points; pie, funnel and waterfall label themselves.” |
| Hex and brand colours | ”Colours are named slots from the house palette; hex and brand colours cannot be set.” |
| Log scale | ”A log scale cannot be set; value axes are linear.” |
| Smoothed lines | ”Lines are drawn straight between points.” |
| Zooming | ”Charts cannot be zoomed or drilled into; draw a narrower query instead.” |