Ring Chart
Donut with a hub total. Default and Motion variants.
Examples
Installation
Default is a ready-made wrapper from the registry. Motion is the composable engine at @cronus-ui/ui/charts (peer visx + motion).
npx cronus-ui add ring-chart
import { RingChart } from "@cronus-ui/ui";
Usage
import { RingChart, Ring, RingCenter, Legend, LegendItem, LegendMarker, LegendLabel } from "@cronus-ui/ui/charts";<RingChart data={rings} hoveredIndex={hovered} onHoverChange={setHovered}>{rings.map((_, i) => <Ring index={i} key={i} />)}<RingCenter defaultLabel="Total" /></RingChart>
Components
Motion API — compose these under the chart root. Default wrapper props are in Default API below.
RingChart
Concentric progress rings. Each datum has value / maxValue.
| Prop | Type | Default | Description |
|---|---|---|---|
data* | RingData[] | — | label, value, maxValue, optional color. |
strokeWidth | number | 12 | Ring thickness. |
ringGap | number | 6 | Gap between rings. |
baseInnerRadius | number | 60 | Innermost inner radius. |
hoveredIndex | number | null | — | Controlled hover. |
Ring
One progress arc. Hover scales the ring; others dim.
| Prop | Type | Default | Description |
|---|---|---|---|
index* | number | — | Index in data. |
color | string | — | Override color. |
lineCap | "round" | "butt" | "round" | Arc end cap. |
showGlow | boolean | true | Glow on hover. |
RingCenter
Hub total / hovered value.
| Prop | Type | Default | Description |
|---|---|---|---|
defaultLabel | string | "Total" | Label when nothing is hovered. |
prefix | string | — | Prefix before the number. |
children | (ctx) => ReactNode | — | Custom hub renderer. |
Legend
Composable side legend. Map `LegendItem` (marker, label, value, optional progress) over `items`. Share `hoveredIndex` with the chart for bidirectional highlight.
| Prop | Type | Default | Description |
|---|---|---|---|
items* | LegendItemData[] | — | Label, value, color, optional maxValue. |
hoveredIndex | number | null | — | Controlled hover. |
onHoverChange | (index: number | null) => void | — | Hover callback. |
title | string | — | Heading above the list. |
children* | ReactElement | — | A single LegendItem template, cloned per item. |
Hover + legend
Same bidirectional hoveredIndex pattern as PieChart.
Data format
type RingData = { label: string; value: number; maxValue: number; color?: string };const rings: RingData[] = [{ label: "Storage", value: 68, maxValue: 100 },{ label: "Bandwidth", value: 42, maxValue: 100 },];
Theming
Motion charts read `--chart-*` aliases that map onto Cronus semantic tokens (`--cronus-chart-1`…`--cronus-chart-5`, `--cronus-border`, `--cronus-fg`, surfaces). Override the aliases or the tokens — never palette scales (`bg-zinc-900`). Default wrappers use `ChartConfig` with `var(--cronus-chart-*)` / `var(--cronus-primary)`. Track background is `--border`. defaultRingColors cycles `--chart-1`…`--chart-5`.
Full token reference: Theming.
Dependencies
Default needs the recharts peer. Motion needs visx (and sometimes d3) as optional peers — install only what this chart uses.
bun add recharts
bun add @visx/shape @visx/responsive motion
Default API
Generated from the Default wrapper's exported types. Motion subcomponents are documented above.
RingChartProps
Extends HTMLAttributes<HTMLDivElement>
| Prop | Type | Default | Description |
|---|---|---|---|
data* | RingChartItem[] | — | — |
series* | ChartSeries[] | — | — |
centerLabel | string | "Total" | — |