footprint-explainable-ui 0.24.0 → 0.25.1
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/flowchart.cjs +290 -120
- package/dist/flowchart.cjs.map +1 -1
- package/dist/flowchart.d.cts +87 -13
- package/dist/flowchart.d.ts +87 -13
- package/dist/flowchart.js +226 -56
- package/dist/flowchart.js.map +1 -1
- package/dist/index.cjs +306 -83
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -16
- package/dist/index.d.ts +15 -16
- package/dist/index.js +234 -11
- package/dist/index.js.map +1 -1
- package/package.json +31 -12
package/dist/flowchart.js
CHANGED
|
@@ -490,7 +490,7 @@ var StageNode = memo(function StageNode2({
|
|
|
490
490
|
background: bg,
|
|
491
491
|
border: `${isHero ? "2.5px" : isMuted ? "1px" : "2px"} ${isLazyUnresolved ? "dashed" : "solid"} ${borderColor}`,
|
|
492
492
|
borderRadius: theme.radius,
|
|
493
|
-
padding: description ? `${Math.round(
|
|
493
|
+
padding: description ? `${Math.round(6 * sizeScale)}px ${Math.round(12 * sizeScale)}px` : `${Math.round(7 * sizeScale)}px ${Math.round(14 * sizeScale)}px`,
|
|
494
494
|
display: "flex",
|
|
495
495
|
flexDirection: "column",
|
|
496
496
|
alignItems: "center",
|
|
@@ -1464,6 +1464,14 @@ function staggeredBendY(sourceBottom, targetTop, others, minGapFromTarget = 8) {
|
|
|
1464
1464
|
if (lowestSkippedBottom === -Infinity) return null;
|
|
1465
1465
|
return Math.min((lowestSkippedBottom + targetTop) / 2, targetTop - minGapFromTarget);
|
|
1466
1466
|
}
|
|
1467
|
+
function forkFanBendY(sourceBottom, childTops, minGapFromTarget = 8) {
|
|
1468
|
+
if (childTops.length < 2) return null;
|
|
1469
|
+
const nearestTop = Math.min(...childTops);
|
|
1470
|
+
return Math.min((sourceBottom + nearestTop) / 2, nearestTop - minGapFromTarget);
|
|
1471
|
+
}
|
|
1472
|
+
function resolveStepBendY(forkBend, staggeredBend) {
|
|
1473
|
+
return staggeredBend ?? forkBend;
|
|
1474
|
+
}
|
|
1467
1475
|
|
|
1468
1476
|
// src/components/SmartStepEdge/SmartStepEdge.tsx
|
|
1469
1477
|
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
@@ -1486,6 +1494,16 @@ function SmartStepEdge({
|
|
|
1486
1494
|
if (!src || !tgt) return null;
|
|
1487
1495
|
const sourceBottom = src.internals.positionAbsolute.y + (src.measured.height ?? 0);
|
|
1488
1496
|
const targetTop = tgt.internals.positionAbsolute.y;
|
|
1497
|
+
const childTops = [];
|
|
1498
|
+
for (const e of s.edges) {
|
|
1499
|
+
if (e.source !== source) continue;
|
|
1500
|
+
if (e.data?.kind === "loop") continue;
|
|
1501
|
+
const c = s.nodeLookup.get(e.target);
|
|
1502
|
+
if (c && c.type !== GROUP_CONTAINER_NODE_TYPE) {
|
|
1503
|
+
childTops.push(c.internals.positionAbsolute.y);
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
const fan = forkFanBendY(sourceBottom, childTops);
|
|
1489
1507
|
const others = [];
|
|
1490
1508
|
for (const n of s.nodeLookup.values()) {
|
|
1491
1509
|
if (n.id === source || n.id === target) continue;
|
|
@@ -1493,7 +1511,8 @@ function SmartStepEdge({
|
|
|
1493
1511
|
const top = n.internals.positionAbsolute.y;
|
|
1494
1512
|
others.push({ top, bottom: top + (n.measured.height ?? 0) });
|
|
1495
1513
|
}
|
|
1496
|
-
|
|
1514
|
+
const staggered = staggeredBendY(sourceBottom, targetTop, others);
|
|
1515
|
+
return resolveStepBendY(fan, staggered);
|
|
1497
1516
|
});
|
|
1498
1517
|
const [path] = getSmoothStepPath({
|
|
1499
1518
|
sourceX,
|
|
@@ -1864,6 +1883,146 @@ import {
|
|
|
1864
1883
|
MarkerType as MarkerType2
|
|
1865
1884
|
} from "@xyflow/react";
|
|
1866
1885
|
|
|
1886
|
+
// src/components/FlowchartView/_internal/snapLinearSuccessors.ts
|
|
1887
|
+
function snapLinearSuccessors(graph, options = {}) {
|
|
1888
|
+
if (graph.nodes.length === 0) return graph;
|
|
1889
|
+
const fallbackW = options.nodeWidth ?? DEFAULT_NODE_W2;
|
|
1890
|
+
const fallbackH = options.nodeHeight ?? DEFAULT_NODE_H2;
|
|
1891
|
+
const byId = /* @__PURE__ */ new Map();
|
|
1892
|
+
const width = /* @__PURE__ */ new Map();
|
|
1893
|
+
for (const n of graph.nodes) {
|
|
1894
|
+
byId.set(n.id, n);
|
|
1895
|
+
width.set(n.id, sizeOf(n, fallbackW, fallbackH, options.nodeSize).width);
|
|
1896
|
+
}
|
|
1897
|
+
const preds = /* @__PURE__ */ new Map();
|
|
1898
|
+
const outDegree = /* @__PURE__ */ new Map();
|
|
1899
|
+
const seenEdge = /* @__PURE__ */ new Set();
|
|
1900
|
+
for (const e of graph.edges) {
|
|
1901
|
+
if (e.data?.kind === "loop") continue;
|
|
1902
|
+
if (!byId.has(e.source) || !byId.has(e.target)) continue;
|
|
1903
|
+
const key = `${e.source}\0${e.target}`;
|
|
1904
|
+
if (seenEdge.has(key)) continue;
|
|
1905
|
+
seenEdge.add(key);
|
|
1906
|
+
const list = preds.get(e.target);
|
|
1907
|
+
if (list) list.push(e.source);
|
|
1908
|
+
else preds.set(e.target, [e.source]);
|
|
1909
|
+
outDegree.set(e.source, (outDegree.get(e.source) ?? 0) + 1);
|
|
1910
|
+
}
|
|
1911
|
+
const workingX = /* @__PURE__ */ new Map();
|
|
1912
|
+
for (const n of graph.nodes) workingX.set(n.id, n.position.x);
|
|
1913
|
+
const centerX = (id) => workingX.get(id) + width.get(id) / 2;
|
|
1914
|
+
const order = [...graph.nodes].sort(
|
|
1915
|
+
(a, b) => a.position.y - b.position.y || a.position.x - b.position.x || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)
|
|
1916
|
+
);
|
|
1917
|
+
for (const n of order) {
|
|
1918
|
+
const p = preds.get(n.id);
|
|
1919
|
+
if (!p || p.length !== 1) continue;
|
|
1920
|
+
const pid = p[0];
|
|
1921
|
+
if ((outDegree.get(pid) ?? 0) !== 1) continue;
|
|
1922
|
+
const P = byId.get(pid);
|
|
1923
|
+
if ((n.parentId ?? void 0) !== (P.parentId ?? void 0)) continue;
|
|
1924
|
+
workingX.set(n.id, centerX(pid) - width.get(n.id) / 2);
|
|
1925
|
+
}
|
|
1926
|
+
const nodes = graph.nodes.map((n) => {
|
|
1927
|
+
const nx = workingX.get(n.id);
|
|
1928
|
+
return nx === n.position.x ? n : { ...n, position: { x: nx, y: n.position.y } };
|
|
1929
|
+
});
|
|
1930
|
+
return { nodes, edges: graph.edges };
|
|
1931
|
+
}
|
|
1932
|
+
function createSnappedDagreLayout(base, options = {}) {
|
|
1933
|
+
return (graph) => snapLinearSuccessors(base(graph), options);
|
|
1934
|
+
}
|
|
1935
|
+
|
|
1936
|
+
// src/components/FlowchartView/_internal/centerForkParents.ts
|
|
1937
|
+
function centerForkParents(graph, options = {}) {
|
|
1938
|
+
if (graph.nodes.length === 0) return graph;
|
|
1939
|
+
const fallbackW = options.nodeWidth ?? DEFAULT_NODE_W2;
|
|
1940
|
+
const fallbackH = options.nodeHeight ?? DEFAULT_NODE_H2;
|
|
1941
|
+
const byId = /* @__PURE__ */ new Map();
|
|
1942
|
+
const width = /* @__PURE__ */ new Map();
|
|
1943
|
+
for (const n of graph.nodes) {
|
|
1944
|
+
byId.set(n.id, n);
|
|
1945
|
+
width.set(n.id, sizeOf(n, fallbackW, fallbackH, options.nodeSize).width);
|
|
1946
|
+
}
|
|
1947
|
+
const childrenOf = /* @__PURE__ */ new Map();
|
|
1948
|
+
const predsOf = /* @__PURE__ */ new Map();
|
|
1949
|
+
const outDegree = /* @__PURE__ */ new Map();
|
|
1950
|
+
const inDegree = /* @__PURE__ */ new Map();
|
|
1951
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1952
|
+
for (const e of graph.edges) {
|
|
1953
|
+
if (e.data?.kind === "loop") continue;
|
|
1954
|
+
if (!byId.has(e.source) || !byId.has(e.target)) continue;
|
|
1955
|
+
const key = `${e.source} ${e.target}`;
|
|
1956
|
+
if (seen.has(key)) continue;
|
|
1957
|
+
seen.add(key);
|
|
1958
|
+
const cl = childrenOf.get(e.source);
|
|
1959
|
+
if (cl) cl.push(e.target);
|
|
1960
|
+
else childrenOf.set(e.source, [e.target]);
|
|
1961
|
+
const pl = predsOf.get(e.target);
|
|
1962
|
+
if (pl) pl.push(e.source);
|
|
1963
|
+
else predsOf.set(e.target, [e.source]);
|
|
1964
|
+
outDegree.set(e.source, (outDegree.get(e.source) ?? 0) + 1);
|
|
1965
|
+
inDegree.set(e.target, (inDegree.get(e.target) ?? 0) + 1);
|
|
1966
|
+
}
|
|
1967
|
+
const workingX = /* @__PURE__ */ new Map();
|
|
1968
|
+
for (const n of graph.nodes) workingX.set(n.id, n.position.x);
|
|
1969
|
+
const centerX = (id) => workingX.get(id) + width.get(id) / 2;
|
|
1970
|
+
const nodeSep = options.nodeSep ?? 60;
|
|
1971
|
+
const clampX = (id, desiredX) => {
|
|
1972
|
+
const w = width.get(id);
|
|
1973
|
+
const x0 = workingX.get(id);
|
|
1974
|
+
const self = byId.get(id);
|
|
1975
|
+
let minX = -Infinity;
|
|
1976
|
+
let maxX = Infinity;
|
|
1977
|
+
for (const m of graph.nodes) {
|
|
1978
|
+
if (m.id === id || m.parentId !== self.parentId) continue;
|
|
1979
|
+
if (Math.abs(m.position.y - self.position.y) > 1) continue;
|
|
1980
|
+
const mLeft = workingX.get(m.id);
|
|
1981
|
+
const mRight = mLeft + width.get(m.id);
|
|
1982
|
+
if (mRight <= x0) minX = Math.max(minX, mRight + nodeSep);
|
|
1983
|
+
else if (mLeft >= x0 + w) maxX = Math.min(maxX, mLeft - nodeSep - w);
|
|
1984
|
+
}
|
|
1985
|
+
return minX <= maxX ? Math.max(minX, Math.min(maxX, desiredX)) : x0;
|
|
1986
|
+
};
|
|
1987
|
+
const order = [...graph.nodes].sort(
|
|
1988
|
+
(a, b) => b.position.y - a.position.y || a.position.x - b.position.x || a.id.localeCompare(b.id)
|
|
1989
|
+
);
|
|
1990
|
+
for (const n of order) {
|
|
1991
|
+
if ((outDegree.get(n.id) ?? 0) < 2) continue;
|
|
1992
|
+
if ((inDegree.get(n.id) ?? 0) > 1) continue;
|
|
1993
|
+
const kids = (childrenOf.get(n.id) ?? []).filter(
|
|
1994
|
+
(k) => byId.get(k)?.parentId === n.parentId
|
|
1995
|
+
// same compound only
|
|
1996
|
+
);
|
|
1997
|
+
if (kids.length < 2) continue;
|
|
1998
|
+
const centers = kids.map(centerX);
|
|
1999
|
+
const wN = width.get(n.id);
|
|
2000
|
+
const span = (Math.min(...centers) + Math.max(...centers)) / 2;
|
|
2001
|
+
workingX.set(n.id, clampX(n.id, span - wN / 2));
|
|
2002
|
+
let curId = n.id;
|
|
2003
|
+
const walked = /* @__PURE__ */ new Set([curId]);
|
|
2004
|
+
for (; ; ) {
|
|
2005
|
+
const ps = predsOf.get(curId);
|
|
2006
|
+
if (!ps || ps.length !== 1) break;
|
|
2007
|
+
const p = ps[0];
|
|
2008
|
+
if (walked.has(p)) break;
|
|
2009
|
+
if ((outDegree.get(p) ?? 0) !== 1) break;
|
|
2010
|
+
if ((inDegree.get(p) ?? 0) > 1) break;
|
|
2011
|
+
if (byId.get(p)?.parentId !== byId.get(curId)?.parentId) break;
|
|
2012
|
+
workingX.set(p, clampX(p, centerX(curId) - width.get(p) / 2));
|
|
2013
|
+
walked.add(p);
|
|
2014
|
+
curId = p;
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
const nodes = graph.nodes.map(
|
|
2018
|
+
(n) => workingX.get(n.id) === n.position.x ? n : { ...n, position: { x: workingX.get(n.id), y: n.position.y } }
|
|
2019
|
+
);
|
|
2020
|
+
return { nodes, edges: graph.edges };
|
|
2021
|
+
}
|
|
2022
|
+
function withForkCentering(base, options = {}) {
|
|
2023
|
+
return (graph) => centerForkParents(base(graph), options);
|
|
2024
|
+
}
|
|
2025
|
+
|
|
1867
2026
|
// src/components/FlowchartView/_internal/devWarn.ts
|
|
1868
2027
|
function isDevModeEnv() {
|
|
1869
2028
|
const proc = globalThis.process;
|
|
@@ -2231,6 +2390,49 @@ function GroupContainerNode({ data }) {
|
|
|
2231
2390
|
);
|
|
2232
2391
|
}
|
|
2233
2392
|
|
|
2393
|
+
// src/components/FlowchartView/_internal/MeasuredNodeSizes.tsx
|
|
2394
|
+
import { useEffect as useEffect6 } from "react";
|
|
2395
|
+
import { useNodesInitialized, useStore as useStore3 } from "@xyflow/react";
|
|
2396
|
+
|
|
2397
|
+
// src/components/FlowchartView/_internal/measuredFootprints.ts
|
|
2398
|
+
function extractMeasuredFootprints(entries) {
|
|
2399
|
+
const sizes = /* @__PURE__ */ new Map();
|
|
2400
|
+
for (const [id, node] of entries) {
|
|
2401
|
+
const width = node.measured?.width;
|
|
2402
|
+
const height = node.measured?.height;
|
|
2403
|
+
if (typeof width === "number" && typeof height === "number" && width > 0 && height > 0) {
|
|
2404
|
+
sizes.set(id, { width: Math.round(width), height: Math.round(height) });
|
|
2405
|
+
}
|
|
2406
|
+
}
|
|
2407
|
+
return sizes;
|
|
2408
|
+
}
|
|
2409
|
+
function sameFootprints(a, b) {
|
|
2410
|
+
if (a === b) return true;
|
|
2411
|
+
if (a.size !== b.size) return false;
|
|
2412
|
+
for (const [id, s] of a) {
|
|
2413
|
+
const t = b.get(id);
|
|
2414
|
+
if (!t || t.width !== s.width || t.height !== s.height) return false;
|
|
2415
|
+
}
|
|
2416
|
+
return true;
|
|
2417
|
+
}
|
|
2418
|
+
|
|
2419
|
+
// src/components/FlowchartView/_internal/MeasuredNodeSizes.tsx
|
|
2420
|
+
function MeasuredNodeSizes({
|
|
2421
|
+
onSizes,
|
|
2422
|
+
includeHiddenNodes = false
|
|
2423
|
+
}) {
|
|
2424
|
+
const initialized = useNodesInitialized({ includeHiddenNodes });
|
|
2425
|
+
const sizes = useStore3(
|
|
2426
|
+
(s) => extractMeasuredFootprints(s.nodeLookup),
|
|
2427
|
+
sameFootprints
|
|
2428
|
+
);
|
|
2429
|
+
useEffect6(() => {
|
|
2430
|
+
if (!initialized || sizes.size === 0) return;
|
|
2431
|
+
onSizes(sizes);
|
|
2432
|
+
}, [initialized, sizes, onSizes]);
|
|
2433
|
+
return null;
|
|
2434
|
+
}
|
|
2435
|
+
|
|
2234
2436
|
// src/components/FlowchartView/TracedFlow.tsx
|
|
2235
2437
|
import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2236
2438
|
var DEFAULT_COLORS = {
|
|
@@ -2403,8 +2605,19 @@ function TracedFlow({
|
|
|
2403
2605
|
() => buildSubflowBreadcrumb(graph, drill.currentSubflowId),
|
|
2404
2606
|
[graph, drill.currentSubflowId]
|
|
2405
2607
|
);
|
|
2608
|
+
const [measuredSizes, setMeasuredSizes] = useState4(null);
|
|
2406
2609
|
const positioned = useMemo5(() => {
|
|
2407
|
-
const
|
|
2610
|
+
const nodeSize = measuredSizes ? (n) => measuredSizes.get(n.id) : void 0;
|
|
2611
|
+
const sizeOpts = nodeSize ? { nodeSize } : {};
|
|
2612
|
+
const dagreBase = withForkCentering(
|
|
2613
|
+
createSnappedDagreLayout(
|
|
2614
|
+
createDagreTraceLayout({ ...sizeOpts, rankSep: 52, nodeSep: 36 }),
|
|
2615
|
+
sizeOpts
|
|
2616
|
+
),
|
|
2617
|
+
{ ...sizeOpts, nodeSep: 36 }
|
|
2618
|
+
// same nodeSep → clamp preserves dagre's reserved gap
|
|
2619
|
+
);
|
|
2620
|
+
const realBase = layout === "passthrough" ? (g) => g : layoutProp === void 0 ? dagreBase : layout;
|
|
2408
2621
|
if (groupedSet.size > 0) {
|
|
2409
2622
|
const grouped = applyGroupLayout(filteredGraph, {
|
|
2410
2623
|
groupedSubflowIds: [...groupedSet],
|
|
@@ -2415,8 +2628,8 @@ function TracedFlow({
|
|
|
2415
2628
|
if (mainChartBox) {
|
|
2416
2629
|
return wrapInMainChartBox(filteredGraph, { baseLayout: realBase, ...mainChartBox });
|
|
2417
2630
|
}
|
|
2418
|
-
return
|
|
2419
|
-
}, [filteredGraph, layout, groupedSet, mainChartBox]);
|
|
2631
|
+
return realBase(filteredGraph);
|
|
2632
|
+
}, [filteredGraph, layout, layoutProp, groupedSet, mainChartBox, measuredSizes]);
|
|
2420
2633
|
const slice = useMemo5(() => {
|
|
2421
2634
|
const empty = {
|
|
2422
2635
|
doneStageIds: /* @__PURE__ */ new Set(),
|
|
@@ -2460,7 +2673,11 @@ function TracedFlow({
|
|
|
2460
2673
|
);
|
|
2461
2674
|
const wrapperRef = useRef5(null);
|
|
2462
2675
|
const [rfInstance, setRfInstance] = useState4(null);
|
|
2463
|
-
useChartAutoRefit(wrapperRef, rfInstance, {
|
|
2676
|
+
useChartAutoRefit(wrapperRef, rfInstance, {
|
|
2677
|
+
// Re-fit on drill AND after the measured-size re-layout settles.
|
|
2678
|
+
refitKey: `${drill.currentSubflowId ?? ""}:${measuredSizes ? "measured" : "estimated"}`,
|
|
2679
|
+
padding: 0.18
|
|
2680
|
+
});
|
|
2464
2681
|
return /* @__PURE__ */ jsxs8(
|
|
2465
2682
|
"div",
|
|
2466
2683
|
{
|
|
@@ -2492,8 +2709,11 @@ function TracedFlow({
|
|
|
2492
2709
|
onNodeClick: handleNodeClick,
|
|
2493
2710
|
onInit: setRfInstance,
|
|
2494
2711
|
fitView: true,
|
|
2712
|
+
fitViewOptions: { padding: 0.18 },
|
|
2713
|
+
minZoom: 0.1,
|
|
2495
2714
|
proOptions: { hideAttribution: true },
|
|
2496
2715
|
children: [
|
|
2716
|
+
/* @__PURE__ */ jsx11(MeasuredNodeSizes, { onSizes: setMeasuredSizes }),
|
|
2497
2717
|
/* @__PURE__ */ jsx11(Background2, { variant: BackgroundVariant2.Dots, gap: 20, size: 1 }),
|
|
2498
2718
|
children
|
|
2499
2719
|
]
|
|
@@ -3508,56 +3728,6 @@ function SlotPillNode({ data }) {
|
|
|
3508
3728
|
);
|
|
3509
3729
|
}
|
|
3510
3730
|
|
|
3511
|
-
// src/components/FlowchartView/_internal/snapLinearSuccessors.ts
|
|
3512
|
-
function snapLinearSuccessors(graph, options = {}) {
|
|
3513
|
-
if (graph.nodes.length === 0) return graph;
|
|
3514
|
-
const fallbackW = options.nodeWidth ?? DEFAULT_NODE_W2;
|
|
3515
|
-
const fallbackH = options.nodeHeight ?? DEFAULT_NODE_H2;
|
|
3516
|
-
const byId = /* @__PURE__ */ new Map();
|
|
3517
|
-
const width = /* @__PURE__ */ new Map();
|
|
3518
|
-
for (const n of graph.nodes) {
|
|
3519
|
-
byId.set(n.id, n);
|
|
3520
|
-
width.set(n.id, sizeOf(n, fallbackW, fallbackH, options.nodeSize).width);
|
|
3521
|
-
}
|
|
3522
|
-
const preds = /* @__PURE__ */ new Map();
|
|
3523
|
-
const outDegree = /* @__PURE__ */ new Map();
|
|
3524
|
-
const seenEdge = /* @__PURE__ */ new Set();
|
|
3525
|
-
for (const e of graph.edges) {
|
|
3526
|
-
if (e.data?.kind === "loop") continue;
|
|
3527
|
-
if (!byId.has(e.source) || !byId.has(e.target)) continue;
|
|
3528
|
-
const key = `${e.source}\0${e.target}`;
|
|
3529
|
-
if (seenEdge.has(key)) continue;
|
|
3530
|
-
seenEdge.add(key);
|
|
3531
|
-
const list = preds.get(e.target);
|
|
3532
|
-
if (list) list.push(e.source);
|
|
3533
|
-
else preds.set(e.target, [e.source]);
|
|
3534
|
-
outDegree.set(e.source, (outDegree.get(e.source) ?? 0) + 1);
|
|
3535
|
-
}
|
|
3536
|
-
const workingX = /* @__PURE__ */ new Map();
|
|
3537
|
-
for (const n of graph.nodes) workingX.set(n.id, n.position.x);
|
|
3538
|
-
const centerX = (id) => workingX.get(id) + width.get(id) / 2;
|
|
3539
|
-
const order = [...graph.nodes].sort(
|
|
3540
|
-
(a, b) => a.position.y - b.position.y || a.position.x - b.position.x || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)
|
|
3541
|
-
);
|
|
3542
|
-
for (const n of order) {
|
|
3543
|
-
const p = preds.get(n.id);
|
|
3544
|
-
if (!p || p.length !== 1) continue;
|
|
3545
|
-
const pid = p[0];
|
|
3546
|
-
if ((outDegree.get(pid) ?? 0) !== 1) continue;
|
|
3547
|
-
const P = byId.get(pid);
|
|
3548
|
-
if ((n.parentId ?? void 0) !== (P.parentId ?? void 0)) continue;
|
|
3549
|
-
workingX.set(n.id, centerX(pid) - width.get(n.id) / 2);
|
|
3550
|
-
}
|
|
3551
|
-
const nodes = graph.nodes.map((n) => {
|
|
3552
|
-
const nx = workingX.get(n.id);
|
|
3553
|
-
return nx === n.position.x ? n : { ...n, position: { x: nx, y: n.position.y } };
|
|
3554
|
-
});
|
|
3555
|
-
return { nodes, edges: graph.edges };
|
|
3556
|
-
}
|
|
3557
|
-
function createSnappedDagreLayout(base, options = {}) {
|
|
3558
|
-
return (graph) => snapLinearSuccessors(base(graph), options);
|
|
3559
|
-
}
|
|
3560
|
-
|
|
3561
3731
|
// src/components/FlowchartView/_internal/traceGroupLayout.ts
|
|
3562
3732
|
function buildAdjacency(graph, fallbackW, fallbackH, nodeSize) {
|
|
3563
3733
|
const preds = /* @__PURE__ */ new Map();
|