Parts of a whole as a ring. Arcs morph with the data, and the middle rolls to the part you point at.
| Plans | $1,832 | 45% |
|---|---|---|
| Products | $1,147 | 28% |
| Services | $637 | 16% |
| Affiliates | $291 | 7% |
| Licensing | $186 | 5% |
pnpm dlx shadcn@latest add @latheui/ring-chartPart of Lathe Pro. Set up your project once with your license key: npx latheui init --key <key>. See Lathe Pro.
Ring Chart is part of Lathe Pro
The preview is live and free to try. The source, the install and every assembly come with Pro: $79 once, with lifetime updates.
Depends on
Also accepts native figure attributes.
| Prop | Type | Default | Description |
|---|---|---|---|
| data* (required) | { key: string; label: string; value: number; color?: string }[] | — | The parts. Zero and negative values are left out. |
| label* (required) | string | — | Names the whole for assistive tech. |
| unit | string | — | Caption under the total. |
| format | Intl.NumberFormatOptions | — | Formatting for every number, for example currency. |
| totalLabel | string | "Total" | Caption above the number at rest. |
| size | number | 200 | Diameter in pixels. It shrinks to fit narrow containers. |
| thickness | number | 22 | Ring thickness in pixels. |
| rounding | number | 0 | How round the segment corners are, from 0 to 100. 0 cuts the ends square, a low number such as 30 softens the sharp corners with a slight curve, and 100 makes each end a half-circle. Very small segments take less so they never swell past their own width. |
| gap | number | 3 | Space between neighbouring segments in pixels, at any rounding. 0 joins them. |
| legend | boolean | true | Shows the list of parts. |
| callouts | boolean | false | Names each part on the ring with a leader line: slanted out from the arc, then level under the label. Adds room around the ring and moves the list below it. |
| activeKey | string | null | — | Controlled pinned part. |
| defaultActiveKey | string | null | null | Initially pinned part. |
| onActiveChange | (key: string | null) => void | — | Called when a part is pinned or unpinned. |
| hiddenKeys | string[] | — | Controlled switched-off parts. |
| defaultHiddenKeys | string[] | [] | Parts switched off at first. |
| onHiddenKeysChange | (keys: string[]) => void | — | Called when a row switches a part on or off. |
| emptyMessage | ReactNode | "No data yet" | Shown in the middle when the total is zero. |
<RingChart label="Earnings by source" data={sources} rounding={30} />
<RingChart label="Earnings by source" data={sources} rounding={60} gap={6} />
<RingChart label="Earnings by source" data={sources} rounding={100} gap={2} />The callouts name the parts, so the list can go.
<RingChart label="Earnings by source" data={sources} callouts legend={false} /><RingChart
label="Spend by category"
totalLabel="Spend"
format={{ style: "currency", currency: "USD", maximumFractionDigits: 0 }}
size={160}
thickness={14}
data={[
{ key: "rent", label: "Rent", value: 4200, color: "var(--chart-2)" },
{ key: "payroll", label: "Payroll", value: 9100, color: "var(--chart-5)" },
]}
/>const [source, setSource] = React.useState<string | null>(null)
<RingChart label="Sources" data={sources} activeKey={source} onActiveChange={setSource} />
<SourcesTable highlight={source} />