footprint-explainable-ui 0.25.2 → 0.25.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -3631,6 +3631,18 @@ function centerForkParents(graph, options = {}) {
3631
3631
  }
3632
3632
  return minX <= maxX ? Math.max(minX, Math.min(maxX, desiredX)) : x0;
3633
3633
  };
3634
+ const evenFanKids = (forkCenter, kids) => {
3635
+ if (kids.length < 2) return;
3636
+ const sorted = [...kids].sort((a, b) => centerX(a) - centerX(b));
3637
+ let gap = 0;
3638
+ for (let i = 0; i < sorted.length - 1; i++) {
3639
+ gap = Math.max(gap, width.get(sorted[i]) / 2 + nodeSep + width.get(sorted[i + 1]) / 2);
3640
+ }
3641
+ const mid = (sorted.length - 1) / 2;
3642
+ for (let i = 0; i < sorted.length; i++) {
3643
+ workingX.set(sorted[i], forkCenter + (i - mid) * gap - width.get(sorted[i]) / 2);
3644
+ }
3645
+ };
3634
3646
  const order = [...graph.nodes].sort(
3635
3647
  (a, b) => b.position.y - a.position.y || a.position.x - b.position.x || a.id.localeCompare(b.id)
3636
3648
  );
@@ -3649,6 +3661,11 @@ function centerForkParents(graph, options = {}) {
3649
3661
  const wN = width.get(n.id);
3650
3662
  const span = (Math.min(...centers) + Math.max(...centers)) / 2;
3651
3663
  workingX.set(n.id, clampX(n.id, span - wN / 2));
3664
+ if (isFork) {
3665
+ const succSets = kin.map((k) => childrenOf.get(k) ?? []);
3666
+ const isDiamond = kin.length >= 2 && succSets[0].some((s) => succSets.every((ss) => ss.includes(s)));
3667
+ if (isDiamond) evenFanKids(centerX(n.id), kin);
3668
+ }
3652
3669
  const stepOf = isFork ? predsOf : childrenOf;
3653
3670
  let curId = n.id;
3654
3671
  const walked = /* @__PURE__ */ new Set([curId]);
@@ -3665,6 +3682,28 @@ function centerForkParents(graph, options = {}) {
3665
3682
  curId = m;
3666
3683
  }
3667
3684
  }
3685
+ for (const n of order) {
3686
+ const outD = outDegree.get(n.id) ?? 0;
3687
+ const inD = inDegree.get(n.id) ?? 0;
3688
+ if (!(outD >= 2 && inD <= 1)) continue;
3689
+ const kids = (childrenOf.get(n.id) ?? []).filter(
3690
+ (k) => byId.get(k)?.parentId === n.parentId
3691
+ );
3692
+ if (kids.length < 2) continue;
3693
+ const succSets = kids.map((k) => childrenOf.get(k) ?? []);
3694
+ const isDiamond = succSets[0].some((s) => succSets.every((ss) => ss.includes(s)));
3695
+ if (isDiamond) continue;
3696
+ const ps = predsOf.get(n.id);
3697
+ if (!ps || ps.length !== 1) continue;
3698
+ const pred = ps[0];
3699
+ if ((outDegree.get(pred) ?? 0) !== 1) continue;
3700
+ if (byId.get(pred)?.parentId !== byId.get(n.id)?.parentId) continue;
3701
+ const before = centerX(n.id);
3702
+ workingX.set(n.id, clampX(n.id, centerX(pred) - width.get(n.id) / 2));
3703
+ const delta = centerX(n.id) - before;
3704
+ if (delta === 0) continue;
3705
+ for (const k of kids) workingX.set(k, clampX(k, workingX.get(k) + delta));
3706
+ }
3668
3707
  const nodes = graph.nodes.map(
3669
3708
  (n) => workingX.get(n.id) === n.position.x ? n : { ...n, position: { x: workingX.get(n.id), y: n.position.y } }
3670
3709
  );