ChartFrame
StableThe box every chart sits in. It adds a title, a short written summary, a table view and clear messages when data is loading or missing.
Also known as chart container, chart card, chart wrapper
Install with npm install @tattva/ui (setup), or copy the code from the kit in Downloads.
A chart with a summary and a table
How long orders take
Minutes per order, last 7 days
The slowest orders took 82 minutes on Friday. A typical order stayed between 26 and 30 minutes all week.
- Typical order
- Slowest orders
Source: order records.
<ChartFrame
title="How long orders take"
subtitle="Minutes per order, last 7 days"
summary="The slowest orders took 82 minutes on Friday. A typical order stayed between 26 and 30 minutes all week."
source="Source: order records."
table={lineChartTable(DAYS, LATENCY, { xHeader: "Day", caption: "How long orders take, last 7 days", unit: "min" })}
>
<LineChart series={LATENCY} x={DAYS} unit="minutes" ariaLabel="How long orders take" />
</ChartFrame>The summary says what the chart shows. View as table swaps the chart for the same numbers in a table.
When to use it
The box every chart sits in. It puts the title, what is measured and a summary in words above the chart, so the point is clear before anyone reads the lines.
Made of: Title · Subtitle with what is measured and when · Table and download buttons · Summary in words · Key for the lines or bars · Chart or table · Source and note
Use it for
- Any chart on a page, so it gets a title, a summary and a table view.
- Showing clear messages while data loads, when there is none, or when loading fails.
- A chart that may land in a narrow space: pass a small trend line as the fallback.
Do and avoid
Orders per day
Orders, Mon to Thu
Thursday was the busiest day, with 21 orders.
Orders per day
Orders, Mon to Thu
Do
- Write the summary as a sentence that says what the data shows, with the key number.
- Say what is measured and over what time in the subtitle.
- Give every chart a table, so the table button is always there.
- When there is nothing to show, say why and what to do next.
- Pass onRetry, so the error message offers a Try again button.
Avoid
- Don't skip the summary because the chart looks obvious. Some people need the words.
- Don't hide numbers in a pop-up. Put them in the table.
- Don't put filters inside the box. Keep them in one row above the charts they control.
- Don't make the box shorter than the chart and its labels.
On a phone
- The chart is drawn at the width of the frame, and below minWidth (280px unless you change it) it is replaced by your fallback, usually a Sparkline, with a note to use the table view.
- Cards use 16px padding and the title wraps instead of being cut off.
- The View as table button swaps in a DataTable that scrolls sideways inside the frame, so give the table a narrow column set for phones.
Seen in products
- The UK Analysis Function charts checklist requires a text alternative as a data table, a description of the message, or both, in body text and not only in alt text. It also recommends a downloadable data file.
- Highcharts' accessibility module offers a chart description and a data-table view.
- Carbon's chart anatomy lists title, legend and graph frame as parts of a chart.
Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| titlerequired | string | none | Chart title, set in the display style. |
| subtitle | string | none | States the unit and the time window. |
| summary | ReactNode | none | Plain-language reading of the chart, shown above it in body text. |
| children | ReactNode | none | The chart. It receives the full width of the frame. |
| table | DataTableProps | none | Data for the table view. Without it the toggle is hidden. Each chart exports a helper that builds it. |
| source | string | none | Source line shown under the chart. |
| note | string | none | Caveat shown after the source, for example that the latest point is still streaming. |
| legend | ReactNode | none | Rendered above the chart. Charts draw their own legend, so use this only for a shared legend. |
| state | "ready" | "loading" | "empty" | "error" | "ready" | Anything other than ready replaces the chart. |
| empty | ChartEmptyState | none | What is missing, why, and an optional action. Shown in the empty state. |
| errorMessage | string | none | Message for the error state. A default says nothing was lost. |
| onRetry | () => void | none | Called by the retry button in the error state. |
| fallback | ReactNode | none | Shown instead of the chart when the frame is narrower than minWidth. |
| minWidth | number | 280 | Narrowest width in px at which the chart is drawn. |
| defaultView | "chart" | "table" | "chart" | Which view is shown first. |
| onDownload | () => void | none | Adds a Download data button and calls this when pressed. |
| stateHeight | number | 200 | Height in px of the loading, empty and error states, so the layout does not jump. |
| className | string | none | Extra classes on the figure. |
"Show code under the preview gives the code for the example on the stage."
In Figma
In Figma, one ChartFrame switches all of this from its properties panel, across 8 variants. Each property sets the React prop beside it, so design and code use the same names.
| Figma property | React | Values |
|---|---|---|
| Status | state | Ready, Loading, Empty, Error |
| Default view | defaultView | Chart, Table |
| Title | title | Any text |
| Subtitle | subtitle | Any text |
| Summary | summary | Any text |
| Source | source | Any text |
Tokens
Change one of these and every part that uses it follows.
--surface--border--fg--fg-muted--fg-subtle--chart-axis--font-serif--radius-card
Built in
- The title and summary sit in the chart's caption, so screen readers hear them with the chart.
- View as table swaps in a real table with the same numbers, and the button label changes to match the view.
- While data loads, screen readers hear "Loading chart".
- A failure is announced right away.
What you need to do
- Write a summary that says what the data shows, with the key number. Some people only get the words.
- Pass table data for every chart, or the View as table button does not appear.
Built toward WCAG 2.2 AA and checked automatically; no independent audit yet. Read the accessibility guide