'use client'; import { useEffect, useState } from 'react'; import dynamic from 'next/dynamic'; import { ApexOptions } from 'apexcharts'; import { useTheme } from 'next-themes'; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; const Chart = dynamic(() => import('react-apexcharts'), { ssr: false }); interface KelompokKeahlianPerAngkatanData { nama_kelompok: string; jumlah_mahasiswa: number; } interface Props { selectedYear: string; } export default function KelompokKeahlianPieChartPerAngkatan({ selectedYear }: Props) { const { theme } = useTheme(); const [data, setData] = useState([]); const [chartColors, setChartColors] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const fetchData = async () => { try { setLoading(true); // Fetch year-filtered data and global data in parallel const [response, allResponse] = await Promise.all([ fetch(`/api/mahasiswa/kk-dashboard?tahun_angkatan=${selectedYear}`), fetch('/api/mahasiswa/kk-dashboard'), ]); if (!response.ok) { throw new Error('Failed to fetch data'); } const result = await response.json(); const allResult = allResponse.ok ? await allResponse.json() : result; // Build global alphabetical list of kelompok (same order as bar chart) const colorPalette = ['#008FFB', '#00E396', '#FEB019', '#FF4560', '#775DD0', '#8B5CF6', '#EC4899', '#06B6D4', '#F97316']; const allKelompok: string[] = [...new Set((allResult as any[]).map((item: any) => item.nama_kelompok as string))] .sort((a, b) => a.localeCompare(b)); // Group by nama_kelompok and sum jumlah_mahasiswa const groupedData = result.reduce((acc: { [key: string]: number }, item: any) => { const namaKelompok = item.nama_kelompok || 'Tidak Diketahui'; acc[namaKelompok] = (acc[namaKelompok] || 0) + item.jumlah_mahasiswa; return acc; }, {}); // Convert to array format and sort by jumlah_mahasiswa descending (display order) const chartData = Object.entries(groupedData).map(([nama_kelompok, jumlah_mahasiswa]) => ({ nama_kelompok, jumlah_mahasiswa: jumlah_mahasiswa as number })); const sortedData = chartData.sort((a, b) => (b.jumlah_mahasiswa as number) - (a.jumlah_mahasiswa as number)); // Assign colors based on global alphabetical position to match bar chart const computedColors = sortedData.map(item => { const idx = allKelompok.indexOf(item.nama_kelompok); return idx >= 0 ? colorPalette[idx % colorPalette.length] : '#999999'; }); setChartColors(computedColors); setData(sortedData); } catch (err) { setError(err instanceof Error ? err.message : 'An error occurred'); } finally { setLoading(false); } }; fetchData(); }, [selectedYear]); // Prepare data for pie chart const series = data.map(item => item.jumlah_mahasiswa); const labels = data.map(item => item.nama_kelompok); const chartOptions: ApexOptions = { chart: { type: 'pie', toolbar: { show: true, }, background: theme === 'dark' ? '#0F172B' : '#fff', }, labels: labels, dataLabels: { enabled: true, formatter: function (val: number) { return `${val.toFixed(0)}%`; }, style: { fontSize: '14px', fontFamily: 'Inter, sans-serif', fontWeight: '500' } }, legend: { position: 'bottom', fontSize: '12px', markers: { size: 12, }, itemMargin: { horizontal: 10, vertical: 5, }, labels: { colors: theme === 'dark' ? '#fff' : '#000' } }, colors: chartColors, tooltip: { theme: theme === 'dark' ? 'dark' : 'light', y: { formatter: function (val: number) { return val + ' mahasiswa'; } } }, plotOptions: { pie: { donut: { size: '0%', }, offsetY: 0, }, }, states: { hover: { filter: { type: 'darken', }, }, }, }; if (loading) { return ( Loading... ); } if (error) { return ( Error: {error} ); } if (data.length === 0) { return ( Tidak ada data yang tersedia ); } return ( Persentase Jumlah Mahasiswa Berdasarkan Kelompok Keahlian {selectedYear !== 'all' ? ` Angkatan ${selectedYear}` : ''}
{typeof window !== 'undefined' && ( )}
); }