diff --git a/src/features/stats/chartOptions.ts b/src/features/stats/chartOptions.ts index dc56497..b1c6d05 100644 --- a/src/features/stats/chartOptions.ts +++ b/src/features/stats/chartOptions.ts @@ -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 }, diff --git a/tests/features/stats/chart-options.test.ts b/tests/features/stats/chart-options.test.ts index 5836a2b..9f56bcd 100644 --- a/tests/features/stats/chart-options.test.ts +++ b/tests/features/stats/chart-options.test.ts @@ -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]); }); });