# Exercise Minutes

> Card with a two-line chart comparing this week's exercise minutes against the average by day, both drawn in primary ink with the average at half strength. Client component on recharts 3.8.

A shadcn/ui block from the [@01orbital](https://01orbital.dev/?utm_source=shadcn.exchange) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/01orbital/exercise-minutes).

- Page, with a live preview: https://shadcn.exchange/r/01orbital/exercise-minutes
- Screenshot: https://shadcn.exchange/shot/01orbital/exercise-minutes/light.png
- Registry item: https://01orbital.dev/r/exercise-minutes.json
- Categories: charts
- Listed: 2026-11-01, source last changed 2026-11-01

## Install

```bash
npx shadcn@latest add https://shadcn.exchange/r/01orbital/exercise-minutes.json
```

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

## Dependencies

- npm packages: `recharts`
- Registry items: `card`, `@01orbital/chart`

## Files

### `blocks/charts/exercise-minutes/index.tsx`

```tsx
"use client"

import { CartesianGrid, Line, LineChart, XAxis } from "recharts"

import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card"
import {
  ChartContainer,
  ChartTooltip,
  ChartTooltipContent,
  type ChartConfig,
} from "@/components/ui/chart"

// The copy: change text here, not in the markup.
const COPY = {
  title: "Exercise minutes",
  description: "Your exercise minutes are ahead of where you normally are.",
} as const

const EXERCISE_MINUTES = [
  { day: "Monday", today: 240, average: 400 },
  { day: "Tuesday", today: 139, average: 300 },
  { day: "Wednesday", today: 980, average: 200 },
  { day: "Thursday", today: 390, average: 278 },
  { day: "Friday", today: 480, average: 189 },
  { day: "Saturday", today: 380, average: 239 },
  { day: "Sunday", today: 430, average: 349 },
]

// Both series take the primary ink; the average is drawn at half strength.
const CHART_CONFIG = {
  today: { label: "Today", color: "var(--primary)" },
  average: { label: "Average", color: "var(--primary)" },
} satisfies ChartConfig

export default function ExerciseMinutes() {
  return (
    <Card className="mx-auto w-full max-w-md">
      <CardHeader>
        <CardTitle>
          <h2>{COPY.title}</h2>
        </CardTitle>
        <CardDescription>{COPY.description}</CardDescription>
      </CardHeader>
      <CardContent>
        <ChartContainer config={CHART_CONFIG} className="w-full md:h-[200px]">
          <LineChart
            accessibilityLayer
            aria-label={COPY.title}
            data={EXERCISE_MINUTES}
            margin={{ top: 5, right: 10, left: 16, bottom: 0 }}
          >
            <CartesianGrid vertical={false} />
            {/* Stock ChartContainer's label color misses recharts 3's label layer. */}
            <XAxis
              tick={{ fill: "var(--muted-foreground)" }}
              dataKey="day"
              tickLine={false}
              axisLine={false}
              tickMargin={8}
              tickFormatter={(value: string) => value.slice(0, 3)}
            />
            <Line
              type="monotone"
              dataKey="today"
              strokeWidth={2}
              stroke="var(--color-today)"
              dot={{ fill: "var(--color-today)" }}
              activeDot={{ r: 5 }}
            />
            <Line
              type="monotone"
              dataKey="average"
              strokeWidth={2}
              stroke="var(--color-average)"
              strokeOpacity={0.5}
              dot={{ fill: "var(--color-average)", opacity: 0.5 }}
              activeDot={{ r: 5 }}
            />
            <ChartTooltip content={<ChartTooltipContent />} />
          </LineChart>
        </ChartContainer>
      </CardContent>
    </Card>
  )
}
```
