Narrow card with a radial ring showing progress toward a weekly listening goal, minutes in the center, the remaining track visible and a footer note. Client component on recharts 3.8.
"use client"
import {
Label,
PolarAngleAxis,
PolarRadiusAxis,
RadialBar,
RadialBarChart,
} from "recharts"
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card"
import { ChartContainer, type ChartConfig } from "@/components/ui/chart"
// The copy: change text here, not in the markup.
const COPY = {
title: "Weekly goal",
description: "October 12 to 18",
unit: "of 600 minutes",
note: "138 minutes to go, about 20 a day.",
} as const
const GOAL = 600
const LISTENED = [{ goal: "week", minutes: 462, fill: "var(--color-minutes)" }]
const CHART_CONFIG = {
minutes: { label: "Minutes", color: "var(--chart-2)" },
} satisfies ChartConfig
export default function RadialChart01() {
return (
<Card className="mx-auto w-full max-w-xs">
<CardHeader>
<CardTitle>
<h2>{COPY.title}</h2>
</CardTitle>
<CardDescription>{COPY.description}</CardDescription>
</CardHeader>
<CardContent>
<ChartContainer
config={CHART_CONFIG}
className="mx-auto aspect-square max-h-64"
>
<RadialBarChart
data={LISTENED}
startAngle={90}
endAngle={-270}
innerRadius={86}
outerRadius={112}
>
{/* The goal sets the full turn; the track shows what is left. */}
<PolarAngleAxis type="number" domain={[0, GOAL]} tick={false} />
<RadialBar dataKey="minutes" background cornerRadius={12} />
<PolarRadiusAxis tick={false} tickLine={false} axisLine={false}>
<Label
content={({ viewBox }) => {
if (!viewBox || !("cx" in viewBox)) return null
return (
<text
x={viewBox.cx}
y={viewBox.cy}
textAnchor="middle"
dominantBaseline="middle"
>
<tspan
x={viewBox.cx}
y={viewBox.cy}
className="fill-foreground text-4xl font-medium tabular-nums"
>
{LISTENED[0].minutes}
</tspan>
<tspan
x={viewBox.cx}
y={(viewBox.cy ?? 0) + 28}
className="fill-muted-foreground"
>
{COPY.unit}
</tspan>
</text>
)
}}
/>
</PolarRadiusAxis>
</RadialBarChart>
</ChartContainer>
</CardContent>
<CardFooter className="justify-center text-sm text-muted-foreground">
<p>{COPY.note}</p>
</CardFooter>
</Card>
)
}
pnpm dlx shadcn add @01orbital/radial-chart-01npx shadcn add @01orbital/radial-chart-01yarn shadcn add @01orbital/radial-chart-01bunx --bun shadcn add @01orbital/radial-chart-01Free under the MIT license. Add the @01orbital registry to components.json once (install guide), then run the command.
It lands at components/blocks/charts/radial-chart-01/index.tsx, as source you own and edit.
import RadialChart01 from "@/components/blocks/charts/radial-chart-01"
export default function Example() {
return <RadialChart01 />
}npm: recharts@3.8.0. The CLI installs them for you.
Registry pieces it installs with it:
cardchartTraffic Overview
Wide card with a two-line chart of views and unique readers, a date-range select, a legend and a dot on the busiest day. The views color changes between light and dark. Uses recharts 3.8.
Compare
Every Showcase block side by side: whether it follows the theme or stays dark, the stock parts it is built on, and whether it is free. Open one for its preview, props and install.