Usage Chart
One quantity per day as a stepped area you can scrub, with the totals recalculated to any day.
Pattern · Shares patterns with Chart, KPI Card
≈ 3,058 tokens per use (tool 1,052 · guidance 336 · typical payload 1,670)How token costs are estimated
Example: Usage Chart
How many tokens have I used since 27 June?
Token usage
Jun 27 – Sep 22
- Total usage
- 302.12M
- Avg. daily
- 3.43M
- Est. cost
- $959.01
| Date | Tokens | Cached |
|---|---|---|
| Sat, Jun 27 | 857.13K | 0 |
| Sun, Jun 28 | 1.15M | 0 |
| Mon, Jun 29 | 2.14M | 762.58K |
| Tue, Jun 30 | 1.67M | 0 |
| Wed, Jul 1 | 2M | 0 |
| Thu, Jul 2 | 2M | 0 |
| Fri, Jul 3 | 1.61M | 0 |
| Sat, Jul 4 | 839.38K | 0 |
| Sun, Jul 5 | 1.24M | 535.1K |
| Mon, Jul 6 | 2.61M | 0 |
| Tue, Jul 7 | 1.64M | 0 |
| Wed, Jul 8 | 1.65M | 1.12M |
| Thu, Jul 9 | 2.03M | 0 |
| Fri, Jul 10 | 3.01M | 0 |
| Sat, Jul 11 | 1.31M | 0 |
| Sun, Jul 12 | 1.29M | 0 |
| Mon, Jul 13 | 2.45M | 1.54M |
| Tue, Jul 14 | 1.85M | 0 |
| Wed, Jul 15 | 2.74M | 0 |
| Thu, Jul 16 | 2.09M | 563.59K |
| Fri, Jul 17 | 2.34M | 0 |
| Sat, Jul 18 | 1.52M | 792.23K |
| Sun, Jul 19 | 1.64M | 0 |
| Mon, Jul 20 | 2.1M | 0 |
| Tue, Jul 21 | 2.06M | 0 |
| Wed, Jul 22 | 3.45M | 0 |
| Thu, Jul 23 | 3.82M | 0 |
| Fri, Jul 24 | 3.64M | 2.09M |
| Sat, Jul 25 | 1.34M | 0 |
| Sun, Jul 26 | 1.69M | 0 |
| Mon, Jul 27 | 3.93M | 2.17M |
| Tue, Jul 28 | 2.44M | 0 |
| Wed, Jul 29 | 2.73M | 0 |
| Thu, Jul 30 | 3.24M | 0 |
| Fri, Jul 31 | 3.59M | 0 |
| Sat, Aug 1 | 2.16M | 0 |
| Sun, Aug 2 | 1.52M | 0 |
| Mon, Aug 3 | 2.57M | 719.62K |
| Tue, Aug 4 | 3.68M | 0 |
| Wed, Aug 5 | 3.31M | 0 |
| Thu, Aug 6 | 4.47M | 0 |
| Fri, Aug 7 | 2.88M | 0 |
| Sat, Aug 8 | 1.88M | 774.08K |
| Sun, Aug 9 | 2.06M | 0 |
| Mon, Aug 10 | 4M | 0 |
| Tue, Aug 11 | 3.81M | 0 |
| Wed, Aug 12 | 4.36M | 0 |
| Thu, Aug 13 | 3.33M | 2.03M |
| Fri, Aug 14 | 4.08M | 0 |
| Sat, Aug 15 | 1.64M | 0 |
| Sun, Aug 16 | 2.53M | 0 |
| Mon, Aug 17 | 3.1M | 0 |
| Tue, Aug 18 | 3.46M | 0 |
| Wed, Aug 19 | 5.42M | 2.73M |
| Thu, Aug 20 | 4.62M | 0 |
| Fri, Aug 21 | 3.21M | 0 |
| Sat, Aug 22 | 4.96M | 0 |
| Sun, Aug 23 | 2.28M | 744.08K |
| Mon, Aug 24 | 3.49M | 1.35M |
| Tue, Aug 25 | 3.47M | 0 |
| Wed, Aug 26 | 4.45M | 1.84M |
| Thu, Aug 27 | 5.86M | 0 |
| Fri, Aug 28 | 5.01M | 0 |
| Sat, Aug 29 | 1.82M | 1.05M |
| Sun, Aug 30 | 2.6M | 0 |
| Mon, Aug 31 | 5.89M | 0 |
| Tue, Sep 1 | 5.29M | 0 |
| Wed, Sep 2 | 3.72M | 0 |
| Thu, Sep 3 | 3.59M | 2.14M |
| Fri, Sep 4 | 6M | 0 |
| Sat, Sep 5 | 8.52M | 0 |
| Sun, Sep 6 | 2.64M | 0 |
| Mon, Sep 7 | 5M | 0 |
| Tue, Sep 8 | 4.99M | 0 |
| Wed, Sep 9 | 5.33M | 0 |
| Thu, Sep 10 | 5.61M | 0 |
| Fri, Sep 11 | 3.75M | 0 |
| Sat, Sep 12 | 2.43M | 0 |
| Sun, Sep 13 | 3.71M | 0 |
| Mon, Sep 14 | 3.94M | 0 |
| Tue, Sep 15 | 6.98M | 0 |
| Wed, Sep 16 | 5.6M | 0 |
| Thu, Sep 17 | 6.74M | 3.26M |
| Fri, Sep 18 | 7.04M | 5.03M |
| Sat, Sep 19 | 3.74M | 0 |
| Sun, Sep 20 | 3.67M | 0 |
| Mon, Sep 21 | 15.3M | 0 |
| Tue, Sep 22 | 4.92M | 0 |
Daily usage has climbed steadily since June; caching covered only a few of the days.
When to use
- The user asks how much of something they've used over a period (API tokens, energy, data, minutes, spend) and you have it per day from a tool.
- The answer is a running picture: the shape of the days and what the period adds up to, with the chance to check any point in between.
When not to use
- The user wants a trend of a rate or a score, or compares categories. Use a Chart.
- You have one total, not days. Say it in a sentence or use a KPI Card.
- The figures are a forecast or an estimate you made. Only show what the tool returned.
- There are fewer than 2 days.
How the agent should use it
- Pass one row per day exactly as the tool returned them, in any order. Never total, average or fill gaps yourself: the card does the sums, so a figure on screen is always the data's, not the model's.
- Plot one quantity. Add an
overlayonly for a true part of it (cached of total tokens), never a different measure. The overlay shares the scale, and a day without it can leave the field out. - Pick 1–3
statsthe user would ask next. Each names a row field and how the days combine:sumfor totals and costs,averagefor daily rates,maxorminfor extremes,latestfor a level. A stat may read a field that isn't plotted, like a cost column. - Name the value in 1–2 words, with
format,currencyorunit. - In
summary, say what stands out (the busiest day, a jump) in plain words.
Design
- Scrub to total. Moving across the chart puts a cursor on a day, dims the days after it and shows that day's value (and the overlay's) in a hover card. The date range under the title and every figure under the chart recalculate for the period from the first day up to the cursor. Leaving the chart returns to the whole period.
- Steps, not slopes. Each day holds its value across its own band, so a day reads as one flat run. Days are spaced evenly, in date order, whether or not the dates are consecutive.
- Grey and one accent. The main series uses the one-hue ramp and the overlay is the blue from the series palette. The legend under the chart names both, so colour is never the only key.
- Figures are abbreviated from four digits up (511.2K, 5.65M); money stays exact below 100,000.
- A day with no overlay value shows a dash in the hover card.
Accessibility
The plot is a slider: Left and Right step one day, Page Up and Page Down a week, Home and End jump to the ends, Escape returns to the whole period. Its value text reads the day, its values and the recalculated figures. The drawing is hidden from screen readers; a visually hidden table lists every day. Touch scrubs horizontally and still scrolls the page vertically. Dates are read as UTC days, so a day never shifts with the viewer's time zone, and numbers and dates follow the user's locale.
Installation
npx shadcn@latest add https://your-site.com/r/usage-chart.json
Usage
The Usage Chart is display-only, so the tool can return immediately:
import { tool } from "ai"
import { usageChartTool } from "@/components/genui/usage-chart.schema"
const tools = {
[usageChartTool.name]: tool({
description: usageChartTool.description,
inputSchema: usageChartTool.inputSchema,
execute: async () => ({ shown: true }),
}),
}Render it through the Renderer under show_usage, or directly:
<UsageChart {...part.input} status={part.state === "input-streaming" ? "streaming" : "ready"} />Days render as they stream in.
Schema
| Prop | Type | Notes |
|---|---|---|
title | string | What is metered, e.g. "Token usage" |
dateKey | string | Row field with each day's ISO date, e.g. 2026-09-22 |
value | { key, label, format?, currency?, unit? } | The plotted quantity. label is 24 characters at most; format is number or currency |
overlay | { key, label, format?, currency?, unit? }? | A part of the value, drawn in blue on the same scale |
stats | { label, key, op, format?, currency?, unit? }[] | 1–3 figures under the chart. op: sum, average, max, min or latest |
data | Record<string, string | number>[] | Data-bound. 2–400 rows, one per day |
summary | string? | One-sentence takeaway, shown under the figures |
Host props: status (streaming or ready) and className.