Files
fitaiProto/apps/admin/src/components/charts/MembershipDistributionChart.tsx
T
dimitar 9d2bfda0ca crud
admin crud ops implemented partialy
2025-11-09 18:11:40 +01:00

103 lines
2.6 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,
fontSize: 18,
fontWeight: "bold",
},
data,
series: [
{
type: "pie",
calloutLabelKey: "label",
angleKey: "value",
sectorLabelKey: "label",
fills: data.map((item) => item.color || "#3b82f6"),
strokes: ["#ffffff"],
strokeWidth: 2,
calloutLabel: {
enabled: true,
fontSize: 12,
fontWeight: "bold",
},
sectorLabel: {
enabled: true,
fontSize: 14,
fontWeight: "bold",
color: "#ffffff",
formatter: (params: any) => {
const percentage = (
(params.datum.value /
data.reduce((sum, item) => sum + item.value, 0)) *
100
).toFixed(1);
return `${params.datum.label}: ${percentage}%`;
},
},
highlightStyle: {
item: {
fillOpacity: 0.8,
stroke: "#000000",
strokeWidth: 2,
},
},
tooltip: {
enabled: true,
renderer: (params: any) => {
const percentage = (
(params.datum.value /
data.reduce((sum, item) => sum + item.value, 0)) *
100
).toFixed(1);
return `<div class="bg-white p-2 rounded shadow-lg border">
<div class="font-bold">${params.datum.label}</div>
<div class="text-sm">Count: ${params.datum.value}</div>
<div class="text-sm">Percentage: ${percentage}%</div>
</div>`;
},
},
},
],
legend: {
enabled: true,
position: "right",
fontSize: 12,
marker: {
shape: "square",
size: 12,
},
},
padding: {
top: 20,
right: 20,
bottom: 20,
left: 20,
},
}),
[data, title],
);
return <AgCharts options={chartOptions} />;
}