import { useList, useTranslate } from "@refinedev/core"; import { Card, theme } from "antd"; import { useMemo } from "react"; import { PieChart, Pie, Cell, ResponsiveContainer, Tooltip, Legend } from "recharts"; import { ISpool } from "../../spools/model"; const { useToken } = theme; // Color palette for the pie chart const COLORS = [ "#1890ff", // blue "#52c41a", // green "#faad14", // gold "#f5222d", // red "#722ed1", // purple "#13c2c2", // cyan "#eb2f96", // magenta "#fa8c16", // orange "#a0d911", // lime "#2f54eb", // geekblue ]; interface MaterialDistributionChartProps { square?: boolean; } export function MaterialDistributionChart({ square }: MaterialDistributionChartProps) { const t = useTranslate(); const { token } = useToken(); // Fetch all spools for aggregation const { result: spoolsResult, query: spoolsQuery } = useList({ resource: "spool", pagination: { pageSize: 1000 }, meta: { queryParams: { allow_archived: false, }, }, }); // Aggregate by material const chartData = useMemo(() => { const data = spoolsResult?.data || []; const materialCounts: Record = {}; data.forEach((spool) => { const material = spool.filament.material || t("unknown"); materialCounts[material] = (materialCounts[material] || 0) + 1; }); return Object.entries(materialCounts) .map(([name, value]) => ({ name, value })) .sort((a, b) => b.value - a.value) .slice(0, 10); // Top 10 materials }, [spoolsResult?.data, t]); if (spoolsQuery.isLoading || chartData.length === 0) { return null; } return ( `${name} (${((percent ?? 0) * 100).toFixed(0)}%)`} labelLine={square ? false : { stroke: token.colorTextSecondary }} > {chartData.map((_, index) => ( ))} [`${value} spools`, t("spool.spool")]} contentStyle={{ backgroundColor: token.colorBgElevated, border: `1px solid ${token.colorBorder}`, borderRadius: token.borderRadius, }} /> {square && ( )} ); }