Chart

Shows how a number moved over time, with exact values on hover.

Examples

Runs over a month

Runs, 30 days

Runs, 30 days
DateRuns
Sep 11,403
Sep 21,672
Sep 31,572
Sep 4775
Sep 5816
Sep 61,557
Sep 71,707
Sep 81,577
Sep 91,620
Sep 101,639
Sep 11844
Sep 12848
Sep 131,656
Sep 141,776
Sep 151,671
Sep 161,814
Sep 171,865
Sep 181,068
Sep 191,139
Sep 201,787
Sep 211,871
Sep 221,801
Sep 231,892
Sep 241,936
Sep 251,215
Sep 261,136
Sep 271,904
Sep 282,123
Sep 291,953
Sep 302,010

Outcomes by day

Outcomes, 14 days

Outcomes, 14 days
DateSucceededRetriedFailed
Sep 171,0416216
Sep 181,2577620
Sep 191,2636720
Sep 201,0368018
Sep 219707317
Sep 221,1806326
Sep 231,3773910
Sep 241,0436116
Sep 251,3558119
Sep 261,354187108
Sep 271,3637124
Sep 281,0678527
Sep 291,3213011
Sep 301,2763610

Failed to load

Outcomes, 14 days

The metrics query timed out

Type

  • Calls

    Calls
    DateAgent callsModel calls
    Sep 1502721
    Sep 2495731
    Sep 3517764
    Sep 4461735
    Sep 5534793
    Sep 6580796
    Sep 7545815
    Sep 8599764
    Sep 9590693
    Sep 10563719
    Sep 11597730
    Sep 12610762
    Sep 13595721
    Sep 14589677
    Sep 15635645
    Sep 16592587
    Sep 17565545
    Sep 18686629
    Sep 19658524
    Sep 20665591
    Sep 21686643
    Sep 22642651
    Sep 23696643
    Sep 24702664
    Sep 25653704
    Sep 26706675
    Sep 27673677
    Sep 28688748
    Sep 29775757
    Sep 30760803

    linedefault

  • Runs by hour

    Runs by hour
    DateRuns
    00:0058
    01:0046
    02:0056
    03:0054
    04:0071
    05:0077
    06:0071
    07:0087
    08:00105
    09:0093
    10:0098
    11:00107
    12:00116
    13:00113
    14:00101
    15:00101
    16:0087
    17:0087
    18:0079
    19:0073
    20:0058
    21:0064
    22:0050
    23:0055

    bar

  • Runs per day: up from 1,403 to 2,010, low 775, high 2,123
    PointRuns per day
    Point 11,403
    Point 21,672
    Point 31,572
    Point 4775
    Point 5816
    Point 61,557
    Point 71,707
    Point 81,577
    Point 91,620
    Point 101,639
    Point 11844
    Point 12848
    Point 131,656
    Point 141,776
    Point 151,671
    Point 161,814
    Point 171,865
    Point 181,068
    Point 191,139
    Point 201,787
    Point 211,871
    Point 221,801
    Point 231,892
    Point 241,936
    Point 251,215
    Point 261,136
    Point 271,904
    Point 282,123
    Point 291,953
    Point 302,010

    sparkline

  • Releases, 30 days
    BucketReleasesStatus
    Sep 199OK
    Sep 2157OK
    Sep 3137OK
    Sep 4119OK
    Sep 569OK
    Sep 60None
    Sep 70None
    Sep 8190OK
    Sep 9104OK
    Sep 1095OK
    Sep 1146OK
    Sep 12155OK
    Sep 130None
    Sep 140None
    Sep 1561OK
    Sep 16116OK
    Sep 17189Warning
    Sep 18154OK
    Sep 1967OK
    Sep 200None
    Sep 210None
    Sep 2296OK
    Sep 2392OK
    Sep 2443OK
    Sep 25179OK
    Sep 2661OK
    Sep 270None
    Sep 280None
    Sep 29136OK
    Sep 30189OK

    status

Frame

  • Runs by hour

    Runs by hour
    DateRuns
    00:0058
    01:0046
    02:0056
    03:0054
    04:0071
    05:0077
    06:0071
    07:0087
    08:00105
    09:0093
    10:0098
    11:00107

    paneldefault

  • Runs by hour

    Runs by hour
    DateRuns
    00:0058
    01:0046
    02:0056
    03:0054
    04:0071
    05:0077
    06:0071
    07:0087
    08:00105
    09:0093
    10:0098
    11:00107

    plain

  • Runs: up from 1,403 to 2,010, low 775, high 2,123
    PointRuns
    Point 11,403
    Point 21,672
    Point 31,572
    Point 4775
    Point 5816
    Point 61,557
    Point 71,707
    Point 81,577
    Point 91,620
    Point 101,639
    Point 11844
    Point 12848
    Point 131,656
    Point 141,776
    Point 151,671
    Point 161,814
    Point 171,865
    Point 181,068
    Point 191,139
    Point 201,787
    Point 211,871
    Point 221,801
    Point 231,892
    Point 241,936
    Point 251,215
    Point 261,136
    Point 271,904
    Point 282,123
    Point 291,953
    Point 302,010

    none

States

  • Reply time

    Loading Reply time

    loading

  • Reply time

    Reply time
    Datep50p95p99
    No runs yet

    empty

  • Reply time

    Query timed out

    error

Usage

