Move cardToMiddle vertical-centering fix into the family-chart patch

Fold the fly-to vertical-centering fix into our patch-package patch (alongside
the existing spouse-layout fix) instead of compensating in app code, and revert
the in-app workaround so the two don't double-correct.

- patches/family-chart+0.9.0.patch: cardToMiddle now scales datum.y by the zoom
  k in both dist builds (.js + .esm.js), matching datum.x. Verified the patch
  applies cleanly (patch-package --error-on-fail).
- tree/page.tsx: the cardToMiddle caller passes raw y again (the patched library
  does the scaling now); pre-scaling here too would double-correct. Behavior is
  identical to the previous in-app fix — both center the node exactly.
- CLAUDE.md: documents the two family-chart patches, how to regenerate them, and
  that both should be upstreamed. The cardToMiddle fix is submitted upstream
  (donatso/family-chart#103, issue #102); the spouse-layout fix is a TODO.

The frontend Dockerfile already COPYs patches/ before npm ci, so the fix is in
the production build.

Signed-off-by: Justin Paul <justin@jpaul.me>
This commit is contained in:
2026-06-11 09:21:30 -04:00
parent 3731d77d4b
commit e0573e6be2
3 changed files with 38 additions and 7 deletions
+5 -5
View File
@@ -315,12 +315,12 @@ export default function TreePage() {
try {
const rect = svg.getBoundingClientRect();
const scale = handlers.getCurrentZoom ? handlers.getCurrentZoom(svg).k : 1;
// family-chart's cardToMiddle scales datum.x by the zoom but NOT
// datum.y (a library bug), so vertical centering is only correct at
// scale 1 and drifts by datum.y·(k1) otherwise — landing "below the
// tree". Pre-multiply y by the scale to cancel the missing ·k.
// cardToMiddle centers the datum at the current zoom. (Its vertical
// centering at non-1 zoom is fixed in our family-chart patch — see
// CLAUDE.md / upstream PR donatso/family-chart#103 — so we pass the
// raw y; do NOT pre-scale it here or it double-corrects.)
handlers.cardToMiddle({
datum: { x: xy.x, y: xy.y * scale },
datum: xy,
svg,
svg_dim: { width: rect.width, height: rect.height },
scale,