@floegence/floe-webapp-core 0.86.7 → 0.86.8
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/components/graph/layout.js +115 -85
- package/dist/components/graph/packing.js +141 -58
- package/dist/components/graph/positions.js +29 -29
- package/dist/components/graph/routing.js +163 -126
- package/dist/components/graph/types.d.ts +4 -2
- package/dist/styles.css +1 -1
- package/package.json +1 -1
|
@@ -1,77 +1,82 @@
|
|
|
1
|
-
import { applyGraphPositions as
|
|
2
|
-
import { computePackedGraphLayout as
|
|
3
|
-
function
|
|
4
|
-
const o = /* @__PURE__ */ new Set(), c = (
|
|
5
|
-
if (!
|
|
6
|
-
o.add(
|
|
7
|
-
},
|
|
8
|
-
for (const
|
|
9
|
-
if (c(
|
|
10
|
-
throw new Error(`Invalid dimensions for graph node: ${
|
|
11
|
-
for (const
|
|
12
|
-
const s = /* @__PURE__ */ new Set([
|
|
13
|
-
let
|
|
14
|
-
for (;
|
|
15
|
-
const
|
|
16
|
-
if (!
|
|
17
|
-
throw new Error(`Invalid parent for graph node: ${
|
|
18
|
-
if (s.has(
|
|
19
|
-
s.add(
|
|
1
|
+
import { applyGraphPositions as b } from "./positions.js";
|
|
2
|
+
import { computePackedGraphLayout as k } from "./packing.js";
|
|
3
|
+
function $(a) {
|
|
4
|
+
const o = /* @__PURE__ */ new Set(), c = (t) => {
|
|
5
|
+
if (!t || o.has(t)) throw new Error(`Duplicate or empty graph ID: ${t}`);
|
|
6
|
+
o.add(t);
|
|
7
|
+
}, i = new Map(a.nodes.map((t) => [t.id, t]));
|
|
8
|
+
for (const t of a.nodes) {
|
|
9
|
+
if (c(t.id), ![t.width, t.height].every((n) => Number.isFinite(n) && n > 0))
|
|
10
|
+
throw new Error(`Invalid dimensions for graph node: ${t.id}`);
|
|
11
|
+
for (const n of t.ports ?? []) c(n.id);
|
|
12
|
+
const s = /* @__PURE__ */ new Set([t.id]);
|
|
13
|
+
let r = t.parentId;
|
|
14
|
+
for (; r !== void 0; ) {
|
|
15
|
+
const n = i.get(r);
|
|
16
|
+
if (!n || n.kind !== "group")
|
|
17
|
+
throw new Error(`Invalid parent for graph node: ${t.id}`);
|
|
18
|
+
if (s.has(r)) throw new Error(`Cyclic graph containment: ${t.id}`);
|
|
19
|
+
s.add(r), r = n.parentId;
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
-
for (const
|
|
23
|
-
c(
|
|
24
|
-
for (const [s,
|
|
25
|
-
[
|
|
26
|
-
[
|
|
22
|
+
for (const t of a.edges) {
|
|
23
|
+
c(t.id);
|
|
24
|
+
for (const [s, r] of [
|
|
25
|
+
[t.source, t.sourcePort],
|
|
26
|
+
[t.target, t.targetPort]
|
|
27
27
|
]) {
|
|
28
|
-
const
|
|
29
|
-
if (!
|
|
30
|
-
throw new Error(`Invalid endpoint for graph edge: ${
|
|
28
|
+
const n = i.get(s);
|
|
29
|
+
if (!n || r !== void 0 && !n.ports?.some((h) => h.id === r))
|
|
30
|
+
throw new Error(`Invalid endpoint for graph edge: ${t.id}`);
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
-
async function P(
|
|
35
|
-
|
|
34
|
+
async function P(a, o, c) {
|
|
35
|
+
$(a);
|
|
36
|
+
const i = O(a, o);
|
|
37
|
+
if (o.aspectRatio !== void 0 && (!Number.isFinite(o.aspectRatio) || o.aspectRatio <= 0))
|
|
36
38
|
throw new Error("Graph layout aspect ratio must be finite and positive");
|
|
37
|
-
const
|
|
38
|
-
if (![...Object.values(
|
|
39
|
+
const t = o.groupPadding ?? { top: 64, right: 28, bottom: 28, left: 28 };
|
|
40
|
+
if (![...Object.values(t), o.spacing ?? 64].every((e) => Number.isFinite(e) && e >= 0))
|
|
39
41
|
throw new Error("Graph layout spacing must be finite and nonnegative");
|
|
40
|
-
if (o.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
42
|
+
if (o.layers && (M(a, o.layers), o.positionMode === "fixed" && o.positions?.length))
|
|
43
|
+
throw new Error("Fixed positions cannot be combined with graph layers");
|
|
44
|
+
if (o.aspectRatio !== void 0 || o.layers)
|
|
45
|
+
return k(i, o, c);
|
|
46
|
+
const s = /* @__PURE__ */ new Map();
|
|
47
|
+
for (const e of i.nodes)
|
|
48
|
+
s.set(e.id, {
|
|
49
|
+
id: e.id,
|
|
50
|
+
width: e.width,
|
|
51
|
+
height: e.height,
|
|
52
|
+
...e.kind === "group" ? { children: [] } : {},
|
|
53
|
+
ports: e.ports?.map((d) => ({
|
|
54
|
+
id: d.id,
|
|
50
55
|
width: 1,
|
|
51
56
|
height: 1,
|
|
52
|
-
layoutOptions: { "elk.port.side":
|
|
57
|
+
layoutOptions: { "elk.port.side": d.side }
|
|
53
58
|
})),
|
|
54
59
|
layoutOptions: {
|
|
55
60
|
"elk.portConstraints": "FIXED_ORDER",
|
|
56
|
-
"elk.padding": `[top=${
|
|
61
|
+
"elk.padding": `[top=${t.top},left=${t.left},bottom=${t.bottom},right=${t.right}]`
|
|
57
62
|
}
|
|
58
63
|
});
|
|
59
|
-
const
|
|
60
|
-
for (const
|
|
61
|
-
(
|
|
62
|
-
const
|
|
63
|
-
...
|
|
64
|
-
...
|
|
64
|
+
const r = [];
|
|
65
|
+
for (const e of i.nodes)
|
|
66
|
+
(e.parentId ? s.get(e.parentId).children : r).push(s.get(e.id));
|
|
67
|
+
const n = /* @__PURE__ */ new Set([
|
|
68
|
+
...i.nodes.flatMap((e) => [e.id, ...(e.ports ?? []).map((d) => d.id)]),
|
|
69
|
+
...i.edges.map((e) => e.id)
|
|
65
70
|
]);
|
|
66
|
-
let
|
|
67
|
-
for (;
|
|
68
|
-
const
|
|
69
|
-
id:
|
|
70
|
-
children:
|
|
71
|
-
edges:
|
|
72
|
-
id:
|
|
73
|
-
sources: [
|
|
74
|
-
targets: [
|
|
71
|
+
let h = "$graph";
|
|
72
|
+
for (; n.has(h); ) h += "$";
|
|
73
|
+
const p = await c.layout({
|
|
74
|
+
id: h,
|
|
75
|
+
children: r,
|
|
76
|
+
edges: i.edges.map((e) => ({
|
|
77
|
+
id: e.id,
|
|
78
|
+
sources: [e.sourcePort ?? e.source],
|
|
79
|
+
targets: [e.targetPort ?? e.target]
|
|
75
80
|
})),
|
|
76
81
|
layoutOptions: {
|
|
77
82
|
"elk.algorithm": "layered",
|
|
@@ -83,47 +88,72 @@ async function P(n, o, c) {
|
|
|
83
88
|
"elk.layered.considerModelOrder.strategy": "NODES_AND_EDGES",
|
|
84
89
|
"elk.randomSeed": "1"
|
|
85
90
|
}
|
|
86
|
-
}),
|
|
87
|
-
for (const
|
|
88
|
-
const
|
|
91
|
+
}), y = /* @__PURE__ */ new Map(), x = /* @__PURE__ */ new Map(), E = (e) => {
|
|
92
|
+
for (const d of e.edges ?? []) {
|
|
93
|
+
const g = d.container ?? e.id, f = y.get(g) ?? { x: 0, y: 0 };
|
|
89
94
|
x.set(
|
|
90
|
-
|
|
91
|
-
(
|
|
92
|
-
(
|
|
93
|
-
x:
|
|
94
|
-
y:
|
|
95
|
+
d.id,
|
|
96
|
+
(d.sections ?? []).map(
|
|
97
|
+
(l) => [l.startPoint, ...l.bendPoints ?? [], l.endPoint].map((m) => ({
|
|
98
|
+
x: m.x + f.x,
|
|
99
|
+
y: m.y + f.y
|
|
95
100
|
}))
|
|
96
101
|
)
|
|
97
102
|
);
|
|
98
103
|
}
|
|
99
|
-
for (const
|
|
100
|
-
},
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
for (const
|
|
104
|
+
for (const d of e.children ?? []) E(d);
|
|
105
|
+
}, v = (e, d, g) => {
|
|
106
|
+
const f = d + (e.x ?? 0), l = g + (e.y ?? 0);
|
|
107
|
+
y.set(e.id, { x: f, y: l, width: e.width ?? 0, height: e.height ?? 0 });
|
|
108
|
+
for (const m of e.children ?? []) v(m, f, l);
|
|
104
109
|
};
|
|
105
|
-
for (const
|
|
106
|
-
E(
|
|
107
|
-
const
|
|
108
|
-
const
|
|
109
|
-
return { ...
|
|
110
|
+
for (const e of p.children ?? []) v(e, 0, 0);
|
|
111
|
+
E(p);
|
|
112
|
+
const w = (!o.positions?.length || o.positionMode === "compact") && o.anchor && y.get(o.anchor.nodeId), u = w ? o.anchor.position.x - w.x : 0, I = w ? o.anchor.position.y - w.y : 0, G = i.nodes.map((e) => {
|
|
113
|
+
const d = y.get(e.id);
|
|
114
|
+
return { ...e, ...d, x: d.x + u, y: d.y + I };
|
|
110
115
|
});
|
|
111
|
-
return
|
|
116
|
+
return b(
|
|
112
117
|
{
|
|
113
|
-
nodes:
|
|
114
|
-
edges:
|
|
115
|
-
...
|
|
116
|
-
sections: (x.get(
|
|
117
|
-
(
|
|
118
|
+
nodes: G,
|
|
119
|
+
edges: i.edges.map((e) => ({
|
|
120
|
+
...e,
|
|
121
|
+
sections: (x.get(e.id) ?? []).map(
|
|
122
|
+
(d) => d.map((g) => ({ x: g.x + u, y: g.y + I }))
|
|
118
123
|
)
|
|
119
124
|
})),
|
|
120
|
-
bounds: { x:
|
|
125
|
+
bounds: { x: u, y: I, width: p.width ?? 0, height: p.height ?? 0 }
|
|
121
126
|
},
|
|
122
127
|
o,
|
|
123
|
-
|
|
128
|
+
i.nodes
|
|
124
129
|
);
|
|
125
130
|
}
|
|
131
|
+
function O(a, o) {
|
|
132
|
+
if (o.positionMode !== "compact" || !o.positions?.length) return a;
|
|
133
|
+
const c = o.direction ?? "RIGHT", i = new Map(
|
|
134
|
+
o.positions.map((r) => [
|
|
135
|
+
r.nodeId,
|
|
136
|
+
c === "RIGHT" || c === "LEFT" ? r.y : r.x
|
|
137
|
+
])
|
|
138
|
+
), t = new Map(a.nodes.map((r, n) => [r.id, n]));
|
|
139
|
+
return { nodes: [...a.nodes].sort((r, n) => {
|
|
140
|
+
const h = (r.parentId ?? "").localeCompare(n.parentId ?? ""), p = o.layers && !r.parentId && !n.parentId ? 0 : (i.get(r.id) ?? 1 / 0) - (i.get(n.id) ?? 1 / 0);
|
|
141
|
+
return h || p || t.get(r.id) - t.get(n.id);
|
|
142
|
+
}), edges: a.edges };
|
|
143
|
+
}
|
|
144
|
+
function M(a, o) {
|
|
145
|
+
const c = new Map(a.nodes.map((t) => [t.id, t])), i = /* @__PURE__ */ new Set();
|
|
146
|
+
for (const [t, s] of o.entries()) {
|
|
147
|
+
if (!s.length) throw new Error(`Graph layer must not be empty: ${t}`);
|
|
148
|
+
for (const r of s) {
|
|
149
|
+
const n = c.get(r);
|
|
150
|
+
if (!n || n.parentId) throw new Error(`Graph layer object must be a root node: ${r}`);
|
|
151
|
+
if (i.has(r)) throw new Error(`Graph object appears in multiple layers: ${r}`);
|
|
152
|
+
i.add(r);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
126
156
|
export {
|
|
127
157
|
P as computeGraphLayout,
|
|
128
|
-
|
|
158
|
+
$ as validateGraphInput
|
|
129
159
|
};
|
|
@@ -1,75 +1,158 @@
|
|
|
1
|
-
import { applyGraphPositions as
|
|
2
|
-
import { routeGraphGeometry as
|
|
3
|
-
async function
|
|
4
|
-
const
|
|
5
|
-
for (const e of
|
|
6
|
-
const
|
|
7
|
-
|
|
1
|
+
import { applyGraphPositions as $ } from "./positions.js";
|
|
2
|
+
import { routeGraphGeometry as P } from "./routing.js";
|
|
3
|
+
async function j(f, i, S) {
|
|
4
|
+
const y = new Map(f.nodes.map((e) => [e.id, { ...e, x: 0, y: 0 }])), O = new Map(f.nodes.map((e, d) => [e.id, d])), m = /* @__PURE__ */ new Map();
|
|
5
|
+
for (const e of y.values()) {
|
|
6
|
+
const d = m.get(e.parentId) ?? [];
|
|
7
|
+
d.push(e), m.set(e.parentId, d);
|
|
8
8
|
}
|
|
9
|
-
const
|
|
10
|
-
...
|
|
11
|
-
...
|
|
9
|
+
const p = /* @__PURE__ */ new Set([
|
|
10
|
+
...f.nodes.flatMap((e) => [e.id, ...(e.ports ?? []).map((d) => d.id)]),
|
|
11
|
+
...f.edges.map((e) => e.id)
|
|
12
12
|
]);
|
|
13
|
-
let
|
|
14
|
-
for (;
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
},
|
|
24
|
-
|
|
25
|
-
for (
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
13
|
+
let T = "$packed";
|
|
14
|
+
for (; p.has(T); ) T += "$";
|
|
15
|
+
const k = i.groupPadding ?? { top: 64, right: 28, bottom: 28, left: 28 }, E = i.direction ?? "RIGHT", w = new Map(
|
|
16
|
+
(i.positions ?? []).map((e) => [
|
|
17
|
+
e.nodeId,
|
|
18
|
+
E === "RIGHT" || E === "LEFT" ? e.y : e.x
|
|
19
|
+
])
|
|
20
|
+
), I = (e, d, s) => {
|
|
21
|
+
e.x += d, e.y += s;
|
|
22
|
+
for (const v of m.get(e.id) ?? []) I(v, d, s);
|
|
23
|
+
}, x = (e, d) => {
|
|
24
|
+
let s = y.get(e);
|
|
25
|
+
for (; s && s.parentId !== d; )
|
|
26
|
+
s = s.parentId ? y.get(s.parentId) : void 0;
|
|
27
|
+
return s;
|
|
28
|
+
}, G = async (e) => {
|
|
29
|
+
const d = [...m.get(e) ?? []];
|
|
30
|
+
(e !== void 0 || !i.layers) && d.sort(
|
|
31
|
+
(o, a) => (w.get(o.id) ?? 1 / 0) - (w.get(a.id) ?? 1 / 0) || O.get(o.id) - O.get(a.id)
|
|
32
|
+
);
|
|
33
|
+
for (const o of d) {
|
|
34
|
+
if (!m.has(o.id)) continue;
|
|
35
|
+
const a = await G(o.id);
|
|
36
|
+
o.width = Math.max(o.width, a.width), o.height = Math.max(o.height, a.height);
|
|
29
37
|
}
|
|
30
|
-
if (!
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
|
|
38
|
+
if (!d.length) return { width: 0, height: 0 };
|
|
39
|
+
if (e === void 0 && i.layers)
|
|
40
|
+
return z(d, f, i, x, I);
|
|
41
|
+
const s = /* @__PURE__ */ new Map();
|
|
42
|
+
for (const o of f.edges) {
|
|
43
|
+
const a = x(o.source, e), M = x(o.target, e);
|
|
44
|
+
if (!a || !M || a.id === M.id) continue;
|
|
45
|
+
const H = JSON.stringify([a.id, M.id]);
|
|
46
|
+
s.has(H) || s.set(H, { id: o.id, sources: [a.id], targets: [M.id] });
|
|
37
47
|
}
|
|
38
|
-
const
|
|
39
|
-
id: e ??
|
|
40
|
-
children:
|
|
41
|
-
edges: [...
|
|
48
|
+
const v = await S.layout({
|
|
49
|
+
id: e ?? T,
|
|
50
|
+
children: d.map((o) => ({ id: o.id, width: o.width, height: o.height })),
|
|
51
|
+
edges: [...s.values()],
|
|
42
52
|
layoutOptions: {
|
|
43
|
-
"elk.algorithm":
|
|
44
|
-
"elk.direction":
|
|
53
|
+
"elk.algorithm": s.size ? "layered" : "rectpacking",
|
|
54
|
+
"elk.direction": E,
|
|
45
55
|
"elk.edgeRouting": "ORTHOGONAL",
|
|
46
56
|
"elk.separateConnectedComponents": "true",
|
|
47
|
-
"elk.aspectRatio": String(
|
|
48
|
-
"elk.spacing.componentComponent": String(
|
|
49
|
-
"elk.spacing.nodeNode": String(
|
|
50
|
-
"elk.layered.spacing.nodeNodeBetweenLayers": String(
|
|
57
|
+
...i.aspectRatio !== void 0 ? { "elk.aspectRatio": String(i.aspectRatio) } : {},
|
|
58
|
+
"elk.spacing.componentComponent": String(i.spacing ?? 64),
|
|
59
|
+
"elk.spacing.nodeNode": String(i.spacing ?? 64),
|
|
60
|
+
"elk.layered.spacing.nodeNodeBetweenLayers": String(i.spacing ?? 64),
|
|
51
61
|
"elk.layered.considerModelOrder.strategy": "NODES_AND_EDGES",
|
|
52
|
-
"elk.padding": e ? `[top=${
|
|
62
|
+
"elk.padding": e ? `[top=${k.top},left=${k.left},bottom=${k.bottom},right=${k.right}]` : "[top=12,left=12,bottom=12,right=12]",
|
|
53
63
|
"elk.randomSeed": "1"
|
|
54
64
|
}
|
|
55
65
|
});
|
|
56
|
-
for (const
|
|
57
|
-
const
|
|
58
|
-
|
|
66
|
+
for (const o of v.children ?? []) {
|
|
67
|
+
const a = y.get(o.id);
|
|
68
|
+
I(a, (o.x ?? 0) - a.x, (o.y ?? 0) - a.y);
|
|
59
69
|
}
|
|
60
|
-
return { width:
|
|
61
|
-
},
|
|
62
|
-
if (
|
|
63
|
-
const e =
|
|
64
|
-
for (const
|
|
70
|
+
return { width: v.width ?? 0, height: v.height ?? 0 };
|
|
71
|
+
}, u = await G(), R = (!i.positions?.length || i.positionMode === "compact" || i.layers) && i.anchor && y.get(i.anchor.nodeId);
|
|
72
|
+
if (R) {
|
|
73
|
+
const e = i.anchor.position.x - R.x, d = i.anchor.position.y - R.y;
|
|
74
|
+
for (const s of m.get(void 0) ?? []) I(s, e, d);
|
|
65
75
|
}
|
|
66
|
-
const
|
|
67
|
-
nodes: [...
|
|
68
|
-
edges:
|
|
69
|
-
bounds: { x: 0, y: 0, ...
|
|
76
|
+
const C = {
|
|
77
|
+
nodes: [...y.values()],
|
|
78
|
+
edges: f.edges.map((e) => ({ ...e, sections: [] })),
|
|
79
|
+
bounds: { x: 0, y: 0, ...u }
|
|
70
80
|
};
|
|
71
|
-
return
|
|
81
|
+
return i.positions?.length && i.positionMode !== "compact" && !i.layers ? $(C, i, f.nodes) : P(C);
|
|
82
|
+
}
|
|
83
|
+
function z(f, i, S, y, O) {
|
|
84
|
+
const m = S.direction ?? "RIGHT", p = m === "RIGHT" || m === "LEFT", T = m === "RIGHT" || m === "DOWN", k = new Map(f.map((t, n) => [t.id, n])), E = new Map(
|
|
85
|
+
(S.positions ?? []).filter((t) => k.has(t.nodeId)).map((t) => [t.nodeId, p ? t.y : t.x])
|
|
86
|
+
), w = (t, n) => k.get(t) - k.get(n) || t.localeCompare(n), I = (t, n) => (E.get(t) ?? 1 / 0) - (E.get(n) ?? 1 / 0) || w(t, n), x = new Map(f.map((t) => [t.id, /* @__PURE__ */ new Set()]));
|
|
87
|
+
for (const t of i.edges) {
|
|
88
|
+
const n = y(t.source, void 0)?.id, r = y(t.target, void 0)?.id;
|
|
89
|
+
n && r && n !== r && (x.get(n)?.add(r), x.get(r)?.add(n));
|
|
90
|
+
}
|
|
91
|
+
const G = S.layers ?? [], u = /* @__PURE__ */ new Map();
|
|
92
|
+
G.forEach((t, n) => t.forEach((r) => u.set(r, n)));
|
|
93
|
+
const R = new Set(f.map((t) => t.id)), C = [];
|
|
94
|
+
for (const t of [...R].sort(w)) {
|
|
95
|
+
if (!R.has(t)) continue;
|
|
96
|
+
const n = [], r = [t];
|
|
97
|
+
R.delete(t);
|
|
98
|
+
for (let c = 0; c < r.length; c++) {
|
|
99
|
+
const g = r[c];
|
|
100
|
+
n.push(g);
|
|
101
|
+
for (const h of [...x.get(g)].sort(w))
|
|
102
|
+
R.delete(h) && r.push(h);
|
|
103
|
+
}
|
|
104
|
+
C.push(n);
|
|
105
|
+
}
|
|
106
|
+
let e = G.length;
|
|
107
|
+
for (const t of C) {
|
|
108
|
+
const n = t.filter((g) => u.has(g));
|
|
109
|
+
if (!n.length) {
|
|
110
|
+
t.sort(w).forEach((g) => u.set(g, e)), e++;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
const r = /* @__PURE__ */ new Map(), c = [...n].sort((g, h) => u.get(g) - u.get(h) || w(g, h));
|
|
114
|
+
for (const g of c) r.set(g, 0);
|
|
115
|
+
for (let g = 0; g < c.length; g++) {
|
|
116
|
+
const h = c[g];
|
|
117
|
+
for (const l of [...x.get(h)].sort(w))
|
|
118
|
+
r.has(l) || (r.set(l, r.get(h) + 1), u.set(l, u.get(h)), c.push(l));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const d = Math.max(G.length, e), s = Array.from({ length: d }, () => []);
|
|
122
|
+
for (const t of f) s[u.get(t.id)].push(t);
|
|
123
|
+
for (const t of s) t.sort((n, r) => I(n.id, r.id));
|
|
124
|
+
const v = (t, n) => {
|
|
125
|
+
const r = new Map(s[n].map((h, l) => [h.id, l])), c = new Map(s[t].map((h, l) => [h.id, l])), g = (h) => {
|
|
126
|
+
const l = [...x.get(h) ?? []].flatMap((N) => {
|
|
127
|
+
const b = r.get(N);
|
|
128
|
+
return u.get(N) === n && b !== void 0 ? [b] : [];
|
|
129
|
+
});
|
|
130
|
+
return l.length ? l.reduce((N, b) => N + b, 0) / l.length : c.get(h);
|
|
131
|
+
};
|
|
132
|
+
s[t].sort((h, l) => g(h.id) - g(l.id) || I(h.id, l.id));
|
|
133
|
+
};
|
|
134
|
+
for (let t = 1; t < s.length; t++) v(t, t - 1);
|
|
135
|
+
for (let t = s.length - 2; t >= 0; t--) v(t, t + 1);
|
|
136
|
+
const o = S.spacing ?? 64;
|
|
137
|
+
let a = 0, M = 0;
|
|
138
|
+
const H = [], L = [];
|
|
139
|
+
for (const t of s) {
|
|
140
|
+
let n = 0;
|
|
141
|
+
const r = Math.max(0, ...t.map((c) => p ? c.width : c.height));
|
|
142
|
+
H.push(a), L.push(r);
|
|
143
|
+
for (const c of t) {
|
|
144
|
+
const g = a + (r - (p ? c.width : c.height)) / 2, h = p ? g : n, l = p ? n : g;
|
|
145
|
+
O(c, h - c.x, l - c.y), n += (p ? c.height : c.width) + o;
|
|
146
|
+
}
|
|
147
|
+
M = Math.max(M, Math.max(0, n - o)), a += r + o;
|
|
148
|
+
}
|
|
149
|
+
if (a = Math.max(0, a - o), !T)
|
|
150
|
+
for (const t of f) {
|
|
151
|
+
const n = u.get(t.id), c = a - H[n] - L[n] + (L[n] - (p ? t.width : t.height)) / 2;
|
|
152
|
+
O(t, p ? c - t.x : 0, p ? 0 : c - t.y);
|
|
153
|
+
}
|
|
154
|
+
return p ? { width: a, height: M } : { width: M, height: a };
|
|
72
155
|
}
|
|
73
156
|
export {
|
|
74
|
-
|
|
157
|
+
j as computePackedGraphLayout
|
|
75
158
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { routeGraphGeometry as G } from "./routing.js";
|
|
2
|
-
function E(d,
|
|
3
|
-
if (!
|
|
2
|
+
function E(d, p, v) {
|
|
3
|
+
if (!p.positions?.length || p.positionMode === "compact") return d;
|
|
4
4
|
const f = new Map(d.nodes.map((t) => [t.id, { ...t }])), l = /* @__PURE__ */ new Map();
|
|
5
|
-
for (const t of
|
|
5
|
+
for (const t of p.positions) {
|
|
6
6
|
if (!f.has(t.nodeId) || l.has(t.nodeId) || !Number.isFinite(t.x) || !Number.isFinite(t.y))
|
|
7
7
|
throw new Error(`Invalid graph position: ${t.nodeId}`);
|
|
8
8
|
l.set(t.nodeId, t);
|
|
@@ -13,14 +13,14 @@ function E(d, c, v) {
|
|
|
13
13
|
const m = y.get(t.parentId) ?? [];
|
|
14
14
|
m.push(t), y.set(t.parentId, m);
|
|
15
15
|
}
|
|
16
|
-
const x =
|
|
17
|
-
const g = { x: t.x, y: t.y },
|
|
18
|
-
t.x =
|
|
16
|
+
const x = p.groupPadding ?? { top: 64, left: 28, right: 28, bottom: 28 }, u = p.positionMode === "preferred", I = new Map(v.map((t) => [t.id, t])), b = (t, m, M) => {
|
|
17
|
+
const g = { x: t.x, y: t.y }, c = l.get(t.id);
|
|
18
|
+
t.x = c?.x ?? t.x + m, t.y = c?.y ?? t.y + M;
|
|
19
19
|
const i = y.get(t.id) ?? [];
|
|
20
20
|
for (const a of i) b(a, t.x - g.x, t.y - g.y);
|
|
21
21
|
if (!i.length || u) return;
|
|
22
|
-
const
|
|
23
|
-
if (
|
|
22
|
+
const r = Math.min(...i.map((a) => a.x)) - x.left, h = Math.min(...i.map((a) => a.y)) - x.top;
|
|
23
|
+
if (c && (r < t.x || h < t.y))
|
|
24
24
|
throw new Error(`Pinned child lies outside group content: ${t.id}`);
|
|
25
25
|
const s = Math.max(
|
|
26
26
|
t.x + t.width,
|
|
@@ -29,43 +29,43 @@ function E(d, c, v) {
|
|
|
29
29
|
t.y + t.height,
|
|
30
30
|
...i.map((a) => a.y + a.height + x.bottom)
|
|
31
31
|
);
|
|
32
|
-
|
|
32
|
+
c || (t.x = Math.min(t.x, r), t.y = Math.min(t.y, h)), t.width = s - t.x, t.height = n - t.y;
|
|
33
33
|
};
|
|
34
34
|
for (const t of f.values()) t.parentId || b(t, 0, 0);
|
|
35
35
|
if (u) {
|
|
36
|
-
const t = Math.max(16,
|
|
37
|
-
i.x +=
|
|
38
|
-
for (const s of y.get(i.id) ?? []) m(s,
|
|
36
|
+
const t = Math.max(16, p.spacing ?? 64), m = (i, r, h) => {
|
|
37
|
+
i.x += r, i.y += h;
|
|
38
|
+
for (const s of y.get(i.id) ?? []) m(s, r, h);
|
|
39
39
|
}, M = (i) => {
|
|
40
|
-
const
|
|
40
|
+
const r = [];
|
|
41
41
|
for (const h of [...i].sort(
|
|
42
42
|
(s, n) => s.y - n.y || s.x - n.x || s.id.localeCompare(n.id)
|
|
43
43
|
)) {
|
|
44
44
|
const s = { x: h.x, y: h.y };
|
|
45
|
-
for (const
|
|
46
|
-
h.y <
|
|
45
|
+
for (const o of [...r].sort((e, w) => e.x - w.x))
|
|
46
|
+
h.y < o.y + o.height + t && h.y + h.height + t > o.y && s.x < o.x + o.width + t && s.x + h.width + t > o.x && (s.x = o.x + o.width + t);
|
|
47
47
|
const n = { x: h.x, y: h.y };
|
|
48
|
-
for (const
|
|
49
|
-
h.x <
|
|
48
|
+
for (const o of [...r].sort((e, w) => e.y - w.y))
|
|
49
|
+
h.x < o.x + o.width + t && h.x + h.width + t > o.x && n.y < o.y + o.height + t && n.y + h.height + t > o.y && (n.y = o.y + o.height + t);
|
|
50
50
|
const a = s.x - h.x < n.y - h.y ? s : n;
|
|
51
|
-
m(h, a.x - h.x, a.y - h.y),
|
|
51
|
+
m(h, a.x - h.x, a.y - h.y), r.push(h);
|
|
52
52
|
}
|
|
53
53
|
}, g = (i) => {
|
|
54
|
-
const
|
|
55
|
-
if (!
|
|
56
|
-
for (const e of
|
|
57
|
-
M(
|
|
58
|
-
const h = Math.max(12, x.left), s = Math.max(12, x.top), n = Math.max(12, x.right), a = Math.max(12, x.bottom),
|
|
59
|
-
i.x = Math.min(
|
|
54
|
+
const r = y.get(i.id) ?? [];
|
|
55
|
+
if (!r.length) return;
|
|
56
|
+
for (const e of r) g(e);
|
|
57
|
+
M(r);
|
|
58
|
+
const h = Math.max(12, x.left), s = Math.max(12, x.top), n = Math.max(12, x.right), a = Math.max(12, x.bottom), o = l.get(i.id);
|
|
59
|
+
i.x = Math.min(o?.x ?? 1 / 0, Math.min(...r.map((e) => e.x)) - h), i.y = Math.min(o?.y ?? 1 / 0, Math.min(...r.map((e) => e.y)) - s), i.width = Math.max(
|
|
60
60
|
I.get(i.id).width,
|
|
61
|
-
Math.max(...
|
|
61
|
+
Math.max(...r.map((e) => e.x + e.width)) + n - i.x
|
|
62
62
|
), i.height = Math.max(
|
|
63
63
|
I.get(i.id).height,
|
|
64
|
-
Math.max(...
|
|
64
|
+
Math.max(...r.map((e) => e.y + e.height)) + a - i.y
|
|
65
65
|
);
|
|
66
|
-
},
|
|
67
|
-
for (const i of
|
|
68
|
-
M(
|
|
66
|
+
}, c = [...f.values()].filter((i) => !i.parentId);
|
|
67
|
+
for (const i of c) g(i);
|
|
68
|
+
M(c);
|
|
69
69
|
}
|
|
70
70
|
return G({ ...d, nodes: [...f.values()] });
|
|
71
71
|
}
|