# Chart 02 - Earnings Pie Chart - Donut with Text

> A clean donut chart widget summarizing total earnings with source-wise breakdown, perfect for admin dashboards to compare revenue streams, monitor growth, and highlight performance insights.

A shadcn/ui block from the [@shadcn-space](https://shadcnspace.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/shadcn-space/chart-02).

- Page, with a live preview: https://shadcn.exchange/r/shadcn-space/chart-02
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/shadcn-space/chart-02-light-63675e366e6e783b.png
- Registry item: https://shadcnspace.com/r/chart-02.json
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://shadcnspace.com/r/chart-02.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- Registry items: `card`, `chart`, `badge`

## Files

### `src/components/shadcn-space/blocks/chart-02/page.tsx`

```tsx
import Chart from "@/components/shadcn-space/blocks/chart-02/chart";

export default function Page() {
    return (
        <div className="lg:py-20 sm:py-16 py-8 ">
            <Chart />
        </div>
    )
}
```

### `src/components/shadcn-space/blocks/chart-02/chart.tsx`

```tsx
"use client";


import { Label, Pie, PieChart } from "recharts"
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import {
    ChartConfig,
    ChartContainer,
    ChartTooltip,
    ChartTooltipContent,
} from "@/components/ui/chart"
import { cn } from "@/lib/utils";

const chartData = [
    { browser: "Website", visitors: 60, fill: "var(--color-blue-500)" },
    { browser: "Marketplace", visitors: 20, fill: "var(--color-sky-400)" },
    { browser: "Affiliate", visitors: 20, fill: "var(--color-sky-400)", fillOpacity: 0.5, },
]

const chartConfig = {
    visitors: {
        label: "Visitors",
    },
    Website: {
        label: "Website",
        color: "var(--color-blue-500)",
    },
    Marketplace: {
        label: "Marketplace",
        color: "var(--color-sky-400)",
    },
    Affiliate: {
        label: "Affiliate",
        color: "var(--color-sky-400)",

    },
} satisfies ChartConfig

export default function Chart02() {


    const CustomerSegmentation = [
        {
            id: 1,
            customer: "Website ",
            tagColor: "muted-foreground",
            borderColor: "bg-blue-500",
            badgeColor: "bg-teal-400/10",
            earning: 18356,
            growthPercentage: "+4.7%",
        },
        {
            id: 2,
            customer: "Marketplace",
            tagColor: "muted-foreground",
            borderColor: "bg-sky-400",
            badgeColor: "bg-teal-400/10",
            earning: 4590,
            growthPercentage: "+2.1%",
        },
        {
            id: 3,
            customer: "Affiliate",
            tagColor: "muted-foreground",
            borderColor: "bg-sky-400/50",
            badgeColor: "bg-teal-400/10",
            earning: 4385,
            growthPercentage: "-1.7%",
        },
    ];

    return (
        <Card className="h-full max-w-96 w-full mx-auto py-6 gap-6 shadow-xs">
            <CardHeader className="px-6">
                <CardTitle>
                    <h4 className="text-lg font-medium">Earning Reports</h4>
                </CardTitle>
            </CardHeader>
            <CardContent className="flex flex-col justify-between gap-8 flex-1 px-6">
                <ChartContainer config={chartConfig} className="aspect-square max-h-50">
                    <PieChart margin={{ top: -20}}>
                        <ChartTooltip
                            cursor={false}
                            content={<ChartTooltipContent hideLabel />}
                        />
                        <Pie
                            data={chartData}
                            dataKey="visitors"
                            nameKey="browser"
                            innerRadius={65}
                            strokeWidth={50}
                            startAngle={90}
                            endAngle={-270}
                        >
                            <Label
                                content={({ viewBox }) => {
                                    if (viewBox && "cx" in viewBox && "cy" in viewBox) {
                                        return (
                                            <text
                                                x={viewBox.cx}
                                                y={viewBox.cy}
                                                textAnchor="middle"
                                                dominantBaseline="middle"
                                            >
                                                <tspan
                                                    x={viewBox.cx}
                                                    y={(viewBox.cy || 0) - 10}
                                                    className="fill-muted-foreground text-sm"
                                                >
                                                    Total
                                                </tspan>
                                                <tspan
                                                    x={viewBox.cx}
                                                    y={(viewBox.cy || 0) + 15}
                                                    className="fill-foreground text-xl font-medium"
                                                >
                                                    $27,850
                                                </tspan>
                                            </text>
                                        )
                                    }
                                }}
                            />
                        </Pie>
                    </PieChart>
                </ChartContainer>
                <div className="flex flex-col gap-3">
                    {CustomerSegmentation.map((item) => (
                        <div key={item.id} className="flex items-center justify-between">
                            <div className="flex items-center gap-2">
                                <div className={cn(item.borderColor, "w-1 h-4 rounded-full")}></div>
                                <h6 className={cn("text-sm font-normal leading-tight")}>
                                    {item.customer}
                                </h6>
                            </div>
                            <div className="flex items-center gap-1.5">
                                <h6 className="text-sm font-medium">${item.earning}</h6>
                                <Badge
                                    className={cn(
                                        item.badgeColor,
                                        `text-${item.tagColor}`,
                                        "shadow-none"
                                    )}
                                >
                                    {item.growthPercentage}
                                </Badge>
                            </div>
                        </div>
                    ))}
                </div>
            </CardContent>
        </Card>
    );
}
```
