GrSparkline
Overview
When to take it
- a trend in a table cell — a “trend” column next to a number: the direction is visible, and the exact values are read from the neighbouring column;
- a trend in a metric card — under the large number of
GrStatistic, so that “1,240” gets a history; - many charts on one page — the component measures nothing and keeps no listeners, so a hundred of them on the screen cost nothing;
- only the silhouette is needed —
summaryadds the minimum, the maximum and the last value in words for a screen reader without taking up room on the screen.
When to take something else
| Need | Take |
|---|---|
| Read values off the axes rather than the silhouette | GrChartLine |
| Show volume rather than the course | GrChartArea |
| Compare categories with one another | GrChartBar |
| Show a share of a whole | GrProgressBar |
Examples 3 each with a live demo and its code
A history under each number
A sparkline gives a big number its history: up or down, steady or jumpy. It has no axes on purpose, so two cards cannot be compared by the height of their lines — each is scaled to its own series, and the number above says how much.
variant="area"suits a card,colorturns churn red because more of it is bad, the change under the number is aGrDeltathat knows a falling churn is good news, andsummaryspeaks the minimum, maximum and last value to a screen reader.- MRR
- €205,640
+3.1%this week- Active customers
- 1,284
+18this week- Churn
- 2.4%
+0.6 ppthis week- Overdue invoices
- €6,940
-18.2%this weekA trend column in a table
The line says «growing or shrinking», the column beside it says how much. Each row gets 365 daily points, and the component thins them itself (LTTB) to what a cell 8rem wide can draw, keeping the shape and the outliers. A
nullis a gap: the line breaks for the month the account was paused instead of diving to zero.API usage by accountCalls per day · last 12 months Account Trend Now Northwind TradersBusiness 48.2k/day Contoso LtdTeam 12.9k/day Fabrikam InteriorsTeamPaused in August 6.4k/day Adventure WorksStarter 1.1k/day Latency on a status page
A silhouette, not a chart to read: no cursor and no Tab stop in every row, by design. The outage is a gap of
nullpoints, so the line does not invent a drop to zero.aria-labelnames the row in a sentence when the automatic summary would say less.Northwind Billing · statusp95 latency · last 24 hours - Invoices APIp95 182 msOperational
- PaymentsNo data 14:30–16:00 — provider outageRecovered
- WebhooksSpike at 17:30 — a retry storm, 30 minutesOperational
- Exportsp95 1.4 sOperational
- Invoices APIp95 182 ms
API generated from the package · cannot drift
Props
| Prop | Type | default | Description |
|---|---|---|---|
valueFormat | GrChartNumberFormat | undefined | undefined | The number format in the text summary for the screen reader: decimal places and separators. |
locale | string | undefined | undefined | The BCP-47 locale for the summary numbers. Unset — the language of the application translations, otherwise `en`. |
ariaLabel | string | undefined | undefined | A custom name instead of the summary. |
color | string | undefined | undefined | Line color. Unset — the `--gr-sparkline-color` token. |
variant | "line" | "area" | undefined | undefined | The look: `line` (the default) or `area` — a line with a fill beneath it. |
summary | boolean | undefined | undefined | An automatic text summary for the screen reader. |
datarequired | readonly (number | null)[] | readonly GrChartPoint[] | — | A bare series of numbers or points. `null` — a gap, the line breaks. |
Types
Every exported type of the subpath, grouped by the file it lives in. Names, generics and bodies come from the package’s declaration files and cannot drift.
import type { GrSparklineConfigurableProps, GrSparklineProps } from '@feugene/granularity-charts/components/GrSparkline'Filedist/types/components/GrSparkline/config.d.ts
const grSparklineConfig: import("@feugene/granum/contract").GranumComponentDescriptor<"GrSparkline">;Filedist/types/components/GrSparkline/defaults.d.ts
interface GrSparklineConfigurableProps {
variant: 'line' | 'area';
summary: boolean;
}Filedist/types/components/GrSparkline/safelist.d.ts
const grSparklineSafelist: string[];Filedist/types/components/GrSparkline/GrSparkline.vue.d.ts
interface GrSparklineProps {
data: readonly (number | null)[] | readonly GrChartPoint[];
variant?: 'line' | 'area';
color?: string;
summary?: boolean;
valueFormat?: GrChartNumberFormat;
locale?: string;
ariaLabel?: string;
}Accessibility
APG pattern
Клавиатуры нет вовсе: компонент неинтерактивен и объявляет себя role="img" со сводкой
Full contract of the package: docs/keyboard.md ↗
Usage from the library prose
There are deliberately no axes
Without axes a line has no scale, and two sparklines cannot be compared with one another: each is normalised over its own series, so a rise that looks identical in two rows of a table may mean plus two per cent and plus two hundred. A sparkline answers “did it grow or fall” — “by how much” is answered by the neighbouring column with the number.
A long series is shortened by itself
The canvas of a sparkline is fixed (a viewBox a hundred units wide), so the budget of vertices is known in advance
and there is nothing to measure: a series longer than the budget is decimated by LTTB with no prop at all. A hundred
sparklines in a column of a table stop adding up a hundred thousand vertices for the sake of a drawing a couple of
centimetres wide, while the shape and single outliers stay in place —
../model.md, the section “Decimation is a projection, not the data”.
Neither a cursor nor a keyboard
The component has no interaction by construction: a point a pixel wide is a target neither for the
mouse nor for a finger, and a focusable element in every cell of a table would break its walk from
the keyboard. If values on hover are needed, that is already
GrChartLine in a cell of its own or in a popover.
Props in this example