stats: anchor the donut center text on the pie's exact center

textAlign/textVerticalAlign make left/top the anchor point, so the
value+label block centers on (35%, 50%) geometrically instead of the
hand-tuned top offset that drifted with card size.
This commit is contained in:
MrAlders0n
2026-06-10 08:26:47 -04:00
parent 4d6d76e451
commit d1ff74cc1f
2 changed files with 8 additions and 2 deletions
+4 -1
View File
@@ -147,9 +147,12 @@ export function donutOption(
title: {
text: centerValue,
subtext: centerLabel,
// anchor the block's center exactly on the pie's center (35%, 50%) — textAlign/-VerticalAlign
// make left/top the anchor point instead of the block's top-left corner
left: "35%",
top: "39%",
top: "50%",
textAlign: "center",
textVerticalAlign: "middle",
itemGap: 2,
textStyle: { color: c.textBright, fontFamily: MONO, fontSize: 21, fontWeight: 700 },
subtextStyle: { color: c.textMuted, fontFamily: MONO, fontSize: 9 },
+4 -1
View File
@@ -57,8 +57,11 @@ describe("donutOption", () => {
// the old graphic-text approach anchored its left edge at the ring center and clipped
expect(opt.graphic).toBeUndefined();
expect(opt.title.textAlign).toBe("center");
expect(opt.title.textVerticalAlign).toBe("middle");
expect(opt.title.text).toBe("10");
expect(parseFloat(opt.title.left)).toBeCloseTo(parseFloat(opt.series[0].center[0]), 0);
// anchor must sit exactly on the pie's center point
expect(opt.title.left).toBe(opt.series[0].center[0]);
expect(opt.title.top).toBe(opt.series[0].center[1]);
});
});