radial-chart-09
Fine radial progress ring for dashboards: a thin blue weekly ring with listened minutes, a goal total and a ruled footer.
pnpm dlx shadcn add @01orbital/radial-chart-09"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"
import { Separator } from "@/components/ui/separator"
// 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(--art-accent)" },
} satisfies ChartConfig
export default function RadialChart09() {
return (
<Card className="mx-auto w-full max-w-[26rem] gap-8 [--card-spacing:24px]">
<CardHeader>
<CardTitle>
<h2>{COPY.title}</h2>
</CardTitle>
<CardDescription>{COPY.description}</CardDescription>
</CardHeader>
<CardContent>
<ChartContainer
config={CHART_CONFIG}
role="img"
aria-label={`${LISTENED[0].minutes} of ${GOAL} minutes listened`}
className="mx-auto aspect-square w-full max-w-56"
>
<RadialBarChart
accessibilityLayer={false}
data={LISTENED}
startAngle={90}
endAngle={-270}
innerRadius="90%"
outerRadius="100%"
>
{/* 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={0} />
<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}
fontSize={36}
className="fill-foreground tabular-nums"
>
{LISTENED[0].minutes}
</tspan>
<tspan
x={viewBox.cx}
y={(viewBox.cy ?? 0) + 28}
fontSize={10}
className="fill-muted-foreground font-mono uppercase"
>
{COPY.unit}
</tspan>
</text>
)
}}
/>
</PolarRadiusAxis>
</RadialBarChart>
</ChartContainer>
</CardContent>
<CardFooter className="grid gap-3 text-sm text-muted-foreground">
<Separator />
<p>{COPY.note}</p>
</CardFooter>
</Card>
)
}
Dependencies
npm: recharts@3.8.0. The CLI installs them for you.
Registry pieces it installs with it: