69 lines
1.7 KiB
TypeScript
69 lines
1.7 KiB
TypeScript
"use client";
|
|
|
|
import React, { useMemo } from "react";
|
|
import { AgCharts } from "ag-charts-react";
|
|
import { AgChartOptions } from "ag-charts-community";
|
|
|
|
interface PieData {
|
|
label: string;
|
|
value: number;
|
|
color?: string;
|
|
}
|
|
|
|
interface MembershipDistributionChartProps {
|
|
data: PieData[];
|
|
title?: string;
|
|
}
|
|
|
|
export function MembershipDistributionChart({
|
|
data,
|
|
title = "Membership Distribution",
|
|
}: MembershipDistributionChartProps) {
|
|
const chartOptions: AgChartOptions = useMemo(
|
|
() =>
|
|
({
|
|
title: {
|
|
text: title,
|
|
},
|
|
data,
|
|
series: [
|
|
{
|
|
type: "pie",
|
|
calloutLabelKey: "label",
|
|
angleKey: "value",
|
|
sectorLabelKey: "label",
|
|
fills: data.map((item) => item.color || "#3b82f6"),
|
|
calloutLabel: {
|
|
enabled: true,
|
|
},
|
|
sectorLabel: {
|
|
enabled: true,
|
|
color: "#ffffff",
|
|
formatter: (params: any) => {
|
|
const percentage = (
|
|
(params.datum.value /
|
|
data.reduce((sum, item) => sum + item.value, 0)) *
|
|
100
|
|
).toFixed(1);
|
|
return `${percentage}%`;
|
|
},
|
|
},
|
|
tooltip: {
|
|
renderer: (params: any) => ({
|
|
title: params.datum.label,
|
|
content: `${params.datum.value} (${((params.datum.value / data.reduce((sum, item) => sum + item.value, 0)) * 100).toFixed(1)}%)`,
|
|
}),
|
|
},
|
|
},
|
|
],
|
|
legend: {
|
|
enabled: true,
|
|
position: "right",
|
|
},
|
|
}) as any,
|
|
[data, title],
|
|
);
|
|
|
|
return <AgCharts options={chartOptions} />;
|
|
}
|