import React, { useEffect, useRef } from "react"; import * as d3 from "d3"; export default function DonutChart({ data }) { const ref = useRef(); const svgWidth = 600; const svgHeight = 600; const width = 400; const height = 400; const radius = Math.min(width, height) / 2; const innerRadius = radius * 0.6; const outerRadius = radius * 0.9; const hoverOuterRadius = outerRadius + 20; useEffect(() => { if (!data || data.length === 0) { return; } const totalOccurrences = data.reduce((acc, item) => acc + item.occurrences, 0); const minPercentage = 1; let otherData = { region: "Autres", occurrences: 0, details: [] }; let newData = data.filter(d => { let percentage = (d.occurrences / totalOccurrences) * 100; if (percentage < minPercentage) { otherData.occurrences += d.occurrences; otherData.details.push(`${d.region} (${percentage.toFixed(2)}%)`); return false; } return true; }); if (otherData.occurrences > 0) { newData.push(otherData); } const pieData = d3.pie().value(d => d.occurrences)(newData); const arc = d3.arc().innerRadius(innerRadius).outerRadius(outerRadius); const hoverArc = d3.arc().innerRadius(innerRadius).outerRadius(hoverOuterRadius); const svg = d3.select(ref.current) .attr("width", svgWidth) .attr("height", svgHeight) .append("g") .attr("transform", `translate(${svgWidth / 2}, ${svgHeight / 2})`); svg.selectAll("path") .data(pieData) .enter() .append("path") .attr("d", arc) .attr("fill", (d, i) => d3.schemeCategory10[i % 10]) .on("mouseover", function(event, d) { d3.select(this).transition().attr("d", hoverArc); if (d.data.region === "Autres") { svg.append("text") .attr("class", "details-text") .attr("x", 0) .attr("y", 0) .attr("text-anchor", "middle") .selectAll("tspan") .data(otherData.details) .enter() .append("tspan") .attr("x", 0) .attr("dy", "1.2em") .text(detail => detail); } else { const percentage = ((d.data.occurrences / totalOccurrences) * 100).toFixed(2); const text = `${d.data.region}: ${percentage}%`; svg.append("text") .attr("class", "tooltip") .attr("x", 0) .attr("y", 20) .attr("text-anchor", "middle") .text(text); } }) .on("mouseout", function() { d3.select(this).transition().attr("d", arc); svg.selectAll(".details-text").remove(); svg.selectAll(".tooltip").remove(); }); }, [data]); return ; }