Skip to content

shadcn.io is an independent project built on shadcn/ui

Ring Chart with Legend

Rings beside a legend with values, percentages and progress bars, highlighting together on hover. For React with TanStack Charts, in your shadcn/ui theme: the live chart, its code and a one-line install.

Charting library: TanStack Charts

Preview

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.

Usage

import { ChartRingLegend } from "@/components/charts/chart-ring-legend";
<ChartRingLegend />

API Reference

RingChart

PropType
dataRingData[]

The rings to draw, from the innermost outwards. Each ring fills value / maxValue of its track.

size?number

Chart width and height in pixels. Omit to fill the width of the parent element; the chart stays square.

strokeWidth?number

Thickness of each ring in pixels.

Default
12
ringGap?number

Gap between neighbouring rings in pixels.

Default
6
baseInnerRadius?number

Inner radius of the innermost ring in pixels. Also sets the size of the area available to RingCenter.

Default
60
animationDuration?number

Accepted for bklit-ui compatibility; has no effect. Use enterTransition to change the entrance timing.

className?string

Extra class name for the chart container.

style?CSSProperties

Inline styles for the chart container, merged over the default sizing.

hoveredIndex?number | null

Index of the hovered ring, for controlled hover. Pass null for no hover; leave it undefined to let the chart manage hover itself.

Type
number | null
onHoverChange?(index: number | null) => void

Called with the index of the hovered or keyboard-focused ring, or null when hover ends.

Type
(index: number | null) => void
startAngle?number

Angle where every ring starts, in radians, clockwise from 12 o'clock (d3's convention): the default -Math.PI / 2 is 9 o'clock. bklit-ui's own comment calls the default "top", but its d3 arcs start at 9 o'clock too.

Default
-Math.PI / 2
endAngle?number

Angle where a full ring ends, in radians. Together with startAngle this sets the sweep; the default is a full circle.

Default
(3 * Math.PI) / 2
enterTransition?RingEnterTransition

Transition for the entrance, in the shape used by the motion library (type, duration in seconds, ease, and spring values). Defaults to a 1.1 second tween on the shared reveal curve.

enterStaggerScale?number

Multiplier for the delay between one ring's entrance and the next. 0 starts all rings together.

Default
1
geometryScrubbing?boolean

Turns off hover effects and Ring overrides. Meant for live editors that redraw the geometry while a control is dragged; leave it off otherwise.

Default
false
childrenReactNode

Ring elements to configure individual rings and an optional RingCenter.

ariaLabel?string

Accessible name of the chart.

Default
"Ring chart"
ariaDescription?string

Longer accessible description of the chart.

Ring

PropType
indexnumber

Index of the ring this element configures, matching its position in the data array.

color?string

Colour override for this ring. Takes precedence over the data item's color.

animate?boolean

Play the entrance animation for this ring. Set false to draw it without animating.

Default
true
showGlow?boolean

Accepted for bklit-ui compatibility. No glow is drawn, which matches how bklit-ui renders.

lineCap?RingLineCap

Shape of the ring's leading end: "round" or "butt" (square).

Default
"round"

RingCenter

PropType
defaultLabel?string

Label shown under the total while no ring is hovered. A hovered ring shows its own label instead.

Default
"Total"
formatOptions?CenterStatFormat

Number format for the centre value, in Intl.NumberFormat terms (notation, currency, fraction digits and so on).

Default
{ maximumFractionDigits: 0, notation: "standard" }
children?(props: Readonly<RingCenterRenderProps>) => ReactNode

Render function for custom centre content. It is called with { value, label, isHovered, data } while a ring is hovered; when nothing is hovered the default total is shown.

Type
(props: Readonly<RingCenterRenderProps>) => ReactNode
className?string

Extra class name for the centre container.

valueClassName?string

Class name for the value text.

labelClassName?string

Class name for the label text.

prefix?string

Text shown before the value, for example "$".

suffix?string

Text shown after the value, for example "%".

Legend

PropType
itemsLegendItemData[]

The items to list.

hoveredIndex?number | null

Controlled hovered item index (null for none). The legend manages hover itself when this is left undefined.

Type
number | null
onHoverChange?(index: number | null) => void

Called with the hovered item index, or null when the pointer leaves. Only used when hoveredIndex is controlled.

Type
(index: number | null) => void
title?string

Heading shown above the items.

titleClassName?string

Class names added to the title, on top of the default title style.

className?string

Class names added to the legend container.

childrenReactElement

A single element rendered once per item, usually a LegendItemComponent.

LegendItemComponent

PropType
className?string

Class names added to the row, on top of the default row style.

childrenReactNode

Row content, for example LegendMarker, LegendLabel, LegendValue and LegendProgress.

LegendMarker

PropType
className?string

Class names that replace the default marker size.

LegendLabel

PropType
className?string

Class names that replace the default label text style.

LegendValue

PropType
className?string

Class names that replace the default value text style.

showPercentage?boolean

Show the percentage of maxValue next to the value. Nothing is shown for items without a maxValue.

Default
false
percentageClassName?string

Class names that replace the default percentage text style.

formatValue?(value: number) => string

Formats the value.

Type
(value: number) => string
Default
en-US number format, for example "1,234"
formatPercentage?(percentage: number) => string

Formats the percentage (a number from 0 to 100).

Type
(percentage: number) => string
Default
percentage rounded to a whole number followed by %

LegendProgress

PropType
trackClassName?string

Class names added to the progress track.

indicatorClassName?string

Class names added to the filled bar.

height?string

Height of the progress track. Defaults to a thin bar.