A word-sized line or bar series without axes, with the latest point marked.
Trend card
A KPI card computed from a series: the latest value, its change against a baseline in the same data, and a sparkline of the series.
- Use when
- A metric whose recent history matters as much as its level: users, revenue, response time. Pass the series and field names; the figure, the change and the sparkline all come from the same rows, so they cannot disagree.
- Avoid when
- A number with no history (use big number or stat tile); several metrics from one dataset (use kpi grid); a series the reader must read values from (use line chart).
Preview
import { TrendCard } from "insightcharts";
const data = [
{ month: "2024-01-01", users: 38100 },
{ month: "2024-02-01", users: 39400 },
{ month: "2024-03-01", users: 39000 },
{ month: "2024-04-01", users: 40800 },
{ month: "2024-05-01", users: 42200 },
{ month: "2024-06-01", users: 41900 },
{ month: "2024-07-01", users: 43500 },
{ month: "2024-08-01", users: 44100 },
{ month: "2024-09-01", users: 44500 },
{ month: "2024-10-01", users: 46000 },
{ month: "2024-11-01", users: 47200 },
{ month: "2024-12-01", users: 48210 },
];
export function Example() {
return (
<TrendCard
label="Monthly active users"
data={data}
x="month"
y="users"
format="compact"
style={{ maxWidth: 300 }}
/>
);
}{
"type": "trend-card",
"label": "Monthly active users",
"data": [
{ "month": "2024-01-01", "users": 38100 },
{ "month": "2024-02-01", "users": 39400 },
{ "month": "2024-03-01", "users": 39000 },
{ "month": "2024-04-01", "users": 40800 },
{ "month": "2024-05-01", "users": 42200 },
{ "month": "2024-06-01", "users": 41900 },
{ "month": "2024-07-01", "users": 43500 },
{ "month": "2024-08-01", "users": 44100 },
{ "month": "2024-09-01", "users": 44500 },
{ "month": "2024-10-01", "users": 46000 },
{ "month": "2024-11-01", "users": 47200 },
{ "month": "2024-12-01", "users": 48210 }
],
"x": "month",
"y": "users",
"format": "compact",
"style": { "maxWidth": 300 }
}Render with import { Insight } from "insightcharts" and <Insight spec={spec} />. Nested specs resolve by name; nothing else to import.
Composition
Built from
The pieces trend card renders or expects in its slots.
Atoms
2A compact, bordered KPI tile: label, value, change against a baseline and an optional trend graphic.
Used in
1 molecule and 1 template use trend card.
Molecules
1A responsive grid of trend cards drawn from one dataset: each metric shows its latest value, its change and a sparkline.
Installation
$ pnpm dlx shadcn@latest add @insightcharts/trend-cardThe CLI copies the source into your project and needs the @insightcharts registry in components.json; see installation. With the package, import it by name:
import { TrendCard } from "insightcharts";Examples
Down is good, trend on the right
import { TrendCard } from "insightcharts";
const data = [
{ month: "2024-01-01", hours: 4.1 },
{ month: "2024-02-01", hours: 3.9 },
{ month: "2024-03-01", hours: 3.8 },
{ month: "2024-04-01", hours: 3.2 },
{ month: "2024-05-01", hours: 3.4 },
{ month: "2024-06-01", hours: 2.9 },
{ month: "2024-07-01", hours: 2.7 },
{ month: "2024-08-01", hours: 2.4 },
{ month: "2024-09-01", hours: 2.2 },
];
export function Example() {
return (
<TrendCard
label="Median first-response time"
data={data}
x="month"
y="hours"
format={"{value} h"}
upIsGood={false}
trendPosition="right"
style={{ maxWidth: 440 }}
/>
);
}{
"type": "trend-card",
"label": "Median first-response time",
"data": [
{ "month": "2024-01-01", "hours": 4.1 },
{ "month": "2024-02-01", "hours": 3.9 },
{ "month": "2024-03-01", "hours": 3.8 },
{ "month": "2024-04-01", "hours": 3.2 },
{ "month": "2024-05-01", "hours": 3.4 },
{ "month": "2024-06-01", "hours": 2.9 },
{ "month": "2024-07-01", "hours": 2.7 },
{ "month": "2024-08-01", "hours": 2.4 },
{ "month": "2024-09-01", "hours": 2.2 }
],
"x": "month",
"y": "hours",
"format": "{value} h",
"upIsGood": false,
"trendPosition": "right",
"style": { "maxWidth": 440 }
}Render with import { Insight } from "insightcharts" and <Insight spec={spec} />. Nested specs resolve by name; nothing else to import.
Absolute change against the previous period, bars
import { TrendCard } from "insightcharts";
const data = [
{ month: "2024-01-01", rate: 3.9 },
{ month: "2024-02-01", rate: 3.8 },
{ month: "2024-03-01", rate: 3.8 },
{ month: "2024-04-01", rate: 3.6 },
{ month: "2024-05-01", rate: 3.5 },
{ month: "2024-06-01", rate: 3.6 },
{ month: "2024-07-01", rate: 3.4 },
{ month: "2024-08-01", rate: 3.7 },
{ month: "2024-09-01", rate: 3.8 },
{ month: "2024-10-01", rate: 3.9 },
{ month: "2024-11-01", rate: 4.1 },
{ month: "2024-12-01", rate: 4.3 },
];
export function Example() {
return (
<TrendCard
label="Unemployment rate"
data={data}
x="month"
y="rate"
format={"{value}%"}
compare="previous"
change="absolute"
upIsGood={false}
kind="bar"
context="Highest month of 2024"
style={{ maxWidth: 300 }}
/>
);
}{
"type": "trend-card",
"label": "Unemployment rate",
"data": [
{ "month": "2024-01-01", "rate": 3.9 },
{ "month": "2024-02-01", "rate": 3.8 },
{ "month": "2024-03-01", "rate": 3.8 },
{ "month": "2024-04-01", "rate": 3.6 },
{ "month": "2024-05-01", "rate": 3.5 },
{ "month": "2024-06-01", "rate": 3.6 },
{ "month": "2024-07-01", "rate": 3.4 },
{ "month": "2024-08-01", "rate": 3.7 },
{ "month": "2024-09-01", "rate": 3.8 },
{ "month": "2024-10-01", "rate": 3.9 },
{ "month": "2024-11-01", "rate": 4.1 },
{ "month": "2024-12-01", "rate": 4.3 }
],
"x": "month",
"y": "rate",
"format": "{value}%",
"compare": "previous",
"change": "absolute",
"upIsGood": false,
"kind": "bar",
"context": "Highest month of 2024",
"style": { "maxWidth": 300 }
}Render with import { Insight } from "insightcharts" and <Insight spec={spec} />. Nested specs resolve by name; nothing else to import.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| labelrequired | string | What the figure measures, sentence case. | |
| data | DataInput | Rows in time order, one per period. Omit inside <InsightData>. | |
| transform | Transform | Transform[] | Applied to the rows before anything is computed. | |
| yrequired | string | Value field: the series drawn and the source of the figure and its change. | |
| x | string | Period field, used to name the baseline and in the sparkline tooltip. | |
| value | number | string | The figure shown. Default: the last row's y. | |
| delta | number | string | The change shown. Default: computed from the series according to compare. | |
| compare | "first" | "previous" | number | "first" | Baseline for the computed change: first row, previous row, or a number of rows back (12 for year-on-year in monthly data). |
| change | "percent" | "absolute" | "percent" | Relative change, or the difference between the two values (use for rates and shares). An absolute change of a percentage is shown in percentage points. |
| deltaFormat | FormatSpec | Format for a computed absolute change, e.g. "{value} pp" or "signed". Default: points ("+1.9 pts") when format is a percentage, otherwise format. | |
| deltaLabel | string | What the change is against. Default: "since {first period}" when x is given. | |
| upIsGood | boolean | true | Whether an increase is good news; decides the delta colour. |
| context | string | A line under the figure that gives it meaning. | |
| format | FormatSpec | "auto" | Number format for the figure and the sparkline tooltip. |
| kind | "line" | "bar" | "line" | Sparkline form: a line for a trend, bars for discrete counts. |
| area | boolean | false | Light fill under the line; the scale then includes zero. |
| trendPosition | "bottom" | "right" | "bottom" | Where the sparkline sits; right falls back to bottom in narrow cards. |
| theme | ThemeInput | Theme override, passed on to the tile and sparkline. | |
| mode | "auto" | "system" | "light" | "dark" | "auto" | Colour mode. |