Commits (2)
......@@ -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 <svg ref={ref}></svg>;
......
......@@ -19,8 +19,7 @@
margin: 20px;
}
.donut-container {
margin: 10px;
width: 90%;
width: 80rem;
}
.form-container {
display: flex;
......