"use client"; import { useState } from "react"; import { Cell, Label, Pie, PieChart, Tooltip } from "recharts"; import { ChartConfig, ChartContainer } from "@/components/ui/chart/Chart"; import { ChartLegend } from "./shared/chart-legend"; import { DonutDataPoint } from "./types"; interface DonutChartProps { data: DonutDataPoint[]; height?: number; innerRadius?: number; outerRadius?: number; showLegend?: boolean; centerLabel?: { value: string | number; label: string; }; } const CustomTooltip = ({ active, payload }: any) => { if (!active || !payload || !payload.length) return null; const entry = payload[0]; const name = entry.name; const percentage = entry.payload?.percentage; const color = entry.color || entry.payload?.color; const change = entry.payload?.change; return (
{/* Title with color chip */}

{percentage}% {name}

{/* Change percentage row */} {change !== undefined && (

{change > 0 ? "+" : ""} {change}% Since last scan

)}
); }; const CustomLegend = ({ payload }: any) => { const items = payload.map((entry: any) => ({ label: `${entry.value} (${entry.payload.percentage}%)`, color: entry.color, })); return ; }; export function DonutChart({ data, innerRadius = 68, outerRadius = 86, showLegend = true, centerLabel, }: DonutChartProps) { const [hoveredIndex, setHoveredIndex] = useState(null); const chartConfig = data.reduce( (config, item) => ({ ...config, [item.name]: { label: item.name, color: item.color, }, }), {} as ChartConfig, ); const chartData = data.map((item) => ({ name: item.name, value: item.value, fill: item.color, color: item.color, percentage: item.percentage, change: item.change, })); const total = chartData.reduce((sum, d) => sum + (Number(d.value) || 0), 0); const isEmpty = total <= 0; const emptyData = [ { name: "No data", value: 1, fill: "var(--chart-border-emphasis)", color: "var(--chart-border-emphasis)", percentage: 0, change: undefined, }, ]; const legendPayload = (isEmpty ? emptyData : chartData).map((entry) => ({ value: isEmpty ? "No data" : entry.name, color: entry.color, payload: { percentage: isEmpty ? 0 : entry.percentage, }, })); return ( <> {!isEmpty && } />} {(isEmpty ? emptyData : chartData).map((entry, index) => { const opacity = hoveredIndex === null ? 1 : hoveredIndex === index ? 1 : 0.5; return ( setHoveredIndex(index)} onMouseLeave={() => setHoveredIndex(null)} /> ); })} {(centerLabel || isEmpty) && ( {showLegend && } ); }