# Bar Chart Examples

> Complete bar chart layouts for category comparison and ranked values.

Source: https://www.honestui.com/docs/charts/bar-chart/blocks

These examples include the context around the plot, not only the chart component. The values are sample data. Open the Code tab and update data keys, labels, units, summaries, and accessible alternatives together.

## Clinic appointments [#clinic-appointments]

Use stacked bars when the total and each category's contribution both matter. Replace `week`, `booked`, and `walkIns`, then recalculate the busiest-period summary. Provide a table if readers need each weekly count.

### Clinic appointments

```tsx
"use client";

import { BarChart, type ChartConfig } from "honestui/charts";
import { cn } from "@/lib/utils";

// Scenario: Clinic appointments
const chartData = [
  { week: "W01", booked: 142, walkIns: 82 },
  { week: "W02", booked: 182, walkIns: 101 },
  { week: "W03", booked: 158, walkIns: 73 },
  { week: "W04", booked: 221, walkIns: 120 },
  { week: "W05", booked: 195, walkIns: 93 },
  { week: "W06", booked: 256, walkIns: 185 },
  { week: "W07", booked: 231, walkIns: 107 },
  { week: "W08", booked: 319, walkIns: 175 },
  { week: "W09", booked: 271, walkIns: 124 },
  { week: "W10", booked: 218, walkIns: 98 },
  { week: "W11", booked: 245, walkIns: 114 },
  { week: "W12", booked: 192, walkIns: 88 },
];

const chartConfig = {
  booked: { label: "Booked", colors: { light: ["#7c3aed"], dark: ["#a78bfa"] } },
  walkIns: { label: "Walk-ins", colors: { light: ["#0891b2"], dark: ["#22d3ee"] } },
} satisfies ChartConfig;

const LEGEND = [
  { key: "booked", label: "Booked", swatch: "bg-[#7c3aed] dark:bg-[#a78bfa]" },
  { key: "walkIns", label: "Walk-ins", swatch: "bg-[#0891b2] dark:bg-[#22d3ee]" },
];

const PEAK = chartData.reduce(
  (best, row) => (row.booked + row.walkIns > best.booked + best.walkIns ? row : best),
  chartData[0],
);
const PEAK_TOTAL = PEAK.booked + PEAK.walkIns;

export function PeakBarChart() {
  return (
    <div className="flex h-full w-full flex-col p-4">
      <div className="flex items-start justify-between gap-4">
        <div className="flex flex-col gap-1">
          <span className="text-muted-foreground text-xs">Busiest week</span>
          <div className="flex items-baseline gap-2">
            <span className="text-primary text-2xl font-semibold tracking-tight sm:text-3xl">
              {PEAK_TOTAL}
            </span>
            <span className="text-muted-foreground text-sm">appointments in {PEAK.week}</span>
          </div>
        </div>
        <div className="flex shrink-0 flex-col items-end gap-1.5 pt-1">
          {LEGEND.map(({ key, label, swatch }) => (
            <span
              key={key}
              className="text-muted-foreground flex items-center gap-2 text-[11px] sm:text-xs"
            >
              <span className={cn("size-2.5 shrink-0 rounded-[3px]", swatch)} />
              {label}
            </span>
          ))}
        </div>
      </div>

      <div className="mt-3 min-h-0 w-full flex-1">
        <BarChart
          data={chartData}
          config={chartConfig}
          xDataKey="week"
          className="h-full w-full"
          stackType="stacked"
          enableMaxValueHighlight
        >
          <BarChart.XAxis dataKey="week" hideDots />
          <BarChart.Tooltip />
          <BarChart.Bar dataKey="walkIns" radius={6} />
          <BarChart.Bar dataKey="booked" radius={6} />
        </BarChart>
      </div>
    </div>
  );
}

```

## Metro departures [#metro-departures]

Use this dense single-series layout for evenly spaced categories such as hours. Replace `hour` and `departures`, then update the total, peak, and unit labels. Test narrow screens because dense axis labels can become hard to read.

### Metro departures

