Skip to content
microcharts
ReferenceCoreProgressRing

ProgressRing

ProgressRing draws a fraction as an arc from a fixed 12 o'clock start, for slots where a bar doesn't fit.

encodes
arc sweep (fixed 12-o'clock start)
precision
medium — Progress when the % must read precisely
nodes
≤ 3
collection
Core
Source

A backup is 68% done and the only room for it is a tab header. ProgressRing draws that fraction as an arc from a start angle fixed at 12 o'clock, with butt-cut caps: rounded caps overstate small fractions, and a variable start angle makes identical fractions look different. It is not a gauge — no needle, no red zone.

ProgressRing
interactive · 4.37 kB · static · 2.76 kB

Install

Import & usereact/progress-ring
import { ProgressRing } from "@microcharts/react/progress-ring";<ProgressRing value={0.68} title="Backup" />
Needs package + stylesheetSet up with AI

Try it

Live playground
onSelect
idle
  1. hover · click · Enter…

Advance the ring — it announces only at quarter-threshold crossings (no spam).

value % · 68
sweep (countdown)
weight · 3
percent label
readout chip
animate
import { ProgressRing } from "@microcharts/react/progress-ring/interactive";<ProgressRing  value={0.68}  label="percent"/>

When to use it

Use it for tab headers, KPI card corners, and cooldowns or retry timers (sweep). For a precise read use Progress, where the percent label is the datum.

Sizing

tab header
Sync
cooldown (sweep)

Variants

sweep (countdown)
weight
locale — German percent spacing ('68 %', not '68%')

Edge cases

past 100% — the ring clamps full, the label carries the true percent
no data

Past 100% the ring clamps full while the center label carries the true percent, the same contract as Progress. A non-finite value announces no data instead of a fraction. A full circle is drawn as two half-arcs, since SVG cannot draw a single 360° arc.

Four homes

In a sentence

Nightly backup is two-thirds through, about 12 minutes left.

In a table cell
Database82%
Media35%
Config100%
In a KPI card
Storage used
142of 200 GB
In a tab header
PhotosVideos

Preview uses the public chart API only. When an interactive twin exists, it swaps in with the same props and no entrance motion - code samples stay on the static import. Placement recipes: Composition, Sizing.

Accessibility

The accessible name reuses the progress wording — "68% complete.", or "32% remaining." in sweep mode. The interactive entry announces only at 25/50/75/100% threshold crossings, so a streaming value never spams the screen reader.

This chart is a single unit, so there is nothing to rove between: a click, tap, Enter or Space selects it and fires onSelect, and no selection stays pinned. That is the scalar half of the shared interaction contract. Hover or focus also reveals the reading itself in a floating chip, for the sizes and label modes where the mark does not print it; readout={false} drops the chip and keeps everything else.

Props

PropTypeNotes
value*numberThe progressed amount.
maxnumberDenominator (default 1).
sweepbooleanCountdown: the REMAINING wedge shrinks.
weightnumberRing thickness (viewBox units).
label"none" | "percent"Centered figure (≥ 20 px rendered).
sizenumberRing box edge in viewBox units (default 24).
animatebooleaninteractiveOpt-in entrance motion when the chart mounts client-side — add import "@microcharts/react/motion" once. Inert on the server, on hydrated server HTML, and under prefers-reduced-motion.

Plus the shared grammar — data, domain, color, title, summary, format — and the layout props (width, height, className, style) that every chart accepts. Interactive entries also share animate and live, and — wherever a chart has more than one navigable unit — onActive, onSelect, selectedIndex and defaultSelectedIndex; and — wherever the chart shows a hover value — readout. See the shared grammar.

Related charts