# Radial Chart Rings

> Three nested activity rings for move, exercise and stand, drawn as plain SVG circles.

A shadcn/ui block from the [@esuiss](https://suiss.app/ui?utm_source=shadcn.exchange) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/esuiss/radial-chart-rings).

- Page, with a live preview: https://shadcn.exchange/r/esuiss/radial-chart-rings
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/esuiss/radial-chart-rings-light-2b8c7630c5f04fae.png
- Registry item: https://suiss.app/ui/r/new-york-v4/radial-chart-rings.json
- Categories: charts, charts-radial
- Listed: 2026-10-20, source last changed 2026-10-20

## Install

```bash
npx shadcn@latest add https://shadcn.exchange/r/esuiss/radial-chart-rings.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- Registry items: `@esuiss/card`

## Files

### `components/charts/radial-chart-rings.tsx`

```tsx
"use client"

import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"

const rings = [
  {
    key: "move",
    label: "Move",
    value: 720,
    goal: 600,
    color: "var(--color-red-500)",
  },
  {
    key: "exercise",
    label: "Exercise",
    value: 62,
    goal: 30,
    color: "var(--color-green-500)",
  },
  {
    key: "stand",
    label: "Stand",
    value: 12,
    goal: 12,
    color: "var(--color-cyan-500)",
  },
]

const SIZE = 200
const BAR = 16

export function RadialChartRings() {
  return (
    <Card variant="filled" size="sm">
      <CardHeader>
        <CardTitle>Activity rings</CardTitle>
        <CardDescription>Move, exercise and stand</CardDescription>
      </CardHeader>
      <CardContent className="flex justify-center">
        <svg
          role="img"
          aria-label={rings
            .map((ring) => `${ring.label} ${ring.value} of ${ring.goal}`)
            .join(", ")}
          viewBox={`0 0 ${SIZE} ${SIZE}`}
          className="size-50 -rotate-90"
        >
          {rings.map((ring, index) => {
            const radius = SIZE / 2 - BAR / 2 - index * (BAR + 2)
            const circumference = 2 * Math.PI * radius
            const progress = Math.min(1, ring.value / ring.goal)
            return (
              <g key={ring.key}>
                <circle
                  cx={SIZE / 2}
                  cy={SIZE / 2}
                  r={radius}
                  fill="none"
                  strokeWidth={BAR}
                  stroke={`color-mix(in oklab, ${ring.color} 22%, transparent)`}
                />
                <circle
                  cx={SIZE / 2}
                  cy={SIZE / 2}
                  r={radius}
                  fill="none"
                  strokeWidth={BAR}
                  strokeLinecap="round"
                  stroke={ring.color}
                  strokeDasharray={`${progress * circumference} ${circumference}`}
                />
              </g>
            )
          })}
        </svg>
      </CardContent>
    </Card>
  )
}
```
