'use client' import { pie, arc } from "d3-shape"; import { useEffect, useMemo, useState } from "react"; import {taxes} from '@/data/taxes'; import { taxeStats } from "@/type/TaxeStats"; // Types simplifiés pour la clarté const years = [2018, 2019, 2020, 2021, 2022, 2023]; const COLORS = ["#2563eb", "#16a34a", "#ea580c", "#7c3aed", "#06b6d4", "#f43f5e"]; export default function PieChart() { const [taxe, setTaxe] = useState("cves"); const [selectedYear, setSelectedYear] = useState(2022); const [hoveredRegion, setHoveredRegion] = useState(null); const [isLoading, setIsLoading] = useState(false); const [data, setData] = useState([]); useEffect(() => { const fetchData = async () => { setIsLoading(true); try { const res = await fetch(`https://localhost/${taxe}/stats?annee=${selectedYear}&groupBy=region&metric=montant`); if (!res.ok) throw new Error("Erreur API"); const apiData = await res.json(); // CORRECTION : On s'assure que la clé correspond à "region" utilisée plus bas const formatted: taxeStats[] = apiData.member.map((d: any) => ({ region: d.label || d.region || "Inconnu", year: selectedYear, value: Number(d.value), })); setData(formatted); } catch (err) { console.error("Erreur fetch data:", err); setData([]); } finally { setIsLoading(false); } }; fetchData(); }, [taxe, selectedYear]); // 1. Préparation des données et calcul du total const { processedData, totalSum } = useMemo(() => { const sum = data.reduce((acc, curr) => acc + curr.value, 0); return { processedData: data, totalSum: sum }; }, [data]); // 2. Générateurs D3 const pieGenerator = pie() .value(d => d.value) .sort(null); // Garde l'ordre original const arcGenerator = arc() .innerRadius(120) // Transformé en Donut pour plus de modernité .outerRadius(240) .cornerRadius(4) .padAngle(0.02); const arcs = useMemo(() => pieGenerator(processedData), [processedData]); return (

Impôt collecté par région

{isLoading && Chargement...}
{arcs.map((d, i) => { const isActive = hoveredRegion === null || hoveredRegion.region === d.data.region; const percentage = ((d.data.value / totalSum) * 100).toFixed(1); return ( setHoveredRegion(d.data)} onMouseLeave={() => setHoveredRegion(null)} className="transition-all duration-300 cursor-pointer outline-none" /> ); })} {/* Centre du Diagramme */} {hoveredRegion && ( {hoveredRegion.region} {Math.round(hoveredRegion.value).toLocaleString()}€ {((hoveredRegion.value / totalSum) * 100).toFixed(1)}% )}
{arcs.map((d, i) => { const percentage = totalSum > 0 ? ((d.data.value / totalSum) * 100).toFixed(1) : 0; const isActive = hoveredRegion === null || hoveredRegion.region === d.data.region; return (
setHoveredRegion(d.data)} onMouseLeave={() => setHoveredRegion(null)} className={` flex items-center gap-2 p-2 rounded-md border transition-all ${isActive ? "bg-gray-50 shadow-sm scale-[1.02]" : "border-transparent opacity-50 grayscale-[0.5]" }`}>
{d.data.region}
{percentage}% {Math.round(d.data.value).toLocaleString()} €
); })}
); }