ayo commit lagi
This commit is contained in:
@@ -26,6 +26,7 @@ export default function JenisPendaftaranPerAngkatanChart({ tahunAngkatan }: Prop
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [data, setData] = useState<JenisPendaftaranData[]>([]);
|
||||
const [series, setSeries] = useState<number[]>([]);
|
||||
const [chartColors, setChartColors] = useState<string[]>([]);
|
||||
const [options, setOptions] = useState<ApexOptions>({
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user