When to use it
Use
A number over time where the shape matters: runs per day, reply time, cost.
Use
Two to four series compared on one axis.
Use
A daily health strip for an agent or a prompt release (type="status").
Use
A small trend beside a stat or in a table row (type="sparkline").
Not for
One number now. Use Stat.
Not for
How far a task got. Use Progress.
Not for
Exact values to sort and compare. Use Table.

Rules

12 rules
Must
Set unit to duration or count; never a valueFormat that picks a unit per value. Because a per-value unit puts 900ms and 1.2s on one axis, so the ticks no longer read as one scale.
Must
Render the Chart with loading and its final height; never a spinner or a 0px chart. Because a spinner or an empty box makes the dashboard jump when data lands, and hides which chart is which.
Should
Give each series its kind in the config so the kind's hue reads the same on every screen; a single-kind chart also passes kind for its legend mark.
Must
Show an error top-left in the chart's own frame with Retry; the frame keeps its height. Because a chart swapped for an alert box moves the dashboard and loses which chart failed.
Never
Draw a round point; the active point is a square. Because round means a person in Quartz, and a dot on a line reads as an avatar.
Must
Name the measure and the range in label, such as "Runs, last 30 days". Because label is the title, the table caption and the name of every point group, so "Chart" is all a screen reader hears.
Should
Pass empty as a sentence that names the range.
Must
Let the chart render its data table; never hide it with your own CSS. Because the sr-only table is the only way a screen reader gets the values, and display:none removes it.
Never
Fill an area with a gradient; use area, a flat wash under one line. Because a gradient fades to nothing near the axis, so low values lose their fill and overlapping areas mix into a new hue.
Never
Color series by index; map series to kinds or leave them ink. Because hue means a kind in Quartz, so a purple series reads as agents, and hex values skip the line step that passes 3:1.
Should
Draw at most 4 series in a line chart; split it or show the top 3 and an Other. Because kind-less series past two repeat dashed, so a fifth line no longer has a look of its own.
Should
Keep kind-less bar series to 2. Because kind-less series step from ink to ink at 66%, and bars cannot dash for a third.

Accessibility

8 checks
The plot is a group named by label with aria-roledescription "chart".
Each point is a button named by its x value and every series value.
A data table with the label as caption is always in the DOM.
Arrow keys move between points, Shift moves 7, Home and End jump, Escape hides the tooltip.
Legend items are toggle buttons with aria-pressed.
The tooltip is aria-hidden; the point name carries the values.
Series differ by dash and position as well as hue, so forced colors still read.
The frame sets aria-busy while loading; error is a status region.

Edge cases

13 edge cases
Long label and series name
The title wraps; x labels thin to one per 72px; legend names truncate.
One data point
Draws a small square; one bar fills its band.
data is []
The sentence top-left over a baseline at the body height; the screen-reader table stays, with one row that says it.
Null value
Breaks the line; never drops to zero.
90 status cells on 320px
Cells share the width in whole pixels at 1px gaps.
Right to left
The chart mirrors: x runs from the right, the y axis sits on the right, and Left and Right follow the screen.
Text-only zoom
SVG axis text stays 12px; read exact values from the table switch.
Query fails
The reason in red and Retry sit top-left at the same height; focus moves to the title when Retry unmounts.
Touch
Each x value is a full-height column; use about 30 buckets on phones.
Forced colors
Series map to CanvasText and differ by dash and position; silhouettes map to GrayText.
Reduced motion
Data changes redraw in one frame; nothing tweens.
Inside a frame
Use frame="plain" or "none" so there is one frame, never two; a chart in a Panel's body takes "none".
Study a chart on a working page
Put it in a Card with frame="plain"; frame="panel" is the widget.

API

15 props
type
'line' | 'bar' | 'sparkline' | 'status' default required
label
string default required
data
ChartRow[] | (number | null)[] | StatusBarBucket[] default required
xKey, config, series
string, ChartConfig, string[]
title, description, actions
ReactNode default label
frame
'panel' | 'plain' | 'none' default 'panel', sparkline 'none'
kind, live
Kind, boolean
height
number default 200, status 56, sparkline 24
loading, error, onRetry, retrying, empty
boolean, ReactNode, () => void, boolean, ReactNode
unit
'duration' | 'count'
legend, table, defaultHidden
boolean, boolean, string[] default legend at 2+ series
curve, area, zero
'monotone' | 'linear' | 'step', boolean, boolean default 'monotone', false, true
stacked
boolean default false
kind, variant, end, size
sparkline
kind, noun, range, onBucketClick, size
status

Tokens

18 tokens
--accent-mark
var(--ink)
--accent-line
var(--ink)
--line-accent
2px
--chart-ink-2
oklch(var(--ink-c) / 0.66)
--accent-wash
var(--surface-selected)
--line-frame
oklch(var(--ink-c) / var(--line-frame-alpha))
--line-row
oklch(var(--ink-c) / 0.08)
--line-hair
1px
--ink
oklch(var(--ink-c))
--type-label-sm
400 12px/16px var(--font-sans)
--text-3
oklch(var(--ink-c) / 0.66)
--surface-skeleton
color-mix(in oklch, oklch(var(--grey-c)), oklch(var(--ink-c)) var(--skeleton-step))
--cell-quiet
oklch(var(--ink-c) / 0.07)
--elev-overlay
0 0 0 1px var(--line-frame), 0 12px 24px -12px oklch(var(--text-on-field-c) / var(--shadow-alpha))
--radius-soft
6px
--radius-frame
10px
--mark-size
8px
--chart-dash
6 4

Install

For your coding agent

GitHub

Please star me pookie

141

A new design system every week

Leave your email before you copy the prompt.