From 211fd9c9553655513a722effb10444eb2d43f182 Mon Sep 17 00:00:00 2001 From: Randa Firman Putra Date: Sun, 22 Feb 2026 00:21:37 +0700 Subject: [PATCH] ayo commit lagi --- .../JenisPendaftaranPerAngkatanChart.tsx | 34 +++++++++++--- components/charts/StatistikMahasiswaChart.tsx | 45 +++++-------------- .../charts/StatusMahasiswaFilterPieChart.tsx | 2 +- .../StatusMahasiswaPieChartPerangkatan.tsx | 17 ++++--- 4 files changed, 49 insertions(+), 49 deletions(-) diff --git a/components/charts/JenisPendaftaranPerAngkatanChart.tsx b/components/charts/JenisPendaftaranPerAngkatanChart.tsx index 0b126b6..67828fe 100644 --- a/components/charts/JenisPendaftaranPerAngkatanChart.tsx +++ b/components/charts/JenisPendaftaranPerAngkatanChart.tsx @@ -26,6 +26,7 @@ export default function JenisPendaftaranPerAngkatanChart({ tahunAngkatan }: Prop const [error, setError] = useState(null); const [data, setData] = useState([]); const [series, setSeries] = useState([]); + const [chartColors, setChartColors] = useState([]); const [options, setOptions] = useState({ chart: { type: 'pie', @@ -43,7 +44,7 @@ export default function JenisPendaftaranPerAngkatanChart({ tahunAngkatan }: Prop } }, labels: [], - colors: ['#3B82F6', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6', '#EC4899', '#06B6D4', '#F97316'], + colors: [], legend: { position: 'bottom', fontSize: '14px', @@ -101,9 +102,11 @@ export default function JenisPendaftaranPerAngkatanChart({ tahunAngkatan }: Prop tooltip: { ...prev.tooltip, theme: theme === 'dark' ? 'dark' : 'light' - } + }, + // Preserve computed colors across theme changes + colors: chartColors.length > 0 ? chartColors : prev.colors, })); - }, [theme]); + }, [theme, chartColors]); // Update dataLabels formatter when data changes useEffect(() => { @@ -141,29 +144,46 @@ export default function JenisPendaftaranPerAngkatanChart({ tahunAngkatan }: Prop setLoading(true); setError(null); - const response = await fetch(`/api/mahasiswa/jenis-pendaftaran?tahun_angkatan=${tahunAngkatan}`); + // Fetch year-filtered data and global data in parallel + const [response, allResponse] = await Promise.all([ + fetch(`/api/mahasiswa/jenis-pendaftaran?tahun_angkatan=${tahunAngkatan}`), + fetch('/api/mahasiswa/jenis-pendaftaran'), + ]); if (!response.ok) { throw new Error(`Failed to fetch data: ${response.status} ${response.statusText}`); } const result = await response.json(); + const allResult = allResponse.ok ? await allResponse.json() : result; if (!Array.isArray(result)) { throw new Error('Invalid data format received from server'); } + // Build global sorted jenis list (same order as bar chart) for stable color assignment + const colorPalette = ['#3B82F6', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6', '#EC4899', '#06B6D4', '#F97316']; + const allJenis: string[] = [...new Set((allResult as any[]).map(item => item.jenis_pendaftaran as string))].sort() as string[]; + // Process data for pie chart - const jenisPendaftaran = [...new Set(result.map(item => item.jenis_pendaftaran))].sort(); - const jumlahData = jenisPendaftaran.map(jenis => { - const item = result.find(d => d.jenis_pendaftaran === jenis); + const jenisPendaftaran = [...new Set(result.map(item => item.jenis_pendaftaran))].sort() as string[]; + const jumlahData = jenisPendaftaran.map((jenis: string) => { + const item = result.find((d: any) => d.jenis_pendaftaran === jenis); return item ? item.jumlah : 0; }); + // Assign colors based on global sorted position to match bar chart colors + const computedColors = jenisPendaftaran.map((jenis: string) => { + const idx = allJenis.indexOf(jenis); + return idx >= 0 ? colorPalette[idx % colorPalette.length] : '#999999'; + }); + + setChartColors(computedColors); setSeries(jumlahData); setOptions(prev => ({ ...prev, labels: jenisPendaftaran, + colors: computedColors, })); // Store processed data diff --git a/components/charts/StatistikMahasiswaChart.tsx b/components/charts/StatistikMahasiswaChart.tsx index f2920cd..4b17aa0 100644 --- a/components/charts/StatistikMahasiswaChart.tsx +++ b/components/charts/StatistikMahasiswaChart.tsx @@ -73,15 +73,10 @@ export default function StatistikMahasiswaChart({ const seriesIndex = opts.seriesIndex; const dataPointIndex = opts.dataPointIndex; - // Jika series Total (index 2), tampilkan angka - if (seriesIndex === 2) { - return val.toString(); - } - - // Untuk Laki-laki (index 0) dan Perempuan (index 1), hitung persentase - // Ambil data total dari series Total (index 2) - const totalSeriesData = opts.w.config.series[2]?.data || []; - const totalValue = totalSeriesData[dataPointIndex] || 0; + // Hitung total dari Laki-laki (index 0) dan Perempuan (index 1) + const lakiLakiData = opts.w.config.series[0]?.data || []; + const perempuanData = opts.w.config.series[1]?.data || []; + const totalValue = (lakiLakiData[dataPointIndex] || 0) + (perempuanData[dataPointIndex] || 0); if (totalValue === 0 || val === 0) return '0%'; @@ -97,7 +92,7 @@ export default function StatistikMahasiswaChart({ stroke: { show: true, width: 2, - colors: ['transparent', 'transparent', 'transparent'], + colors: ['transparent', 'transparent'], curve: 'straight' as const }, xaxis: { @@ -153,7 +148,7 @@ export default function StatistikMahasiswaChart({ colors: '#000' } }, - colors: ['#3B82F6', '#EC4899', '#10B981'], + colors: ['#3B82F6', '#EC4899'], tooltip: { theme: 'light', shared: true, @@ -161,7 +156,7 @@ export default function StatistikMahasiswaChart({ custom: function({ series, seriesIndex, dataPointIndex, w }: any) { const lakiLaki = series[0][dataPointIndex]; const perempuan = series[1][dataPointIndex]; - const total = series[2][dataPointIndex]; + const total = lakiLaki + perempuan; const tahun = w.globals.labels[dataPointIndex]; return ` @@ -199,7 +194,6 @@ export default function StatistikMahasiswaChart({ display: flex; align-items: center; "> -
Total ${total} @@ -248,18 +242,11 @@ export default function StatistikMahasiswaChart({ dataLabels: { ...prev.dataLabels, formatter: function (val: number, opts: any) { - const seriesIndex = opts.seriesIndex; const dataPointIndex = opts.dataPointIndex; - // Jika series Total (index 2), tampilkan angka - if (seriesIndex === 2) { - return val.toString(); - } - - // Untuk Laki-laki (index 0) dan Perempuan (index 1), hitung persentase - // Ambil data total dari series Total (index 2) - const totalSeriesData = opts.w.config.series[2]?.data || []; - const totalValue = totalSeriesData[dataPointIndex] || 0; + const lakiLakiData = opts.w.config.series[0]?.data || []; + const perempuanData = opts.w.config.series[1]?.data || []; + const totalValue = (lakiLakiData[dataPointIndex] || 0) + (perempuanData[dataPointIndex] || 0); if (totalValue === 0 || val === 0) return '0%'; @@ -320,13 +307,9 @@ export default function StatistikMahasiswaChart({ custom: function({ series, seriesIndex, dataPointIndex, w }: any) { const lakiLaki = series[0][dataPointIndex]; const perempuan = series[1][dataPointIndex]; - const total = series[2][dataPointIndex]; + const total = lakiLaki + perempuan; const tahun = w.globals.labels[dataPointIndex]; - const bgColor = currentTheme === 'dark' ? '#1e293b' : 'white'; - const textColor = currentTheme === 'dark' ? '#fff' : '#000'; - const borderColor = currentTheme === 'dark' ? '#475569' : '#ccc'; - const isDark = currentTheme === 'dark'; return ` @@ -364,7 +347,6 @@ export default function StatistikMahasiswaChart({ display: flex; align-items: center; "> -
Total ${total} @@ -404,11 +386,6 @@ export default function StatistikMahasiswaChart({ name: 'Perempuan', type: 'bar' as const, data: statistikData.map(item => item.wanita) - }, - { - name: 'Total', - type: 'bar' as const, - data: statistikData.map(item => item.total_mahasiswa) } ]; diff --git a/components/charts/StatusMahasiswaFilterPieChart.tsx b/components/charts/StatusMahasiswaFilterPieChart.tsx index 1c6b7c8..d3308d3 100644 --- a/components/charts/StatusMahasiswaFilterPieChart.tsx +++ b/components/charts/StatusMahasiswaFilterPieChart.tsx @@ -70,7 +70,7 @@ export default function StatusMahasiswaFilterPieChart({ selectedYear, selectedSt background: theme === 'dark' ? '#0F172B' : '#fff', }, labels: ['Laki-laki', 'Perempuan'], - colors: ['#3B82F6', '#EC4899'], + colors: ['#008FFB', '#EC4899'], legend: { position: 'bottom', fontSize: '14px', diff --git a/components/chartsDashboard/StatusMahasiswaPieChartPerangkatan.tsx b/components/chartsDashboard/StatusMahasiswaPieChartPerangkatan.tsx index d4b084e..832eaf5 100644 --- a/components/chartsDashboard/StatusMahasiswaPieChartPerangkatan.tsx +++ b/components/chartsDashboard/StatusMahasiswaPieChartPerangkatan.tsx @@ -65,9 +65,18 @@ export default function StatusMahasiswaPieChartPerangkatan({ selectedYear }: Pro fetchData(); }, [selectedYear]); + // Color mapping consistent with StatusMahasiswaChart bar chart + const STATUS_COLOR_MAP: { [key: string]: string } = { + 'Aktif': '#008FFB', + 'Lulus': '#00E396', + 'Cuti': '#FEB019', + 'Non Aktif': '#EF4444', + }; + // Prepare data for pie chart const series = data.map(item => item.jumlah); const labels = data.map(item => item.status_kuliah); + const colors = data.map(item => STATUS_COLOR_MAP[item.status_kuliah] || '#775DD0'); const chartOptions: ApexOptions = { chart: { @@ -103,13 +112,7 @@ export default function StatusMahasiswaPieChartPerangkatan({ selectedYear }: Pro colors: theme === 'dark' ? '#fff' : '#000' } }, - colors: [ - '#00E396', // Aktif - Green - '#008FFB', // Lulus - Blue - '#FEB019', // Cuti - Orange - '#FF4560', // Non-Aktif - Red - '#775DD0', // Lainnya - Purple - ], + colors: colors, tooltip: { theme: theme === 'dark' ? 'dark' : 'light', y: {