---
title: "Chart gallery"
meta:
  description: "Which chart answers which question, in the house style"
---

Every chart is a Markdown table inside `::chart`: the first column is x, every other column is a series, and the table stays under the chart in a **Data** fold. Each section below is one question shape, its chart, and the rules that keep it readable.

## House style

[#Section titled "House style"](#house-style)

These hold for every chart on the page:

- `title` says what is measured, per what, and in what unit when there's no `unit`: "Questions per customer", "Time to first reply (h)".
- `description` says what to see, in one sentence: "Northwind asks twice as many as anyone."
- `unit` goes on every chart whose numbers have one: `$` prints before the number, `%`, `h`, and `ms` after. Numbers from a thousand up print short, as `$22.2k`.
- One measure per chart. Two measures, such as questions and reply time, are two charts.
- At most eight series. Past that, keep the seven largest and add the rest up as `other`.
- Rows sorted by value, largest first, unless their order means something: time, steps, or a funnel.
- A category keeps its column position in every chart, so it keeps its color across the page.
- Bars and heatmaps print their numbers. Leave that on; `labels=false` is for charts so dense the numbers collide.

## How many, per name

[#Section titled "How many, per name"](#how-many-per-name)

Bars, sideways when the names are long or there are more than about six. Sort them.

*Questions per type*

Data questions are a quarter of the total.

Data missingHow it worksForecastPurchasingBugAlerts

886344373730

<details>

<summary>Data</summary>



| type | questions |
| --- | --- |
| Data missing | 88 |
| How it works | 63 |
| Forecast | 44 |
| Purchasing | 37 |
| Bug | 37 |
| Alerts | 30 |

</details>

## How each total splits

[#Section titled "How each total splits"](#how-each-total-splits)

Stacked bars, the parts in a fixed order, from the one the reader cares about first.

*Questions per customer, by the last source a reply needs*

Northwind needs the team for one question in five.

NorthwindContosoFabrikamTailspin

1326241719181611159108111511

thread only

docs and code

product data

team only

<details>

<summary>Data</summary>



| customer | thread only | docs and code | product data | team only |
| --- | --- | --- | --- | --- |
| Northwind | 13 | 26 | 24 | 17 |
| Contoso | 19 | 18 | 16 | 11 |
| Fabrikam | 15 | 9 | 10 | 8 |
| Tailspin | 11 | 15 | 11 | 1 |

</details>

## Two groupings crossed

[#Section titled "Two groupings crossed"](#two-groupings-crossed)

A heatmap, rows and columns in the order the reader scans them. It reads best up to about 12 columns.

*Questions per customer and type*

Northwind's data questions are the largest cell.

21910161517771174271135

Data missingHow it worksForecastBug

NorthwindContosoFabrikamTailspin

<details>

<summary>Data</summary>



| customer | Data missing | How it works | Forecast | Bug |
| --- | --- | --- | --- | --- |
| Northwind | 21 | 9 | 10 | 16 |
| Contoso | 15 | 17 | 7 | 7 |
| Fabrikam | 11 | 7 | 4 | 2 |
| Tailspin | 7 | 11 | 3 | 5 |

</details>

## Scores or pass rates

[#Section titled "Scores or pass rates"](#scores-or-pass-rates)

A heatmap with `better`, so red and green say good and bad without a legend. `better="lower"` for error rates and costs.

*Judge score per section, out of 10*

Every agent struggles with validation.

8.61010106.24.38.51099.64.657.99.18.3101.56.441.97.66.702.1

ScoreFeaturesDataAuthValidationSecurity

Fable 5.2 highOpus 5.5 highGPT-6.1 Sol xhighGPT-6 Luna low

<details>

<summary>Data</summary>



| agent | Score | Features | Data | Auth | Validation | Security |
| --- | --- | --- | --- | --- | --- | --- |
| Fable 5.2 high | 8.6 | 10 | 10 | 10 | 6.2 | 4.3 |
| Opus 5.5 high | 8.5 | 10 | 9 | 9.6 | 4.6 | 5 |
| GPT-6.1 Sol xhigh | 7.9 | 9.1 | 8.3 | 10 | 1.5 | 6.4 |
| GPT-6 Luna low | 4 | 1.9 | 7.6 | 6.7 | 0 | 2.1 |

</details>

## A trend over time

[#Section titled "A trend over time"](#a-trend-over-time)

A line, x as dates such as `2026-05` or `2026-05-04`. Two to eight lines are named at their ends; past that, split the chart.

*Time to first reply*

The median halved since May; the slowest tenth still waits half a day.

May 2026JunJulAugSepOct

1 h2 h5 h10 h

p90median

<details>

<summary>Data</summary>



| month | median | p90 |
| --- | --- | --- |
| 2026-05 | 2.79 | 11.5 |
| 2026-06 | 2.37 | 7.5 |
| 2026-07 | 0.97 | 2.9 |
| 2026-08 | 1.46 | 6.7 |
| 2026-09 | 1.41 | 4.1 |
| 2026-10 | 0.72 | 3.8 |

</details>

## Volume over time, by part

[#Section titled "Volume over time, by part"](#volume-over-time-by-part)

Stacked bars per month or week. Use bars rather than an area when there are fewer than about 20 periods.

*Questions per month, by type*

August doubled May, mostly in data questions.

May 2026JunJulAug

712101017141030211342

Data missing

How it works

other

<details>

<summary>Data</summary>



| month | Data missing | How it works | other |
| --- | --- | --- | --- |
| 2026-05 | 7 | 2 | 12 |
| 2026-06 | 10 | 10 | 17 |
| 2026-07 | 14 | 10 | 30 |
| 2026-08 | 21 | 13 | 42 |

</details>

## One measure against another

[#Section titled "One measure against another"](#one-measure-against-another)

A scatter for points, or a line over numbers when each series is one thing at several settings, such as a model at each effort. Costs and token counts that run from cents to thousands go on `log`.

*Score against cost per task ($)*

Each line is one model from low to max effort.

0.010.1110cost per task

0 pts10 pts20 pts30 pts40 pts50 pts60 pts70 pts

FableOpusLuna

<details>

<summary>Data</summary>



| cost per task | Luna | Opus | Fable |
| --- | --- | --- | --- |
| 0.005 | 10 |  | |
| 0.05 | 19 |  | |
| 0.2 | 28 |  | |
| 1 |  | 35 | |
| 2 |  | 48 | 55 |
| 10 |  | 59 | 62 |
| 20 |  |  | 65 |

</details>

## Before and after

[#Section titled "Before and after"](#before-and-after)

Grouped bars for one to three metrics, a dumbbell past that.

*Page load before and after the cache*

Every page got faster; search the most.

500 ms600 ms700 ms800 ms900 ms1k ms1.1k ms1.2k ms1.3k ms1.4k ms1.5k ms

homesearchcheckoutaccount

before

after

<details>

<summary>Data</summary>



| page | before | after |
| --- | --- | --- |
| home | 820 | 540 |
| search | 1450 | 610 |
| checkout | 980 | 720 |
| account | 640 | 510 |

</details>

## Money across groups

[#Section titled "Money across groups"](#money-across-groups)

Grouped bars with `unit="$"`. When the largest bar flattens the rest, add `log`.

*Cost of a full benchmark run*

High effort costs eight times low on the largest model.

smallmediumlarge

$9$40$63$980$4.8k$22.2k

low

medium

high

<details>

<summary>Data</summary>



| model | low | medium | high |
| --- | --- | --- | --- |
| small | 9 | 40 | 63 |
| medium | 980 | 2,000 | 4,800 |
| large | 2,900 | 11,700 | 22,200 |

</details>

## How changes add up

[#Section titled "How changes add up"](#how-changes-add-up)

A waterfall: the start total, each change, then the end total, which must be the start plus every change.

*Open tickets this quarter*

More tickets closed than opened, so the queue fell to 73.

JulyopenedclosedmergedOctober

0100200300400

total

increase

decrease

<details>

<summary>Data</summary>



| step | tickets |
| --- | --- |
| July | 140 |
| opened | 310 |
| closed | -365 |
| merged | -12 |
| October | 73 |

</details>

## Shares of one whole

[#Section titled "Shares of one whole"](#shares-of-one-whole)

A pie only for five or fewer slices that add up to a whole. Otherwise use sideways bars.

*Replies per person (%)*

Ana writes almost half.

Ana

Ben

Chen

Dara

<details>

<summary>Data</summary>



| person | share |
| --- | --- |
| Ana | 46 |
| Ben | 25 |
| Chen | 21 |
| Dara | 8 |

</details>