From bcc04b5db962684108593e3949d97bf6b30d44e1 Mon Sep 17 00:00:00 2001 From: Hajar RAHMOUNI Date: Sun, 7 Jan 2024 12:05:57 +0100 Subject: [PATCH] lines for donut divisions added --- pwa/app/components/donut-chart/donut.jsx | 64 +++++++++++++----------- pwa/app/style/style.css | 3 +- 2 files changed, 37 insertions(+), 30 deletions(-) diff --git a/pwa/app/components/donut-chart/donut.jsx b/pwa/app/components/donut-chart/donut.jsx index b006fb0..3d01034 100644 --- a/pwa/app/components/donut-chart/donut.jsx +++ b/pwa/app/components/donut-chart/donut.jsx @@ -3,14 +3,15 @@ import * as d3 from "d3"; export default function DonutChart({ data }) { const ref = useRef(); - const svgWidth = 600; - const svgHeight = 600; + const svgWidth = 1100; + const svgHeight = 1000; 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; + const minPercentage = 1; // le seuil pour regrouper les petites divisions useEffect(() => { if (!data || data.length === 0) { @@ -18,9 +19,7 @@ export default function DonutChart({ data }) { } 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) { @@ -38,6 +37,7 @@ export default function DonutChart({ data }) { 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 labelArc = d3.arc().innerRadius(outerRadius + 30).outerRadius(outerRadius + 30); const svg = d3.select(ref.current) .attr("width", svgWidth) @@ -54,37 +54,45 @@ export default function DonutChart({ data }) { .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}%`; + let text = (d.data.region === "Autres") ? + otherData.details.join(", ") : + `${d.data.region}: ${((d.data.occurrences / totalOccurrences) * 100).toFixed(2)}%`; - svg.append("text") - .attr("class", "tooltip") - .attr("x", 0) - .attr("y", 20) - .attr("text-anchor", "middle") - .text(text); - } + const centroid = hoverArc.centroid(d); + svg.append("text") + .attr("class", "tooltip") + .attr("x", centroid[0]) + .attr("y", centroid[1]) + .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(); }); + // l'ajout des lignes et textes pour chaque division sauf pour autres + svg.selectAll(".label-line") + .data(pieData.filter(d => d.data.region !== "Autres")) + .enter() + .append("line") + .attr("x1", d => labelArc.centroid(d)[0]) + .attr("y1", d => labelArc.centroid(d)[1]) + .attr("x2", d => labelArc.centroid(d)[0] * 2) + .attr("y2", d => labelArc.centroid(d)[1] * 2) + .attr("stroke", "gray"); + + svg.selectAll(".label-text") + .data(pieData.filter(d => d.data.region !== "Autres")) + .enter() + .append("text") + .attr("transform", d => { + const [x, y] = labelArc.centroid(d); + return `translate(${x * 2}, ${y * 2})`; + }) + .attr("text-anchor", "middle") + .text(d => `${d.data.region}: ${((d.data.occurrences / totalOccurrences) * 100).toFixed(2)}%`); + }, [data]); return ; diff --git a/pwa/app/style/style.css b/pwa/app/style/style.css index ee81acf..e9e9f8f 100644 --- a/pwa/app/style/style.css +++ b/pwa/app/style/style.css @@ -19,8 +19,7 @@ margin: 20px; } .donut-container { - margin: 10px; - width: 90%; + width: 80rem; } .form-container { display: flex; -- GitLab