The sheet an infographic is composed on. It paints a full-bleed ground from a poster theme, forces one theme and colour mode on everything inside, and lays out a masthead, a grid of panels and a footer. It can save the whole sheet as one PNG.
Donut chart
Shows how 2 to 5 parts make up one whole, with each slice labelled by name and share.
- Use when
- A simple composition with one dominant part, or one part the title is about, where the total itself is worth printing in the centre.
- Avoid when
- More than 5 categories or parts of similar size that must be ranked (use bar chart); a single figure (use big number); composition compared across groups or time (use bar chart with stack "percent"); a compact card (use segmented bar).
Preview
4.9 million households in England rented privately in 2022-23
Households by tenure, England, 2022-23
import { DonutChart } from "insightcharts";
const data = [
{ tenure: "Own outright", households: 8.8 },
{ tenure: "Own with a mortgage", households: 7.4 },
{ tenure: "Rent privately", households: 4.9 },
{ tenure: "Rent social housing", households: 4.1 },
];
export function Example() {
return (
<DonutChart
data={data}
name="tenure"
value="households"
format={"{value}m"}
centerLabel="households"
highlight="Rent privately"
title="4.9 million households in England rented privately in 2022-23"
subtitle="Households by tenure, England, 2022-23"
source="English Housing Survey"
note="Figures are approximate, for illustration"
/>
);
}{
"type": "donut-chart",
"data": [
{ "tenure": "Own outright", "households": 8.8 },
{ "tenure": "Own with a mortgage", "households": 7.4 },
{ "tenure": "Rent privately", "households": 4.9 },
{ "tenure": "Rent social housing", "households": 4.1 }
],
"name": "tenure",
"value": "households",
"format": "{value}m",
"centerLabel": "households",
"highlight": "Rent privately",
"title": "4.9 million households in England rented privately in 2022-23",
"subtitle": "Households by tenure, England, 2022-23",
"source": "English Housing Survey",
"note": "Figures are approximate, for illustration"
}Render with import { Insight } from "insightcharts" and <Insight spec={spec} />. Nested specs resolve by name; nothing else to import.
Composition
Used in
1 molecule uses donut chart.
Molecules
1Installation
$ pnpm dlx shadcn@latest add @insightcharts/donut-chartThe 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 { DonutChart } from "insightcharts";Examples
Two slices, no centre
41% of employed adults work remotely or hybrid
Share of employed adults by working pattern
import { DonutChart } from "insightcharts";
const data = [
{ answer: "Remote or hybrid", share: 41 },
{ answer: "On site every day", share: 59 },
];
export function Example() {
return (
<DonutChart
data={data}
name="answer"
value="share"
format={"{value}%"}
highlight="Remote or hybrid"
title="41% of employed adults work remotely or hybrid"
subtitle="Share of employed adults by working pattern"
source="Illustrative survey data"
/>
);
}{
"type": "donut-chart",
"data": [
{ "answer": "Remote or hybrid", "share": 41 },
{ "answer": "On site every day", "share": 59 }
],
"name": "answer",
"value": "share",
"format": "{value}%",
"highlight": "Remote or hybrid",
"title": "41% of employed adults work remotely or hybrid",
"subtitle": "Share of employed adults by working pattern",
"source": "Illustrative survey data"
}Render with import { Insight } from "insightcharts" and <Insight spec={spec} />. Nested specs resolve by name; nothing else to import.
Folded into Other, custom centre
Coal generated 35% of the world's electricity in 2023
Global electricity generation by source, 2023, terawatt-hours
import { DonutChart } from "insightcharts";
const data = [
{ source: "Coal", twh: 10434 },
{ source: "Gas", twh: 6634 },
{ source: "Hydro", twh: 4210 },
{ source: "Nuclear", twh: 2686 },
{ source: "Wind", twh: 2304 },
{ source: "Solar", twh: 1631 },
{ source: "Bioenergy", twh: 697 },
{ source: "Other fossil", twh: 786 },
{ source: "Other renewables", twh: 90 },
];
export function Example() {
return (
<DonutChart
data={data}
name="source"
value="twh"
format="compact"
centerLabel="TWh generated"
centerValue="29,471"
title="Coal generated 35% of the world's electricity in 2023"
subtitle="Global electricity generation by source, 2023, terawatt-hours"
source="Ember, Global Electricity Review 2024"
note="Figures are approximate, for illustration"
/>
);
}{
"type": "donut-chart",
"data": [
{ "source": "Coal", "twh": 10434 },
{ "source": "Gas", "twh": 6634 },
{ "source": "Hydro", "twh": 4210 },
{ "source": "Nuclear", "twh": 2686 },
{ "source": "Wind", "twh": 2304 },
{ "source": "Solar", "twh": 1631 },
{ "source": "Bioenergy", "twh": 697 },
{ "source": "Other fossil", "twh": 786 },
{ "source": "Other renewables", "twh": 90 }
],
"name": "source",
"value": "twh",
"format": "compact",
"centerLabel": "TWh generated",
"centerValue": "29,471",
"title": "Coal generated 35% of the world's electricity in 2023",
"subtitle": "Global electricity generation by source, 2023, terawatt-hours",
"source": "Ember, Global Electricity Review 2024",
"note": "Figures are approximate, for illustration"
}Render with import { Insight } from "insightcharts" and <Insight spec={spec} />. Nested specs resolve by name; nothing else to import.
Stress: long names and a sliver
Staff costs made up 68% of the departmental budget
Departmental spending by category, £ thousands
import { DonutChart } from "insightcharts";
const data = [
{ item: "Salaries, pensions and other staff-related expenditure", cost: 612 },
{ item: "Buildings and facilities management", cost: 188 },
{ item: "Information technology and software licences", cost: 94 },
{ item: "Travel", cost: 3 },
];
export function Example() {
return (
<DonutChart
data={data}
name="item"
value="cost"
format="currency:GBP"
centerLabel="Total budget"
title="Staff costs made up 68% of the departmental budget"
subtitle="Departmental spending by category, £ thousands"
source="Illustrative data"
/>
);
}{
"type": "donut-chart",
"data": [
{ "item": "Salaries, pensions and other staff-related expenditure", "cost": 612 },
{ "item": "Buildings and facilities management", "cost": 188 },
{ "item": "Information technology and software licences", "cost": 94 },
{ "item": "Travel", "cost": 3 }
],
"name": "item",
"value": "cost",
"format": "currency:GBP",
"centerLabel": "Total budget",
"title": "Staff costs made up 68% of the departmental budget",
"subtitle": "Departmental spending by category, £ thousands",
"source": "Illustrative data"
}Render with import { Insight } from "insightcharts" and <Insight spec={spec} />. Nested specs resolve by name; nothing else to import.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| namerequired | string | Category field: one slice per distinct value. | |
| valuerequired | string | Value field. | |
| maxSlices | number | 5 | Most slices drawn, including "Other"; smaller categories are folded. |
| centerLabel | string | Small label in the hole, e.g. "Total". Turns the centre text on. | |
| centerValue | string | number | Big text in the hole. Default: the formatted total when centerLabel is set. | |
| otherLabel | string | "Other" | Name of the folded slice. |
| names | Record<string, string> | Display names for category keys. |
Common chart props 29
Every chart built with defineChart accepts these on top of its own props.
| Prop | Type | Description |
|---|---|---|
| data | DataInput | Rows, CSV text, a URL, { url, path }, an async function, or an Arrow-style table. Omit inside <InsightData>. |
| transform | Transform | Transform[] | A pipeline of transforms applied before drawing. |
| title | string | The title. One plain statement of what the data shows, with the number and the period ("Monthly churn fell from 4.2% to 2.1% in 2024"), or a plain label ("Monthly churn, 2024"). One clause, no figures of speech. |
| subtitle | string | Measure, unit, population, period. |
| source | string | Data source, shown as "Source: ...". |
| note | string | Method notes or caveats. |
| height | number | string | CSS height of the plot. Default 360. |
| aspect | number | Width / height. Overrides height. |
| highlight | string | string[] | The entity (or entities) the title is about. Every other series is drawn in grey. |
| annotations | Annotation[] | Reference lines, shaded bands and callouts, in data coordinates. |
| format | FormatSpec | How to print values: "compact", "percent", "currency:USD", "{value} kg", Intl options, or a function. |
| legend | boolean | Show the legend. Default: shown when there are two or more series. |
| select | boolean | string | Make marks clickable to filter. Inside <InsightData> the selection filters every other chart. Pass a field name, or true to use the chart's category field. |
| onSelect | (values: string[], field: string) => void | Called with the selected values whenever the selection changes. |
| option | EChartsOption | ((option: EChartsOption, ctx: BuildContext) => EChartsOption) | Deep-merged over the generated ECharts option, or a function that receives and returns it. Use it for ECharts settings no prop covers. |
| theme | ThemeInput | A theme, or a partial set of tokens merged over the surrounding theme, for this chart only. |
| mode | ModeInput | "auto" (default) follows the page, "system" follows the OS, or force "light" / "dark". |
| renderer | RendererInput | "auto" (default) uses SVG for light charts and canvas for heavy ones. |
| animate | boolean | Set false to disable animation. Reduced-motion preferences are always respected. |
| lazy | boolean | Mount the chart only when it scrolls near the viewport. Default true. |
| group | string | Link tooltips with other charts sharing this group id. |
| exportable | boolean | ExportFormat[] | Show an export menu: true or a list of formats from png, jpeg, svg, pdf, csv, json. |
| table | boolean | Show a collapsible "View data" table under the chart. |
| alt | string | Accessible description: the chart type and measures, then the main pattern and the notable values. |
| id | string | Stable id for this chart's selection in the shared store. |
| onEvents | Record<string, ChartEventHandler> | ECharts event handlers, e.g. { click: (params, chart) => {} }. Prefix a name with zr: to bind to the canvas itself. |
| onReady | (chart: EChartsInstance) => void | Called with the ECharts instance once it is created. |
| className | string | Class name for the outer <figure>. |
| style | CSSProperties | Inline style for the outer <figure>. |