# Chart 5

> A stacked bar chart visualizing monthly profit and loss amounts with interactive tooltips and custom striped indicators.

A shadcn/ui block from the [@pacekit](https://ui.pacekit.dev/?utm_source=shadcn.exchange) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/pacekit/dashboard-chart-5).

- Page, with a live preview: https://shadcn.exchange/r/pacekit/dashboard-chart-5
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/pacekit/dashboard-chart-5-light-6c84e7cce3570fa1.png
- Registry item: https://ui.pacekit.dev/r/dashboard-chart-5.json
- Listed: 2026-10-21, source last changed 2026-10-21

## Install

```bash
npx shadcn@latest add https://shadcn.exchange/r/pacekit/dashboard-chart-5.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`, `button`, `chart`, `dropdown-menu`

## Files

### `components/blocks/dashboard/chart/chart-5.tsx`

```tsx
import { useState } from "react";

import { ChevronDownIcon } from "lucide-react";
import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from "recharts";

import { Button } from "@/components/ui/button";
import { Card, CardAction, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { type ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart";
import {
    DropdownMenu,
    DropdownMenuContent,
    DropdownMenuItem,
    DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";

const chartData = [
    { month: "Jan", newSignups: 450, churned: 80 },
    { month: "Feb", newSignups: 520, churned: 95 },
    { month: "Mar", newSignups: 610, churned: 110 },
    { month: "Apr", newSignups: 580, churned: 90 },
    { month: "May", newSignups: 710, churned: 105 },
    { month: "Jun", newSignups: 800, churned: 120 },
    { month: "Jul", newSignups: 750, churned: 115 },
    { month: "Aug", newSignups: 820, churned: 130 },
    { month: "Sep", newSignups: 900, churned: 140 },
];

const chartConfig: ChartConfig = {
    newSignups: {
        label: "New Signups",
        color: "var(--chart-2)",
    },
    churned: {
        label: "Churned",
        color: "var(--chart-1)",
    },
};

const CustomBar = (props: any) => {
    const { x, y, width, height, fill } = props;
    if (height === undefined || height === null || height <= 0) {
        return null;
    }
    const gap = 4;
    const adjustedY = y + gap / 2;
    const adjustedHeight = Math.max(0, height - gap);
    return <rect x={x} y={adjustedY} width={width} height={adjustedHeight} rx={4} ry={4} fill={fill} />;
};

export const Chart5 = () => {
    const [range, setRange] = useState("This Year");

    return (
        <Card>
            <CardHeader className="flex flex-row items-center justify-between">
                <div className="flex flex-col gap-0.5">
                    <CardTitle className="text-lg font-medium tracking-tight">Customer Growth</CardTitle>
                    <CardDescription className="text-muted-foreground text-sm">
                        View new customer signups and churn over time
                    </CardDescription>
                </div>
                <CardAction>
                    <DropdownMenu>
                        <DropdownMenuTrigger
                            render={
                                <Button variant="outline" size="sm" className="gap-1.5">
                                    <span>{range}</span>
                                    <ChevronDownIcon className="size-3.5" />
                                </Button>
                            }
                        />
                        <DropdownMenuContent align="end" className="w-36">
                            <DropdownMenuItem onClick={() => setRange("This Year")}>This Year</DropdownMenuItem>
                            <DropdownMenuItem onClick={() => setRange("Last Year")}>Last Year</DropdownMenuItem>
                            <DropdownMenuItem onClick={() => setRange("All Time")}>All Time</DropdownMenuItem>
                        </DropdownMenuContent>
                    </DropdownMenu>
                </CardAction>
            </CardHeader>
            <CardContent className="ps-0 pe-5">
                <ChartContainer config={chartConfig} className="h-68 w-full">
                    <BarChart data={chartData}>
                        <defs fill="var(--color-newSignups)">
                            <pattern
                                id="signups-stripes"
                                width="8"
                                height="8"
                                patternUnits="userSpaceOnUse"
                                patternTransform="rotate(45)">
                                <rect width="8" height="8" fill="var(--color-newSignups)" />
                                <line x1="0" y1="0" x2="0" y2="8" stroke="oklch(1 0 0 / 25%)" strokeWidth="3" />
                            </pattern>
                        </defs>
                        <CartesianGrid vertical={false} strokeDasharray="3 3" />
                        <XAxis
                            dataKey="month"
                            tickLine={false}
                            axisLine={false}
                            tickMargin={10}
                            className="text-muted-foreground text-xs"
                        />
                        <YAxis
                            tickLine={false}
                            axisLine={false}
                            tickMargin={10}
                            ticks={[200, 400, 600, 800, 1000]}
                            domain={[0, 1100]}
                            tickFormatter={(value) => (value > 0 ? `${value}` : "")}
                            className="text-muted-foreground text-xs"
                        />
                        <ChartTooltip
                            cursor={false}
                            content={
                                <ChartTooltipContent
                                    labelFormatter={(value) => `Month: ${value}`}
                                    indicator="dot"
                                    className="rounded-md shadow-none"
                                />
                            }
                        />
                        <Bar
                            dataKey="churned"
                            stackId="a"
                            fill="var(--color-churned)"
                            shape={<CustomBar />}
                            maxBarSize={28}
                        />
                        <Bar
                            dataKey="newSignups"
                            stackId="a"
                            fill="url(#signups-stripes)"
                            shape={<CustomBar />}
                            maxBarSize={28}
                        />
                    </BarChart>
                </ChartContainer>
            </CardContent>
        </Card>
    );
};
```
