A headline metric with its change against a previous value and an optional trend
Tags: chart stat kpi metric delta dashboard reporting
The StatCard shows one headline metric: a label, a formatted value, its change against a previous value (coloured by whether the direction is good), an optional hint and definition, and an optional sparkline trend. Group several with StatGroup for a KPI row.
Svelte only (
@classic-homes/charts-svelte); React support is pending.
Import
<script>
import { StatCard } from '@classic-homes/charts-svelte';
</script>Basic Usage
<script>
import { StatCard } from '@classic-homes/charts-svelte';
</script>
<StatCard
label="Closings YTD"
value={412}
valueFormat="integer"
delta={{ previous: 368, label: 'vs last year' }}
trend={[28, 31, 35, 33, 38, 41, 44, 47]}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
label |
string |
required | Metric name |
value |
number | string | null | undefined |
required | The value; numbers are formatted with valueFormat, strings shown as-is |
valueFormat |
ValueFormat |
- | Preset ('number', 'integer', 'compact', 'currency', 'currencyCents', 'percent', 'percentValue', 'days'), Intl.NumberFormatOptions or a function |
locale |
string |
'en-US' |
Locale for valueFormat and the change percentage |
delta |
StatDelta |
- | Change against a previous value |
hint |
string |
- | Secondary text under the value |
definition |
string |
- | Definition of the metric, shown in an info tooltip beside the label (and to screen readers) |
href |
string |
- | Make the card a link |
trend |
(number | null)[] |
- | Trend values, drawn as a sparkline |
trendVariant |
'line' | 'area' | 'bar' |
'line' |
Sparkline variant |
tone |
'default' | 'success' | 'warning' | 'destructive' |
'default' |
Tone of the value itself, e.g. to flag a breached threshold |
emptyValue |
string |
'—' |
Text shown when the value is missing |
loading |
boolean |
false |
Show a loading placeholder |
class |
string |
- | Custom CSS class |
Data Structure
interface StatDelta {
previous: number | null | undefined; // The value compared against
current?: number | null; // Defaults to the card's value when it is a number
display?: 'percent' | 'absolute' | 'both'; // Default 'percent'
goodWhen?: 'up' | 'down' | 'none'; // Which direction is coloured as good (default 'up')
label?: string; // Text after the change (defaults to "vs <previous>")
}The change is shown with an arrow and sign. A rise is green when goodWhen is 'up' and red when it is 'down'; 'none' keeps it neutral. A change from zero has no percentage, so 'percent' falls back to the absolute change. No change is shown when previous (or the current value) is missing.
Examples
Lower Is Better
<StatCard
label="Avg cycle time"
value={112}
valueFormat="days"
delta={{ previous: 121, goodWhen: 'down', display: 'both', label: 'vs Q2' }}
definition="Days from permit to close, for homes closed in the period"
trend={[124, 121, 119, 118, 115, 112]}
/>Currency, Linked, with a Hint
<StatCard
label="Gross margin per home"
value={86400}
valueFormat="currency"
delta={{ previous: 81200, display: 'absolute' }}
hint="Closed homes, trailing 90 days"
href="/reports/margin"
/>Flagging a Threshold
<StatCard
label="Warranty requests over 30 days"
value={23}
tone={23 > 15 ? 'destructive' : 'default'}
delta={{ previous: 18, goodWhen: 'down' }}
/>Loading and Missing Values
<StatCard label="Backlog" value={backlog} loading={!loaded} emptyValue="n/a" />Accessibility
- The definition is available to screen readers as visually hidden text after the label
- Direction is shown with ▲/▼ and a sign as well as colour
- The trend sparkline is labelled "
<label>trend" loadingsetsaria-busyon the card- With
hrefthe card is a focusable link with a visible focus ring
Related Charts
- StatGroup - Responsive grid of stat cards
- Sparkline - The trend line on its own
- BulletChart - Several values against targets