Piechart is not rendering proportionally

3 weeks ago 20
ARTICLE AD BOX

Why your start and end points are reversed in the compute?

const start = polarToCartesian(cx, cy, r, endAngle); const end   = polarToCartesian(cx, cy, r, startAngle);

But you are drawing as "L", start.x, start.y, "A", ..., end.x, end.y

You avoid subtracting 90 here, and keep the <g rotate(-90 )> in SVG

function polarToCartesian(cx: number, cy: number, r: number, angleDeg: number) { // Kindly avoid subtracting 90 here. const rad = (angleDeg * Math.PI) / 180; return { x: cx + r * Math.cos(rad), y: cy + r * Math.sin(rad), }; } function describeArc( cx: number, cy: number, r: number, startAngle: number, endAngle: number ) { const s = ((startAngle % 360) + 360) % 360; const e = ((endAngle % 360) + 360) % 360; const start = polarToCartesian(cx, cy, r, s); const end = polarToCartesian(cx, cy, r, e); let angle = e - s; if (angle < 0) angle += 360; const largeArcFlag = angle > 180 ? "1" : "0"; const sweepFlag = "1"; // clockwise return [ "M", cx, cy, "L", start.x, start.y, "A", r, r, 0, largeArcFlag, sweepFlag, end.x, end.y, "Z", ].join(" "); }

Then, keep the clockwise accumulation and a single 90 degree correction in your renderer:

// Keep this rotate to start at 12, since polarToCartesian no longer subtracts 90 degree <g transform={`rotate(-90 ${cx} ${cy})`}> {visible.map((s, idx) => { const v = s.value || 0; const angle = (v / total) * 360; const end = start + angle; const d = describeArc(cx, cy, r, start, end); start = end; return <path key={idx} d={d} fill={s.color} />; })} </g>
Read Entire Article