2025-07-31 17:41:54 +02:00

102 lines
1.8 KiB
TypeScript

'use client'
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
RadialLinearScale,
BarElement,
PointElement,
LineElement,
ArcElement,
Tooltip,
Legend,
Title,
} from 'chart.js'
import { Line, Bar, Radar, Doughnut, PolarArea, Bubble, Pie, Scatter } from 'react-chartjs-2'
import { useMemo } from 'react'
ChartJS.register(
CategoryScale,
LinearScale,
RadialLinearScale,
BarElement,
PointElement,
LineElement,
ArcElement,
Tooltip,
Legend,
Title
)
type ChartType = 'bar' | 'line' | 'pie' | 'doughnut' | 'radar'
type ChartProps = {
type: ChartType
labels: string[]
datasets: {
label: string
data: number[]
backgroundColor?: string | string[]
borderColor?: string
borderWidth?: number
}[]
title?: string
height?: number
hideLabels?: boolean
}
export default function Chart({
type,
labels,
datasets,
title,
height = 300,
hideLabels
}: ChartProps) {
const data = useMemo(() => ({ labels, datasets }), [labels, datasets])
const options = useMemo(
() => ({
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: !hideLabels,
position: 'top' as const,
},
title: {
display: !!title,
text: title,
},
},
scales: hideLabels
? {
x: { display: false },
y: { display: false },
}
: undefined,
}),
[title, hideLabels]
)
const chartMap = {
line: Line,
bar: Bar,
radar: Radar,
doughnut: Doughnut,
polararea: PolarArea,
bubble: Bubble,
pie: Pie,
scatter: Scatter,
}
const ChartComponent = chartMap[type]
return (
<div style={{ height }}>
<ChartComponent data={data} options={options} />
</div>
)
}