```tsx
"use client";

import { BarChart, type ChartConfig } from "honestui/charts";

// Scenario: Metro departures
const chartData = [
  { hour: "00:00", departures: 47 },
  { hour: "01:00", departures: 31 },
  { hour: "02:00", departures: 21 },
  { hour: "03:00", departures: 16 },
  { hour: "04:00", departures: 13 },
  { hour: "05:00", departures: 20 },
  { hour: "06:00", departures: 38 },
  { hour: "07:00", departures: 73 },
  { hour: "08:00", departures: 109 },
  { hour: "09:00", departures: 138 },
  { hour: "10:00", departures: 163 },
  { hour: "11:00", departures: 181 },
  { hour: "12:00", departures: 175 },
  { hour: "13:00", departures: 190 },
  { hour: "14:00", departures: 206 },
  { hour: "15:00", departures: 193 },
  { hour: "16:00", departures: 169 },
  { hour: "17:00", departures: 153 },
  { hour: "18:00", departures: 132 },
  { hour: "19:00", departures: 107 },
  { hour: "20:00", departures: 93 },
  { hour: "21:00", departures: 79 },
  { hour: "22:00", departures: 64 },
  { hour: "23:00", departures: 52 },
];

const chartConfig = {
  departures: {
    label: "Departures",
    colors: {
      light: ["#18181b"],
      dark: ["#FFFFFF"],
    },
  },
} satisfies ChartConfig;

const TOTAL = chartData.reduce((sum, { departures }) => sum + departures, 0);
const PEAK = chartData.reduce(
  (max, row) => (row.departures > max.departures ? row : max),
  chartData[0],
);

export function GridBarChart() {
  return (
    <div className="flex h-full w-full flex-col p-4">
      <div className="flex flex-row justify-between">
        <div className="flex flex-row">
          <div className="flex flex-col gap-2">
            <span className="text-muted-foreground font-mono text-xs">{"[Σ] Total"}</span>
            <span className="text-primary font-mono text-3xl tracking-tighter">
              {TOTAL.toLocaleString()}
            </span>
          </div>
          <hr className="mx-4 h-full border-l border-dashed" />
          <div className="flex flex-col gap-2">
            <span className="text-muted-foreground font-mono text-xs">{"[⬆] Peak"}</span>
            <span className="text-primary font-mono text-3xl tracking-tighter">{PEAK.hour}</span>
          </div>
        </div>
        <div className="flex flex-col justify-end gap-1">
          <span className="text-muted-foreground font-mono text-[10px]">
            {"// CELL: "}
            <span className="text-primary">24H</span>
          </span>
          <span className="text-muted-foreground font-mono text-[10px]">
            {"// TYPE: "}
            <span className="text-primary">METRO</span>
          </span>
        </div>
      </div>

      <hr className="my-4 border-t border-dashed" />

      <div className="min-h-0 w-full flex-1">
        <BarChart
          data={chartData}
          config={chartConfig}
          xDataKey="hour"
          className="h-full w-full"
          barCategoryGap={14}
        >
          <BarChart.XAxis dataKey="hour" hideDots />
          <BarChart.Tooltip />
          <BarChart.Bar dataKey="departures" variant="blocks" />
        </BarChart>
      </div>
    </div>
  );
}

```

## Archive digitization [#archive-digitization]

Use this layout for one measured value across a short ordered sequence. Replace `month` and `scans`, then update the operational summary and unit. Make the highest or selected value available in text when it drives a decision.

### Archive digitization

```tsx
"use client";

import { BarChart, type ChartConfig } from "honestui/charts";

// Scenario: Archive digitization
const chartData = [
  { month: "Jan '24", scans: 380 },
  { month: "Feb '24", scans: 972 },
  { month: "Mar '24", scans: 568 },
  { month: "Apr '24", scans: 698 },
  { month: "May '24", scans: 508 },
  { month: "Jun '24", scans: 867 },
  { month: "Jul '24", scans: 437 },
  { month: "Aug '24", scans: 1027 },
  { month: "Sep '24", scans: 718 },
  { month: "Oct '24", scans: 591 },
  { month: "Nov '24", scans: 891 },
  { month: "Dec '24", scans: 301 },
  { month: "Jan '25", scans: 431 },
  { month: "Feb '25", scans: 1012 },
  { month: "Mar '25", scans: 626 },
  { month: "Apr '25", scans: 745 },
  { month: "May '25", scans: 554 },
  { month: "Jun '25", scans: 930 },
  { month: "Jul '25", scans: 474 },
  { month: "Aug '25", scans: 1074 },
  { month: "Sep '25", scans: 779 },
  { month: "Oct '25", scans: 649 },
  { month: "Nov '25", scans: 956 },
  { month: "Dec '25", scans: 349 },
];

const chartConfig = {
  scans: {
    label: "Scans",
    colors: {
      light: ["#18181b"],
      dark: ["#fafafa"],
    },
  },
} satisfies ChartConfig;

const TOTAL = chartData.reduce((sum, { scans }) => sum + scans, 0);
const TOP = chartData.reduce((max, row) => (row.scans > max.scans ? row : max), chartData[0]);

export function MonospaceBarChart() {
  return (
    <div className="flex h-full w-full flex-col p-4">
      <div className="flex flex-row justify-between">
        <div className="flex flex-row">
          <div className="flex flex-col gap-2">
            <span className="text-muted-foreground font-mono text-xs">{"[↗] Total Scans"}</span>
            <span className="text-primary font-mono text-3xl">
              <span className="text-muted-foreground text-sm font-normal">pages</span>
              <span className="tracking-tighter">{TOTAL.toLocaleString()}</span>
            </span>
          </div>
          <hr className="mx-4 h-full border-l border-dashed" />
          <div className="flex flex-col gap-2">
            <span className="text-muted-foreground font-mono text-xs">{"[⬆] Busiest Month"}</span>
            <span className="text-primary font-mono text-3xl tracking-tighter">{TOP.month}</span>
          </div>
        </div>
        <div className="flex flex-col justify-end gap-1">
          <span className="text-muted-foreground font-mono text-[10px]">
            {"// X-AXIS: "}
            <span className="text-primary">MONTHS</span>
          </span>
          <span className="text-muted-foreground font-mono text-[10px]">
            {"// Y-AXIS: "}
            <span className="text-primary">CHECKOUTS</span>
          </span>
        </div>
      </div>

      <hr className="my-4 border-t border-dashed" />

      <div className="min-h-0 w-full flex-1">
        <BarChart
          data={chartData}
          config={chartConfig}
          xDataKey="month"
          className="h-full w-full"
        >
          <BarChart.XAxis
            dataKey="month"
            tickFormatter={(value) => value.slice(0, 3)}
            hideDots
          />
          <BarChart.Bar dataKey="scans" variant="expandable" />
        </BarChart>
      </div>
    </div>
  );
}

```
