diff --git a/node_modules/family-chart/dist/family-chart.esm.js b/node_modules/family-chart/dist/family-chart.esm.js index 3867be0..656fafa 100644 --- a/node_modules/family-chart/dist/family-chart.esm.js +++ b/node_modules/family-chart/dist/family-chart.esm.js @@ -10,10 +10,10 @@ function sortChildrenWithSpouses(children, datum, data) { const b_p2 = otherParent(b, datum, data); const a_i = a_p2 ? spouses.indexOf(a_p2.id) : -1; const b_i = b_p2 ? spouses.indexOf(b_p2.id) : -1; - if (datum.data.gender === "M") - return a_i - b_i; - else - return b_i - a_i; + // Provenance patch: order children by spouse order (ascending), gender- + // independent, so each couple's children sit next to the matching spouse + // in the centered-spouse layout (see setupSpouses). + return a_i - b_i; }); } function sortAddNewChildren(children) { @@ -701,20 +701,38 @@ function calculateTree(data, { main_id = null, node_separation = 250, level_sepa if (spouses.length > 0) { if (one_level_rels && d.depth > 0) continue; - const side = d.data.data.gender === "M" ? -1 : 1; // female on right - d.x += spouses.length / 2 * node_separation * side; + // Provenance patch: keep the person in the MIDDLE and split + // their spouses to alternating sides, then recenter the whole + // cluster on the person's slot, so each couple's children + // descend from between the correct pair instead of all + // spouses stacking on one side. Ordered by relationship order + // (spouse 1 on top, spouse 2 below, further spouses farther + // out) — NOT gender; children are sorted to match in + // sortChildrenWithSpouses. + const offsets = spouses.map((_sp, i) => { + const dir = i % 2 === 0 ? 1 : -1; + const dist = Math.floor(i / 2) + 1; // 1,1,2,2,3,3... + return -(node_separation * dist) * dir; + }); + // Mean of the person (offset 0) + every spouse, so the + // cluster stays centered on the person's original slot. + const center = offsets.reduce((a, b) => a + b, 0) / (offsets.length + 1); + const base_x = d.x; + d.x = base_x - center; spouses.forEach((sp_id, i) => { const spouse = { data: data_stash.find(d0 => d0.id === sp_id), added: true, depth: d.depth, spouse: d, - x: d.x - (node_separation * (i + 1)) * side, + x: base_x + offsets[i] - center, y: d.y, tid: `${d.data.id}-spouse-${i}`, }; - spouse.sx = i > 0 ? spouse.x : spouse.x + (node_separation / 2) * side; - spouse.sy = i > 0 ? spouse.y : spouse.y + (node_separation / 2) * side; + // Anchor links at the midpoint toward the person. + const toward = spouse.x < d.x ? 1 : -1; + spouse.sx = spouse.x + toward * (node_separation / 2); + spouse.sy = spouse.y; if (!d.spouses) d.spouses = []; d.spouses.push(spouse); @@ -1073,7 +1091,7 @@ function calculateTreeFit(svg_dim, tree_dim) { return { k, x, y }; } function cardToMiddle({ datum, svg, svg_dim, scale, transition_time }) { - const k = scale || 1, x = svg_dim.width / 2 - datum.x * k, y = svg_dim.height / 2 - datum.y, t = { k, x: x / k, y: y / k }; + const k = scale || 1, x = svg_dim.width / 2 - datum.x * k, y = svg_dim.height / 2 - datum.y * k, t = { k, x: x / k, y: y / k }; positionTree({ t, svg, transition_time }); } function manualZoom({ amount, svg, transition_time = 500 }) { diff --git a/node_modules/family-chart/dist/family-chart.js b/node_modules/family-chart/dist/family-chart.js index 1c750d4..edeb804 100644 --- a/node_modules/family-chart/dist/family-chart.js +++ b/node_modules/family-chart/dist/family-chart.js @@ -33,10 +33,9 @@ const b_p2 = otherParent(b, datum, data); const a_i = a_p2 ? spouses.indexOf(a_p2.id) : -1; const b_i = b_p2 ? spouses.indexOf(b_p2.id) : -1; - if (datum.data.gender === "M") - return a_i - b_i; - else - return b_i - a_i; + // Provenance patch: order children by spouse order (ascending), + // gender-independent, to match the centered-spouse layout. + return a_i - b_i; }); } function sortAddNewChildren(children) { @@ -724,20 +723,31 @@ if (spouses.length > 0) { if (one_level_rels && d.depth > 0) continue; - const side = d.data.data.gender === "M" ? -1 : 1; // female on right - d.x += spouses.length / 2 * node_separation * side; + // Provenance patch: keep the person in the MIDDLE and + // split spouses to alternating sides, recentered on the + // person's slot, so each couple's children descend from + // between the correct pair (see esm build for details). + const offsets = spouses.map((_sp, i) => { + const dir = i % 2 === 0 ? 1 : -1; + const dist = Math.floor(i / 2) + 1; + return -(node_separation * dist) * dir; + }); + const center = offsets.reduce((a, b) => a + b, 0) / (offsets.length + 1); + const base_x = d.x; + d.x = base_x - center; spouses.forEach((sp_id, i) => { const spouse = { data: data_stash.find(d0 => d0.id === sp_id), added: true, depth: d.depth, spouse: d, - x: d.x - (node_separation * (i + 1)) * side, + x: base_x + offsets[i] - center, y: d.y, tid: `${d.data.id}-spouse-${i}`, }; - spouse.sx = i > 0 ? spouse.x : spouse.x + (node_separation / 2) * side; - spouse.sy = i > 0 ? spouse.y : spouse.y + (node_separation / 2) * side; + const toward = spouse.x < d.x ? 1 : -1; + spouse.sx = spouse.x + toward * (node_separation / 2); + spouse.sy = spouse.y; if (!d.spouses) d.spouses = []; d.spouses.push(spouse); @@ -1096,7 +1106,7 @@ return { k, x, y }; } function cardToMiddle({ datum, svg, svg_dim, scale, transition_time }) { - const k = scale || 1, x = svg_dim.width / 2 - datum.x * k, y = svg_dim.height / 2 - datum.y, t = { k, x: x / k, y: y / k }; + const k = scale || 1, x = svg_dim.width / 2 - datum.x * k, y = svg_dim.height / 2 - datum.y * k, t = { k, x: x / k, y: y / k }; positionTree({ t, svg, transition_time }); } function manualZoom({ amount, svg, transition_time = 500 }) {