diff --git a/components/chartsDashboard/DistribusiIPKChartPerangkatan.tsx b/components/chartsDashboard/DistribusiIPKChartPerangkatan.tsx index f87d6b3..4dfd340 100644 --- a/components/chartsDashboard/DistribusiIPKChartPerangkatan.tsx +++ b/components/chartsDashboard/DistribusiIPKChartPerangkatan.tsx @@ -81,9 +81,18 @@ export default function DistribusiIPKChartPerangkatan({ selectedYear }: Props) { fetchData(); }, [selectedYear]); + // Fixed color map consistent with bar chart (DistribusiIPKChart) + const KATEGORI_COLOR_MAP: { [key: string]: string } = { + 'Sangat Baik': '#008FFB', + 'Baik': '#00E396', + 'Cukup': '#FEB019', + 'Kurang': '#EF4444', + }; + // Prepare data for pie chart const series = data.map(item => item.jumlah); const labels = data.map(item => kategoriLabelsMap[item.kategori_ipk] || item.kategori_ipk); + const colors = data.map(item => KATEGORI_COLOR_MAP[item.kategori_ipk] || '#999999'); const chartOptions: ApexOptions = { chart: { @@ -122,12 +131,7 @@ export default function DistribusiIPKChartPerangkatan({ selectedYear }: Props) { return seriesName; } }, - colors: [ - '#008FFB', // Sangat Baik - Blue - '#00E396', // Baik - Green - '#FEB019', // Cukup - Orange - '#EF4444', // Kurang - Red - ], + colors: colors, tooltip: { theme: theme === 'dark' ? 'dark' : 'light', y: { diff --git a/components/chartsDashboard/NamaBeasiswaDashPieChartPerangkatan.tsx b/components/chartsDashboard/NamaBeasiswaDashPieChartPerangkatan.tsx index 7ceb69c..b8b3ac2 100644 --- a/components/chartsDashboard/NamaBeasiswaDashPieChartPerangkatan.tsx +++ b/components/chartsDashboard/NamaBeasiswaDashPieChartPerangkatan.tsx @@ -20,6 +20,7 @@ interface Props { export default function NamaBeasiswaDashPieChartPerangkatan({ selectedYear }: Props) { const { theme } = useTheme(); const [data, setData] = useState([]); + const [chartColors, setChartColors] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); @@ -43,6 +44,11 @@ export default function NamaBeasiswaDashPieChartPerangkatan({ selectedYear }: Pr throw new Error('Invalid data format received from server'); } + // Build global alphabetical list from all data (same order as bar chart) + const colorPalette = ['#3B82F6', '#EC4899', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6', '#06B6D4']; + const allBeasiswa: string[] = [...new Set((result as any[]).map((item: any) => item.nama_beasiswa as string))] + .sort(); + // Filter data for selected year and group by nama_beasiswa const yearData = result.filter((item: any) => item.tahun_angkatan.toString() === selectedYear @@ -55,14 +61,20 @@ export default function NamaBeasiswaDashPieChartPerangkatan({ selectedYear }: Pr return acc; }, {}); - // Convert to array format + // Convert to array format and sort by count descending (display order) const chartData = Object.entries(groupedData).map(([nama_beasiswa, jumlah_nama_beasiswa]) => ({ nama_beasiswa, jumlah_nama_beasiswa: jumlah_nama_beasiswa as number })); - - // Sort by jumlah_nama_beasiswa descending const sortedData = chartData.sort((a, b) => (b.jumlah_nama_beasiswa as number) - (a.jumlah_nama_beasiswa as number)); + + // Assign colors based on global alphabetical position to match bar chart + const computedColors = sortedData.map(item => { + const idx = allBeasiswa.indexOf(item.nama_beasiswa); + return idx >= 0 ? colorPalette[idx % colorPalette.length] : '#999999'; + }); + + setChartColors(computedColors); setData(sortedData); } catch (err) { console.error('Error in fetchData:', err); @@ -122,7 +134,7 @@ export default function NamaBeasiswaDashPieChartPerangkatan({ selectedYear }: Pr colors: theme === 'dark' ? '#fff' : '#000' } }, - colors: [ + colors: chartColors.length > 0 ? chartColors : [ '#3B82F6', // Blue '#EC4899', // Pink '#10B981', // Green diff --git a/components/chartsDashboard/kkdashboardpiechartperangkatan.tsx b/components/chartsDashboard/kkdashboardpiechartperangkatan.tsx index fa60456..6f68c55 100644 --- a/components/chartsDashboard/kkdashboardpiechartperangkatan.tsx +++ b/components/chartsDashboard/kkdashboardpiechartperangkatan.tsx @@ -20,6 +20,7 @@ interface Props { 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); @@ -27,14 +28,23 @@ export default function KelompokKeahlianPieChartPerAngkatan({ selectedYear }: Pr const fetchData = async () => { try { setLoading(true); - const response = await fetch( - `/api/mahasiswa/kk-dashboard?tahun_angkatan=${selectedYear}` - ); + + // 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'; @@ -42,14 +52,20 @@ export default function KelompokKeahlianPieChartPerAngkatan({ selectedYear }: Pr return acc; }, {}); - // Convert to array format + // 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 })); - - // Sort by jumlah_mahasiswa descending 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'); @@ -98,9 +114,7 @@ export default function KelompokKeahlianPieChartPerAngkatan({ selectedYear }: Pr colors: theme === 'dark' ? '#fff' : '#000' } }, - colors: [ - '#008FFB', '#00E396', '#FEB019', '#FF4560', '#775DD0', '#8B5CF6', '#EC4899', '#06B6D4', '#F97316' - ], + colors: chartColors, tooltip: { theme: theme === 'dark' ? 'dark' : 'light', y: {