Charts

Diverging Bar Chart

Card with a diverging column chart of week-on-week change by day, bars rising and falling from a zero reference line with signed percentage labels. Client component on recharts 3.8.

Free, MIT licenseOpen in Browse
"use client"

import {
  Bar,
  BarChart,
  CartesianGrid,
  LabelList,
  ReferenceLine,
  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: "Listening time",
  description: "Change on last week, by day",
} as const

const CHANGE = [
  { day: "Monday", change: 12 },
  { day: "Tuesday", change: -8 },
  { day: "Wednesday", change: 5 },
  { day: "Thursday", change: -14 },
  { day: "Friday", change: 9 },
  { day: "Saturday", change: 18 },
  { day: "Sunday", change: -3 },
]

const CHART_CONFIG = {
  change: { label: "Change", color: "var(--chart-2)" },
} satisfies ChartConfig

const formatChange = (value: unknown) => {
  const change = Number(value)
  return `${change > 0 ? "+" : ""}${change}%`
}

export default function BarChart03() {
  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}>
          <BarChart
            accessibilityLayer
            data={CHANGE}
            margin={{ top: 24, bottom: 8 }}
          >
            <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={10}
              tickFormatter={(value: string) => value.slice(0, 3)}
            />
            <ReferenceLine y={0} stroke="var(--border)" />
            <ChartTooltip
              cursor={false}
              content={
                <ChartTooltipContent
                  hideLabel
                  formatter={(value) => formatChange(value)}
                />
              }
            />
            {/* Rise and fall read by direction and the printed value. */}
            <Bar dataKey="change" fill="var(--color-change)" radius={6}>
              <LabelList
                dataKey="change"
                position="top"
                offset={8}
                className="fill-foreground"
                fontSize={12}
                formatter={formatChange}
              />
            </Bar>
          </BarChart>
        </ChartContainer>
      </CardContent>
    </Card>
  )
}

Installation

pnpm dlx shadcn add @01orbital/bar-chart-03
npx shadcn add @01orbital/bar-chart-03
yarn shadcn add @01orbital/bar-chart-03
bunx --bun shadcn add @01orbital/bar-chart-03

Free under the MIT license. Add the @01orbital registry to components.json once (install guide), then run the command.

It lands at components/blocks/charts/bar-chart-03/index.tsx, as source you own and edit.

Usage

import BarChart03 from "@/components/blocks/charts/bar-chart-03"

export default function Example() {
  return <BarChart03 />
}

Dependencies

npm: recharts@3.8.0. The CLI installs them for you.

Registry pieces it installs with it:

  • card
  • chart