# Chart 3

> A dynamic chart tracking revenue trends and performance with interactive cursor details and tooltips.

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-3).

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

## Install

```bash
npx shadcn@latest add https://shadcn.exchange/r/pacekit/dashboard-chart-3.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-3.tsx`

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

import {
    ArrowDownToLineIcon,
    FileJsonIcon,
    MoreHorizontalIcon,
    RefreshCwIcon,
    SettingsIcon,
    Share2Icon,
} 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,
    DropdownMenuGroup,
    DropdownMenuItem,
    DropdownMenuLabel,
    DropdownMenuSeparator,
    DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";

const generateData = () => {
    return Array.from({ length: 20 }, (_, i) => {
        const date = new Date();
        date.setMonth(date.getMonth() - 1);
        date.setDate(date.getDate() + i);

        return {
            date: date.toISOString().split("T")[0],
            item1: Math.floor(Math.random() * 500) + 50,
            item2: Math.floor(Math.random() * 500) + 50,
        };
    });
};

const chartConfig: ChartConfig = {
    visitors: {
        label: "Visitors",
    },
    item1: {
        label: "Item 1",
        color: "var(--chart-2)",
    },
    item2: {
        label: "Item 2",
        color: "var(--chart-1)",
    },
};

export const Chart3 = () => {
    const [chartData, setChartData] = useState(generateData());

    const handleRefresh = () => {
        setChartData(generateData());
    };

    return (
        <Card className="@container/card max-md:py-4!">
            <CardHeader className="max-md:px-4">
                <CardTitle>Financial Performance</CardTitle>
                <CardDescription>Real-time insights for the last 30 days</CardDescription>
                <CardAction className="flex items-center gap-2">
                    <Button
                        variant="outline"
                        size="icon-sm"
                        className="max-sm:hidden"
                        aria-label="Refresh"
                        onClick={handleRefresh}>
                        <RefreshCwIcon />
                    </Button>
                    <Button variant="outline" size="icon-sm" className="max-sm:hidden" aria-label="Download">
                        <ArrowDownToLineIcon />
                    </Button>
                    <DropdownMenu>
                        <DropdownMenuTrigger
                            render={
                                <Button variant="outline" size="icon-sm">
                                    <MoreHorizontalIcon />
                                    <span className="sr-only">Open menu</span>
                                </Button>
                            }></DropdownMenuTrigger>
                        <DropdownMenuContent align="end" className="w-40">
                            <DropdownMenuGroup>
                                <DropdownMenuLabel>Options</DropdownMenuLabel>
                                <DropdownMenuItem>
                                    <SettingsIcon />
                                    <span>Configure</span>
                                </DropdownMenuItem>
                                <DropdownMenuItem onClick={handleRefresh}>
                                    <RefreshCwIcon />
                                    <span>Refresh Data</span>
                                </DropdownMenuItem>
                                <DropdownMenuSeparator />
                                <DropdownMenuItem>
                                    <ArrowDownToLineIcon />
                                    <span>Export as PNG</span>
                                </DropdownMenuItem>
                                <DropdownMenuItem>
                                    <FileJsonIcon />
                                    <span>Export CSV</span>
                                </DropdownMenuItem>
                                <DropdownMenuItem>
                                    <Share2Icon />
                                    <span>Share Chart</span>
                                </DropdownMenuItem>
                            </DropdownMenuGroup>
                        </DropdownMenuContent>
                    </DropdownMenu>
                </CardAction>
                <div className="mt-4 flex items-center gap-6">
                    <div className="space-y-1.5">
                        <p className="text-muted-foreground text-sm font-medium">Revenue</p>
                        <p className="text-lg leading-none font-semibold sm:text-2xl">$12,345</p>
                    </div>
                    <div className="bg-border h-10 w-px"></div>
                    <div className="space-y-1.5">
                        <p className="text-muted-foreground text-sm font-medium whitespace-nowrap">Avg. Order</p>
                        <p className="text-lg leading-none font-semibold sm:text-2xl">$248</p>
                    </div>
                    <div className="bg-border h-10 w-px max-sm:hidden"></div>
                    <div className="space-y-1.5 max-sm:hidden">
                        <p className="text-muted-foreground text-sm font-medium">Conversion</p>
                        <p className="text-lg leading-none font-semibold sm:text-2xl">+7.2%</p>
                    </div>
                </div>
            </CardHeader>
            <CardContent className="px-2 pt-4 sm:px-6 sm:pt-6">
                <ChartContainer config={chartConfig} className="aspect-auto h-65 w-full">
                    <BarChart data={chartData}>
                        <CartesianGrid vertical={false} />
                        <XAxis
                            dataKey="date"
                            tickLine={false}
                            axisLine={false}
                            tickMargin={8}
                            minTickGap={32}
                            tickFormatter={(value) => {
                                const date = new Date(value);
                                return date.toLocaleDateString("en-US", {
                                    month: "short",
                                    day: "numeric",
                                });
                            }}
                        />
                        <YAxis
                            tickLine={false}
                            axisLine={false}
                            tickMargin={4}
                            width={35}
                            className="text-sm sm:text-xs"
                            tickFormatter={(value) => `${value}`}
                        />
                        <ChartTooltip
                            cursor={false}
                            content={
                                <ChartTooltipContent
                                    className="rounded-md shadow-none"
                                    labelFormatter={(value) => {
                                        return new Date(value as any).toLocaleDateString("en-US", {
                                            month: "short",
                                            day: "numeric",
                                        });
                                    }}
                                    indicator="dot"
                                />
                            }
                        />
                        <Bar
                            dataKey="item1"
                            stackId="a"
                            fill="var(--color-item1)"
                            radius={6}
                            className="stroke-background"
                            strokeWidth={3}
                        />
                        <Bar
                            dataKey="item2"
                            stackId="a"
                            fill="var(--color-item2)"
                            radius={6}
                            className="stroke-background"
                            strokeWidth={3}
                        />
                    </BarChart>
                </ChartContainer>
            </CardContent>
        </Card>
    );
};
```
