Ring Chart
Animated concentric progress rings with staggered track and sweep entrances, a scale-up hover, a rolled center total, and a loading state.
Daily Activity
- Exercise2170%%
- Steps8,30083%%
- Calories54077%%
Installation
pnpm add @blakeui/pro-reactnpm install @blakeui/pro-reactyarn add @blakeui/pro-reactbun add @blakeui/pro-reactUsage
RingChart is built on visx for its arc geometry and the
motion library for the animation — it does not use Recharts, and it
replaces the retired RadialChart. It is a single component: pass a data array (one
{label, value, maxValue} per concentric ring, index 0 innermost) and configure everything through
props. Each ring is a progress arc of value / maxValue over a full-circle track — tracks scale in
staggered from the center, the value arcs sweep open after a hand-off, and hovering a ring scales it
up while the others dim and the center rolls to that ring's value through the shared odometer. Ring
colors come from the categorical --chart-1 … --chart-5 tokens in data order (override per-datum
with color); the tracks and chrome map onto BlakeUI's neutral tokens automatically.
import {RingChart} from "@blakeui/pro-react";
const activity = [
{label: "Exercise", value: 21, maxValue: 30},
{label: "Steps", value: 8300, maxValue: 10000},
{label: "Calories", value: 540, maxValue: 700},
];
function App() {
return <RingChart data={activity} centerLabel="Total" />;
}For a legend that highlights in sync with the chart, control the hover: pass hoveredIndex and
onHoverChange, and drive both the chart and your legend rows from the same index (the hero demo
above wires this in both directions).
Keyboard & motion
The chart is keyboard-accessible: focus it and use the arrow keys (or Home / End) to walk
the rings; Escape clears the selection. The active ring is announced to screen readers through a
live region. The entrance choreography, hover springs, and center odometer all respect
prefers-reduced-motion — when it is set, the chart renders without animation.
Loading state
Set status="loading" to show a stroke-only skeleton ring while data resolves — a bright pulse laps
the ring under a shimmering caption. Flip it to "ready" and the load→ready choreography plays: the
pulse flows out, the caption exits, the tracks scale in, and the value arcs sweep around.
- Exercise
- Steps
- Calories
API Reference
RingChart
The single chart component. Measures its container (or takes a fixed size), auto-scales the ring
stack to fit, and renders the SVG plus the HTML center overlay.
| Prop | Type | Default | Description |
|---|---|---|---|
data | RingChartDataPoint[] | — | One entry per concentric ring, index 0 innermost: {label, value, maxValue, color?}. Each ring fills value / maxValue of the circle; color overrides the positional --chart-1..5 assignment. |
size | number | — | Fixed box size in px. Omit for responsive sizing (a square that fills the container width). |
strokeWidth | number | 12 | Ring thickness in design px (the whole stack auto-scales to fit the box). |
ringGap | number | 6 | Gap between concentric rings in design px. |
baseInnerRadius | number | 60 | Inner radius of the innermost ring in design px. |
lineCap | "round" | "butt" | "round" | Progress-arc end treatment — fully rounded caps or square ends. |
startAngle | number | -Math.PI / 2 | Start angle in radians (0 = 12 o'clock, clockwise). |
endAngle | number | (3 * Math.PI) / 2 | End angle in radians (the default closes a full lap from the top). |
showGlow | boolean | true | Glow the hovered ring with a drop-shadow in its own color. |
centerLabel | string | "Total" | Label under the rolled total; hover swaps it for the active ring's label. |
showCenter | boolean | true | Render the rolled total + label inside the innermost ring. |
valuePrefix | string | — | Static text rendered before the center value (e.g. "$"). |
hoveredIndex | number | null | — | Controlled hover — the active ring index. Pair with onHoverChange for legend sync. |
onHoverChange | (index: number | null) => void | — | Called when the active ring changes (pointer, keyboard, or a controlled legend). |
animationDuration | number | 1100 | Per-stage entrance duration in ms (tracks stagger 80ms; sweeps hand off at 600ms + 100ms per ring). |
status | "loading" | "ready" | "ready" | While loading, shows the skeleton ring and disables interaction. Flipping to ready plays the entrance. |
loadingLabel | string | "" | Centered caption shown while loading. Empty string hides it. |
Also supports all native div HTML attributes.
Radar Chart
A radar (spider) chart — translucent series polygons over shared metric spokes, with a staggered radial entrance, per-series hover with glow and legend sync, and a loading state.
Scatter Chart
A time-series scatter chart — offset-ring point marks per series on a shared time axis, with a blur-fade entrance, hover dimming, a crosshair tooltip, and a loading state.