Component

Bar Chart Stacked

Stacked bar chart comparing two data series with a legend. Ideal for showing part-to-whole relationships across time.

Usage

Use when you need to show both the total and the breakdown of each segment. Pair with a legend so both series are clearly labeled.

Playground

Preview
Bar Chart - Stacked + Legend
January - June 2024
Trending up by 5.2% this month
Showing total visitors for the last 6 months

Configure

Code

const chartData = [
  { month: "January", desktop: 186, mobile: 80 },
  { month: "February", desktop: 305, mobile: 200 },
  { month: "March", desktop: 237, mobile: 120 },
  { month: "April", desktop: 73, mobile: 190 },
  { month: "May", desktop: 209, mobile: 130 },
  { month: "June", desktop: 214, mobile: 140 },
]

const chartConfig = {
  desktop: { label: "Desktop", color: "var(--chart-1)" },
  mobile:  { label: "Mobile", color: "var(--chart-2)" },
} satisfies ChartConfig

<Card>
  <CardHeader>
    <CardTitle>Bar Chart - Stacked + Legend</CardTitle>
    <CardDescription>January - June 2024</CardDescription>
  </CardHeader>
  <CardContent>
    <ChartContainer config={chartConfig}>
      <BarChart accessibilityLayer data={chartData}>
        <defs>
          <pattern id="hatchMobile" patternUnits="userSpaceOnUse" width="6" height="6" patternTransform="rotate(45)">
            <rect width="6" height="6" fill="var(--color-mobile)" fillOpacity={0.15} />
            <line x1="0" y1="0" x2="0" y2="6" stroke="var(--color-mobile)" strokeWidth="2.5" />
          </pattern>
        </defs>
        <CartesianGrid vertical={false} />
        <XAxis
          dataKey="month"
          tickLine={false}
          tickMargin={10}
          axisLine={false}
          tickFormatter={(value) => value.slice(0, 3)}
        />
        <ChartTooltip content={<ChartTooltipContent hideLabel />} />
        <ChartLegend content={<ChartLegendContent />} />
        <Bar dataKey="desktop" stackId="a" fill="var(--color-desktop)" radius={[0, 0, 2, 2]} />
        <Bar dataKey="mobile"  stackId="a" fill="url(#hatchMobile)"    radius={[2, 2, 0, 0]} />
      </BarChart>
    </ChartContainer>
  </CardContent>
  <CardFooter className="flex-col items-start gap-2 text-sm">
    <div className="flex gap-2 leading-none font-medium">
      Trending up by 5.2% this month <TrendUp className="size-4" />
    </div>
    <div className="leading-none text-muted-foreground">
      Showing total visitors for the last 6 months
    </div>
  </CardFooter>
</Card>

Do

  • Always show a legend when using two or more series
  • Use chart-1 / chart-2 tokens to keep colors consistent across charts

Don't

  • Don't stack more than 3 series, the chart becomes unreadable
  • Don't use stacked bars when comparing individual series values is the primary goal, use a grouped bar instead