2025-10-23 12:11:41 +02:00

104 lines
2.5 KiB
TypeScript

'use client';
import { useMemo } from 'react';
import { Pie } from 'react-chartjs-2';
import {
Chart as ChartJS,
ArcElement,
Tooltip,
Legend,
ChartOptions,
ChartDataset
} from 'chart.js';
import type { DayCount } from './ChartBar';
import ChartDataLabels from 'chartjs-plugin-datalabels';
ChartJS.register(ArcElement, Tooltip, Legend, ChartDataLabels);
type ChartPieProps = {
data: DayCount[];
legend?: boolean;
};
export default function ChartPie({ data, legend = true }: ChartPieProps) {
const isDark =
typeof window !== 'undefined' &&
window.matchMedia('(prefers-color-scheme: dark)').matches;
const chartData = useMemo(() => {
const labels = data.map(d => d.date);
const series = data.map(d => d.count);
return {
labels,
datasets: [
{
label: 'Erkennungen',
data: series,
backgroundColor: [
'#3b82f6', '#6366f1', '#10b981', '#f59e0b', '#ef4444',
'#8b5cf6', '#ec4899', '#f97316', '#14b8a6', '#84cc16',
'#22d3ee', '#a78bfa', '#eab308', '#fb7185'
],
borderColor: isDark ? '#1f2937' : '#ffffff',
borderWidth: 1
}
]
};
}, [data, isDark]);
const options: ChartOptions<'pie'> = useMemo(() => ({
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: legend,
position: 'bottom',
labels: {
color: isDark ? '#a3a3a3' : '#4b5563'
}
},
tooltip: {
callbacks: {
label: (context) => {
const value = context.raw;
const label = context.label;
return `${label}: ${value} Erkennungen`;
}
}
},
datalabels: {
color: isDark ? '#d1d5db' : '#374151',
font: {
weight: 'bold' as const,
size: 12
},
anchor: 'end',
align: 'start',
offset: 6,
clamp: true,
display: (ctx) => {
const dataset = ctx.chart.data.datasets[0] as ChartDataset<'pie', number[]>;;
const total = dataset.data.reduce((sum: number, val: number) => sum + val, 0);
const value = dataset.data[ctx.dataIndex] as number;
return value / total >= 0.03;
}
},
layout: {
padding: 20
},
clip: false,
},
animation: {
animateRotate: true,
animateScale: true,
duration: 800,
easing: 'easeOutCubic'
}
}), [isDark, legend]);
return (
<Pie data={chartData} options={options} />
);
}