@weasel-js/diagram 1.11.0 → 1.12.0
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/README.md +696 -4
- package/dist/chunk-2SYY4W3B.js +2055 -0
- package/dist/chunk-2SYY4W3B.js.map +1 -0
- package/dist/chunk-5GIP2LA6.js +312 -0
- package/dist/chunk-5GIP2LA6.js.map +1 -0
- package/dist/chunk-DYDX6EJC.js +3653 -0
- package/dist/chunk-DYDX6EJC.js.map +1 -0
- package/dist/chunk-GA4BX7SH.js +1431 -0
- package/dist/chunk-GA4BX7SH.js.map +1 -0
- package/dist/{chunk-NUMMW5BI.js → chunk-R2XB6D32.js} +416 -36
- package/dist/chunk-R2XB6D32.js.map +1 -0
- package/dist/chunk-WDIE35AK.js +3 -0
- package/dist/chunk-WDIE35AK.js.map +1 -0
- package/dist/{fromData-GKqRgPFs.d.ts → dataTypes-DHdkzCL8.d.ts} +238 -59
- package/dist/effect-audio.d.ts +139 -0
- package/dist/effect-audio.js +533 -0
- package/dist/effect-audio.js.map +1 -0
- package/dist/effect.d.ts +486 -121
- package/dist/effect.js +1632 -347
- package/dist/effect.js.map +1 -1
- package/dist/icons.table.d.ts +6 -0
- package/dist/icons.table.js +32 -0
- package/dist/icons.table.js.map +1 -0
- package/dist/icons.table.json +24 -0
- package/dist/index.d.ts +2159 -92
- package/dist/index.js +1056 -2
- package/dist/index.js.map +1 -1
- package/dist/layout.d.ts +3 -3
- package/dist/layout.entry-B-jJMc50.d.ts +617 -0
- package/dist/layout.js +3 -1
- package/dist/stageTypes-DvnR8cKQ.d.ts +189 -0
- package/dist/{body-2lC7IiIA.d.ts → types-M_ccNAlk.d.ts} +221 -182
- package/package.json +28 -7
- package/dist/chunk-C4NAI6NV.js +0 -2041
- package/dist/chunk-C4NAI6NV.js.map +0 -1
- package/dist/chunk-NUMMW5BI.js.map +0 -1
- package/dist/layout.entry-BoWFcR4G.d.ts +0 -285
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AUTO_POSE_DESCRIPTOR, rotatePoint, rectPath, polygonFromPoints, PATH_M, PATH_L, PATH_C, flattenCubic, PATH_Q, PATH_Z, PathBuilder } from '@weasel-js/core/math';
|
|
2
|
-
import { transformPath } from '@weasel-js/geom';
|
|
1
|
+
import { AUTO_POSE_DESCRIPTOR, rotatePoint, rectPath, polygonFromPoints, PATH_M, PATH_L, PATH_C, flattenCubic, PATH_Q, PATH_Z, PathBuilder, clipNothing, pointAlongPath } from '@weasel-js/core/math';
|
|
2
|
+
import { transformPath, ellipsePath, PATH_M as PATH_M$1, PATH_CMD_LENGTHS, measurePath, forEachSegment, PATH_L as PATH_L$1, nearestOnLine, PATH_Q as PATH_Q$1, nearestOnQuadratic, PATH_C as PATH_C$1, nearestOnCubic } from '@weasel-js/geom';
|
|
3
3
|
import { cssFamilyName } from '@weasel-js/font/metrics';
|
|
4
4
|
import { createSimulation } from '@weasel-js/simulation';
|
|
5
5
|
|
|
@@ -48,6 +48,8 @@ function outlinePath(outline, bounds) {
|
|
|
48
48
|
]);
|
|
49
49
|
case "stadium":
|
|
50
50
|
return stadiumPath(x, y, w, h);
|
|
51
|
+
case "ellipse":
|
|
52
|
+
return ellipsePath(bounds);
|
|
51
53
|
}
|
|
52
54
|
}
|
|
53
55
|
function stadiumPath(x, y, w, h) {
|
|
@@ -85,6 +87,11 @@ function contentBox(outline, bounds) {
|
|
|
85
87
|
return { x, y: y + h / 4, width: w, height: h / 2 };
|
|
86
88
|
case "hexagon":
|
|
87
89
|
return { x: x + w * POINT, y, width: w * (1 - POINT * 2), height: h };
|
|
90
|
+
case "ellipse": {
|
|
91
|
+
const cw = w / Math.SQRT2;
|
|
92
|
+
const ch = h / Math.SQRT2;
|
|
93
|
+
return { x: x + (w - cw) / 2, y: y + (h - ch) / 2, width: cw, height: ch };
|
|
94
|
+
}
|
|
88
95
|
case "stadium": {
|
|
89
96
|
const r = Math.min(w, h) / 2;
|
|
90
97
|
return w >= h ? { x: x + r, y, width: Math.max(w - r * 2, 0), height: h } : { x, y: y + r, width: w, height: Math.max(h - r * 2, 0) };
|
|
@@ -106,6 +113,8 @@ function boxForContent(outline, content) {
|
|
|
106
113
|
return { width: content.width / (1 - POINT * 2), height: content.height };
|
|
107
114
|
case "stadium":
|
|
108
115
|
return { width: content.width + content.height, height: content.height };
|
|
116
|
+
case "ellipse":
|
|
117
|
+
return { width: content.width * Math.SQRT2, height: content.height * Math.SQRT2 };
|
|
109
118
|
}
|
|
110
119
|
}
|
|
111
120
|
var TOLERANCE = 0.25;
|
|
@@ -217,6 +226,7 @@ var dataKeyReader = (node) => {
|
|
|
217
226
|
if (trait === null || typeof trait !== "object") return null;
|
|
218
227
|
if ("from" in trait && "to" in trait) return null;
|
|
219
228
|
if ("label" in trait || "anchor" in trait || "mark" in trait) return null;
|
|
229
|
+
if (trait.container?.role === "lane") return null;
|
|
220
230
|
return trait;
|
|
221
231
|
};
|
|
222
232
|
function createDiagramNodes(entries) {
|
|
@@ -492,6 +502,7 @@ function buildBody(spec, at2, opts) {
|
|
|
492
502
|
layer: opts.layer,
|
|
493
503
|
pose,
|
|
494
504
|
data: opts.body(trait, pose),
|
|
505
|
+
clipFromPose: clipNothing,
|
|
495
506
|
...opts.id === void 0 ? {} : { id: opts.id }
|
|
496
507
|
}];
|
|
497
508
|
const leaf = (box, data, rowId) => {
|
|
@@ -735,6 +746,10 @@ function crossInset(inset, axes) {
|
|
|
735
746
|
const c = canonical(inset, axes);
|
|
736
747
|
return { lo: c.crossLo, hi: c.crossHi };
|
|
737
748
|
}
|
|
749
|
+
function rankInset(inset, axes) {
|
|
750
|
+
const c = canonical(inset, axes);
|
|
751
|
+
return { lo: c.rankLo, hi: c.rankHi };
|
|
752
|
+
}
|
|
738
753
|
function rankGaps(graph, rows, axes, rankGap) {
|
|
739
754
|
const gaps = rows.slice(1).map(() => rankGap);
|
|
740
755
|
const ends2 = /* @__PURE__ */ new Map();
|
|
@@ -922,6 +937,181 @@ function expandGroupEdges(edges, groups) {
|
|
|
922
937
|
}
|
|
923
938
|
return out;
|
|
924
939
|
}
|
|
940
|
+
function subpathOf(path, index) {
|
|
941
|
+
if (path.kind !== "polygon") return index === 0 ? path : null;
|
|
942
|
+
const { commands, coords } = path;
|
|
943
|
+
let seen = -1;
|
|
944
|
+
let start = -1;
|
|
945
|
+
let startCoord = 0;
|
|
946
|
+
let coord2 = 0;
|
|
947
|
+
for (let i = 0; i <= commands.length; i++) {
|
|
948
|
+
const cmd = commands[i];
|
|
949
|
+
if (i === commands.length || cmd === PATH_M$1) {
|
|
950
|
+
if (seen === index) {
|
|
951
|
+
if (start === 0 && i === commands.length) return path;
|
|
952
|
+
return { kind: "polygon", fillRule: path.fillRule, commands: commands.slice(start, i), coords: coords.slice(startCoord, coord2) };
|
|
953
|
+
}
|
|
954
|
+
seen++;
|
|
955
|
+
start = i;
|
|
956
|
+
startCoord = coord2;
|
|
957
|
+
}
|
|
958
|
+
if (cmd !== void 0) coord2 += PATH_CMD_LENGTHS[cmd] ?? 0;
|
|
959
|
+
}
|
|
960
|
+
return null;
|
|
961
|
+
}
|
|
962
|
+
var NAMED = { start: 0, mid: 0.5, end: 1 };
|
|
963
|
+
function nearestStation(path, near) {
|
|
964
|
+
if (path.kind !== "polygon") return null;
|
|
965
|
+
const { commands, coords } = path;
|
|
966
|
+
let best = null;
|
|
967
|
+
let heading = { x: 1, y: 0 };
|
|
968
|
+
forEachSegment(commands, coords, (cmd, ci, x0, y0) => {
|
|
969
|
+
let hit;
|
|
970
|
+
let d;
|
|
971
|
+
if (cmd === PATH_L$1) {
|
|
972
|
+
hit = nearestOnLine(near.x, near.y, x0, y0, coords[ci], coords[ci + 1]);
|
|
973
|
+
d = { x: coords[ci] - x0, y: coords[ci + 1] - y0 };
|
|
974
|
+
} else if (cmd === PATH_Q$1) {
|
|
975
|
+
hit = nearestOnQuadratic(near.x, near.y, x0, y0, coords[ci], coords[ci + 1], coords[ci + 2], coords[ci + 3]);
|
|
976
|
+
const t = hit.t;
|
|
977
|
+
d = {
|
|
978
|
+
x: 2 * (1 - t) * (coords[ci] - x0) + 2 * t * (coords[ci + 2] - coords[ci]),
|
|
979
|
+
y: 2 * (1 - t) * (coords[ci + 1] - y0) + 2 * t * (coords[ci + 3] - coords[ci + 1])
|
|
980
|
+
};
|
|
981
|
+
} else if (cmd === PATH_C$1) {
|
|
982
|
+
hit = nearestOnCubic(
|
|
983
|
+
near.x,
|
|
984
|
+
near.y,
|
|
985
|
+
x0,
|
|
986
|
+
y0,
|
|
987
|
+
coords[ci],
|
|
988
|
+
coords[ci + 1],
|
|
989
|
+
coords[ci + 2],
|
|
990
|
+
coords[ci + 3],
|
|
991
|
+
coords[ci + 4],
|
|
992
|
+
coords[ci + 5]
|
|
993
|
+
);
|
|
994
|
+
const t = hit.t;
|
|
995
|
+
const u = 1 - t;
|
|
996
|
+
d = {
|
|
997
|
+
x: 3 * u * u * (coords[ci] - x0) + 6 * u * t * (coords[ci + 2] - coords[ci]) + 3 * t * t * (coords[ci + 4] - coords[ci + 2]),
|
|
998
|
+
y: 3 * u * u * (coords[ci + 1] - y0) + 6 * u * t * (coords[ci + 3] - coords[ci + 1]) + 3 * t * t * (coords[ci + 5] - coords[ci + 3])
|
|
999
|
+
};
|
|
1000
|
+
} else return;
|
|
1001
|
+
const len = Math.hypot(d.x, d.y);
|
|
1002
|
+
if (len === 0 || best !== null && hit.dist >= best.dist) return;
|
|
1003
|
+
best = hit;
|
|
1004
|
+
heading = { x: d.x / len, y: d.y / len };
|
|
1005
|
+
});
|
|
1006
|
+
const found = best;
|
|
1007
|
+
return found === null ? null : { point: { x: found.x, y: found.y }, tangent: heading };
|
|
1008
|
+
}
|
|
1009
|
+
function labelCenter(whole, label, size) {
|
|
1010
|
+
const path = subpathOf(whole, 0) ?? whole;
|
|
1011
|
+
const at2 = label.placed ?? label;
|
|
1012
|
+
const station = typeof at2.at === "object" ? nearestStation(path, at2.at.near) ?? pointAlongPath(path, 0.5) : pointAlongPath(path, typeof at2.at === "number" ? at2.at : NAMED[at2.at] ?? 0.5);
|
|
1013
|
+
if (station === null) return null;
|
|
1014
|
+
return besideStation(station.point, station.tangent, at2.offset ?? 0, size);
|
|
1015
|
+
}
|
|
1016
|
+
function halfDepth(tangent, size) {
|
|
1017
|
+
return (Math.abs(tangent.y) * size.width + Math.abs(tangent.x) * size.height) / 2;
|
|
1018
|
+
}
|
|
1019
|
+
function besideStation(point, tangent, offset, size) {
|
|
1020
|
+
const reach = offset + Math.sign(offset) * halfDepth(tangent, size);
|
|
1021
|
+
return { x: point.x + tangent.y * reach, y: point.y - tangent.x * reach };
|
|
1022
|
+
}
|
|
1023
|
+
function offsetFrom(point, tangent, center2, size) {
|
|
1024
|
+
const d = (center2.x - point.x) * tangent.y - (center2.y - point.y) * tangent.x;
|
|
1025
|
+
const offset = Math.sign(d) * Math.max(Math.abs(d) - halfDepth(tangent, size), 0);
|
|
1026
|
+
return offset === 0 ? 0 : offset;
|
|
1027
|
+
}
|
|
1028
|
+
var NUDGE = 1e-9;
|
|
1029
|
+
function labelSpotAt(whole, center2, size) {
|
|
1030
|
+
const measure = measurePath(subpathOf(whole, 0) ?? whole);
|
|
1031
|
+
if (measure === null) return null;
|
|
1032
|
+
const station = measure.nearest(center2);
|
|
1033
|
+
if (measure.length === 0) return { at: 0.5, offset: offsetFrom(station.point, station.tangent, center2, size) };
|
|
1034
|
+
const at2 = station.s / measure.length;
|
|
1035
|
+
const step = NUDGE * measure.length;
|
|
1036
|
+
const before = measure.at(station.s - step).tangent;
|
|
1037
|
+
const after = measure.at(station.s + step).tangent;
|
|
1038
|
+
if (before.x === after.x && before.y === after.y) {
|
|
1039
|
+
return { at: at2, offset: offsetFrom(station.point, station.tangent, center2, size) };
|
|
1040
|
+
}
|
|
1041
|
+
const reads = measure.at(at2 * measure.length).tangent;
|
|
1042
|
+
let best = { at: at2, offset: 0 };
|
|
1043
|
+
let bestDist = Infinity;
|
|
1044
|
+
for (const [tangent, side] of [[before, -1], [after, 1]]) {
|
|
1045
|
+
const offset = offsetFrom(station.point, tangent, center2, size);
|
|
1046
|
+
const back = besideStation(station.point, tangent, offset, size);
|
|
1047
|
+
const dist = Math.hypot(back.x - center2.x, back.y - center2.y);
|
|
1048
|
+
if (dist >= bestDist) continue;
|
|
1049
|
+
const onLeg = reads.x === tangent.x && reads.y === tangent.y;
|
|
1050
|
+
best = { at: onLeg ? at2 : at2 + side * NUDGE, offset };
|
|
1051
|
+
bestDist = dist;
|
|
1052
|
+
}
|
|
1053
|
+
return best;
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
// src/edgeTrait.ts
|
|
1057
|
+
function layoutOwnsPort(end) {
|
|
1058
|
+
return end.port === void 0 || end.port === end.laidOut;
|
|
1059
|
+
}
|
|
1060
|
+
function layoutOwnsRoute(edge) {
|
|
1061
|
+
const points = edge.waypoints ?? [];
|
|
1062
|
+
if (points.length === 0) return true;
|
|
1063
|
+
return edge.laidOut !== void 0 && samePoints(points, edge.laidOut);
|
|
1064
|
+
}
|
|
1065
|
+
function layoutWritesRoute(edge) {
|
|
1066
|
+
return edge.router !== "avoid" && layoutOwnsRoute(edge);
|
|
1067
|
+
}
|
|
1068
|
+
function samePoints(a, b) {
|
|
1069
|
+
return a.length === b.length && a.every((p, i) => p.x === b[i].x && p.y === b[i].y);
|
|
1070
|
+
}
|
|
1071
|
+
function diagramEdgeOf(node) {
|
|
1072
|
+
const data = node.data;
|
|
1073
|
+
if (data === null || typeof data !== "object") return null;
|
|
1074
|
+
const edge = data.diagram;
|
|
1075
|
+
if (edge === null || typeof edge !== "object") return null;
|
|
1076
|
+
return "from" in edge && "to" in edge ? edge : null;
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
// src/avoid/holds.ts
|
|
1080
|
+
var EPS2 = 1e-6;
|
|
1081
|
+
function runsAlong(d, normal, sign) {
|
|
1082
|
+
const len = Math.hypot(d.x, d.y) * Math.hypot(normal.x, normal.y);
|
|
1083
|
+
if (len === 0) return false;
|
|
1084
|
+
const cross = d.x * normal.y - d.y * normal.x;
|
|
1085
|
+
return Math.abs(cross) <= EPS2 * len && sign * (d.x * normal.x + d.y * normal.y) > 0;
|
|
1086
|
+
}
|
|
1087
|
+
function onSegment(p, a, b) {
|
|
1088
|
+
const dx = b.x - a.x;
|
|
1089
|
+
const dy = b.y - a.y;
|
|
1090
|
+
const len2 = dx * dx + dy * dy;
|
|
1091
|
+
const t = len2 === 0 ? 0 : Math.max(0, Math.min(1, ((p.x - a.x) * dx + (p.y - a.y) * dy) / len2));
|
|
1092
|
+
return Math.hypot(a.x + t * dx - p.x, a.y + t * dy - p.y) <= EPS2 * Math.max(1, Math.sqrt(len2)) ? t : null;
|
|
1093
|
+
}
|
|
1094
|
+
function routeHolds(from, to, waypoints, route) {
|
|
1095
|
+
const points = [from.point, ...route, to.point];
|
|
1096
|
+
const n = points.length;
|
|
1097
|
+
const first = { x: points[1].x - points[0].x, y: points[1].y - points[0].y };
|
|
1098
|
+
const last = { x: points[n - 1].x - points[n - 2].x, y: points[n - 1].y - points[n - 2].y };
|
|
1099
|
+
if (from.normal !== null && !runsAlong(first, from.normal, 1)) return false;
|
|
1100
|
+
if (to.normal !== null && !runsAlong(last, to.normal, -1)) return false;
|
|
1101
|
+
let seg = 0;
|
|
1102
|
+
let along = 0;
|
|
1103
|
+
for (const w of waypoints) {
|
|
1104
|
+
for (; seg < n - 1; seg++, along = 0) {
|
|
1105
|
+
const t = onSegment(w, points[seg], points[seg + 1]);
|
|
1106
|
+
if (t !== null && t >= along) {
|
|
1107
|
+
along = t;
|
|
1108
|
+
break;
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
if (seg === n - 1) return false;
|
|
1112
|
+
}
|
|
1113
|
+
return true;
|
|
1114
|
+
}
|
|
925
1115
|
|
|
926
1116
|
// src/forceGroups.ts
|
|
927
1117
|
function resolve(groups, byId) {
|
|
@@ -1036,7 +1226,7 @@ var DEFAULTS = {
|
|
|
1036
1226
|
groupStrength: 0.2
|
|
1037
1227
|
};
|
|
1038
1228
|
var GOLDEN = Math.PI * (3 - Math.sqrt(5));
|
|
1039
|
-
var
|
|
1229
|
+
var NUDGE2 = 0.5;
|
|
1040
1230
|
function charge(bodies, strength) {
|
|
1041
1231
|
return (alpha) => {
|
|
1042
1232
|
for (let i = 0; i < bodies.length; i++) {
|
|
@@ -1179,7 +1369,7 @@ function separate(bodies) {
|
|
|
1179
1369
|
seen.set(key, nth + 1);
|
|
1180
1370
|
if (nth === 0 || body.fx != null || body.fy != null) return;
|
|
1181
1371
|
const angle = GOLDEN * i;
|
|
1182
|
-
const radius =
|
|
1372
|
+
const radius = NUDGE2 * nth;
|
|
1183
1373
|
body.x += Math.cos(angle) * radius;
|
|
1184
1374
|
body.y += Math.sin(angle) * radius;
|
|
1185
1375
|
});
|
|
@@ -1786,8 +1976,18 @@ function chainsOf(groups) {
|
|
|
1786
1976
|
};
|
|
1787
1977
|
return (group) => group === void 0 ? [] : chain2(group, /* @__PURE__ */ new Set());
|
|
1788
1978
|
}
|
|
1789
|
-
var newBlock = (first) => ({
|
|
1790
|
-
|
|
1979
|
+
var newBlock = (first, group) => ({
|
|
1980
|
+
...group !== void 0 ? { group } : {},
|
|
1981
|
+
items: [],
|
|
1982
|
+
sub: /* @__PURE__ */ new Map(),
|
|
1983
|
+
sum: 0,
|
|
1984
|
+
count: 0,
|
|
1985
|
+
first
|
|
1986
|
+
});
|
|
1987
|
+
function placesOf(groups) {
|
|
1988
|
+
return new Map(groups.filter((g) => g.ordered !== void 0).map((g) => [g.id, new Map(g.ordered.map((m, i) => [m, i]))]));
|
|
1989
|
+
}
|
|
1990
|
+
function sortRank(row, key, chainOf, places = /* @__PURE__ */ new Map()) {
|
|
1791
1991
|
const root = newBlock(0);
|
|
1792
1992
|
const keyOf = /* @__PURE__ */ new Map();
|
|
1793
1993
|
const firstOf = /* @__PURE__ */ new Map();
|
|
@@ -1797,7 +1997,7 @@ function sortRank(row, key, chainOf) {
|
|
|
1797
1997
|
for (const g of chainOf(n.group)) {
|
|
1798
1998
|
let next = at2.sub.get(g);
|
|
1799
1999
|
if (next === void 0) {
|
|
1800
|
-
next = newBlock(i);
|
|
2000
|
+
next = newBlock(i, g);
|
|
1801
2001
|
at2.sub.set(g, next);
|
|
1802
2002
|
at2.items.push(next);
|
|
1803
2003
|
}
|
|
@@ -1811,7 +2011,12 @@ function sortRank(row, key, chainOf) {
|
|
|
1811
2011
|
});
|
|
1812
2012
|
const out = [];
|
|
1813
2013
|
const flatten = (block) => {
|
|
2014
|
+
const place = block.group === void 0 ? void 0 : places.get(block.group);
|
|
1814
2015
|
const items = block.items.map((item) => {
|
|
2016
|
+
if (place !== void 0) {
|
|
2017
|
+
const k = place.get("id" in item ? item.id : item.group) ?? Infinity;
|
|
2018
|
+
return { item, k, first: "id" in item ? firstOf.get(item) : item.first };
|
|
2019
|
+
}
|
|
1815
2020
|
if ("id" in item) return { item, k: keyOf.get(item), first: firstOf.get(item) };
|
|
1816
2021
|
return { item, k: item.sum / item.count, first: item.first };
|
|
1817
2022
|
});
|
|
@@ -1837,7 +2042,7 @@ function reorder(work, r, side) {
|
|
|
1837
2042
|
if (near === void 0 || near.length === 0) return i;
|
|
1838
2043
|
return near.reduce((s, m) => s + landing(m, n.id, work) - 0.5, 0) / near.length;
|
|
1839
2044
|
};
|
|
1840
|
-
work.rows[r] = sortRank(work.rows[r], key, work.chainOf);
|
|
2045
|
+
work.rows[r] = sortRank(work.rows[r], key, work.chainOf, work.places);
|
|
1841
2046
|
reindex(work, r);
|
|
1842
2047
|
}
|
|
1843
2048
|
function between(work, side, u, v) {
|
|
@@ -1858,7 +2063,7 @@ function transpose(work) {
|
|
|
1858
2063
|
for (let i = 0; i + 1 < row.length; i++) {
|
|
1859
2064
|
const u = row[i];
|
|
1860
2065
|
const v = row[i + 1];
|
|
1861
|
-
if (u.group !== v.group) continue;
|
|
2066
|
+
if (u.group !== v.group || u.group !== void 0 && work.places.has(u.group)) continue;
|
|
1862
2067
|
const now = cost(u.id, v.id);
|
|
1863
2068
|
pos.set(v.id, i);
|
|
1864
2069
|
pos.set(u.id, i + 1);
|
|
@@ -1878,6 +2083,7 @@ function orderRows(rows, hops, opts = {}) {
|
|
|
1878
2083
|
const patience = opts.patience ?? 4;
|
|
1879
2084
|
const maxSweeps = opts.maxSweeps ?? 24;
|
|
1880
2085
|
const chainOf = chainsOf(opts.groups ?? []);
|
|
2086
|
+
const places = placesOf(opts.groups ?? []);
|
|
1881
2087
|
const byRank = hopsByRank(rows, hops);
|
|
1882
2088
|
const ups = /* @__PURE__ */ new Map();
|
|
1883
2089
|
const downs = /* @__PURE__ */ new Map();
|
|
@@ -1887,9 +2093,9 @@ function orderRows(rows, hops, opts = {}) {
|
|
|
1887
2093
|
(ups.get(p.to) ?? ups.set(p.to, []).get(p.to)).push({ id: p.from, frac: p.fromAt, places: p.fromPlaces, side: "down" });
|
|
1888
2094
|
}
|
|
1889
2095
|
}
|
|
1890
|
-
const seeded = rows.map((row) => sortRank(row, (_, i) => i, chainOf));
|
|
2096
|
+
const seeded = rows.map((row) => sortRank(row, (_, i) => i, chainOf, places));
|
|
1891
2097
|
const sides = sidesOf(hops);
|
|
1892
|
-
const work = { rows: seeded, pos: positions(seeded), ups, downs, sides, chainOf };
|
|
2098
|
+
const work = { rows: seeded, pos: positions(seeded), ups, downs, sides, chainOf, places };
|
|
1893
2099
|
let best = seeded.map((row) => [...row]);
|
|
1894
2100
|
let fewest = total(work.rows, byRank, work.pos, sides);
|
|
1895
2101
|
for (let sweep = 0, stale = 0; sweep < maxSweeps && stale < patience && fewest > 0; sweep++) {
|
|
@@ -1975,7 +2181,7 @@ function around(a, b, others, axes, rankGap) {
|
|
|
1975
2181
|
}
|
|
1976
2182
|
|
|
1977
2183
|
// src/layered/across.ts
|
|
1978
|
-
var
|
|
2184
|
+
var EPS3 = 1e-6;
|
|
1979
2185
|
function settleAcross(input) {
|
|
1980
2186
|
const { graph, rows, axes } = input;
|
|
1981
2187
|
const groups = new Map((graph.groups ?? []).map((g) => [g.id, g]));
|
|
@@ -2034,7 +2240,7 @@ function squeeze(items, order, xs, gap) {
|
|
|
2034
2240
|
for (const list of order) {
|
|
2035
2241
|
let edge = -Infinity;
|
|
2036
2242
|
for (const i of list) {
|
|
2037
|
-
if (free(i) && xs[i] < edge -
|
|
2243
|
+
if (free(i) && xs[i] < edge - EPS3) [xs[i], moved] = [edge, true];
|
|
2038
2244
|
edge = Math.max(edge, xs[i] + items[i].width + gap);
|
|
2039
2245
|
}
|
|
2040
2246
|
}
|
|
@@ -2045,7 +2251,7 @@ function squeeze(items, order, xs, gap) {
|
|
|
2045
2251
|
let edge = Infinity;
|
|
2046
2252
|
for (const i of [...list].reverse()) {
|
|
2047
2253
|
const most = edge - items[i].width - gap;
|
|
2048
|
-
if (free(i) && xs[i] > most +
|
|
2254
|
+
if (free(i) && xs[i] > most + EPS3) [xs[i], moved] = [most, true];
|
|
2049
2255
|
edge = Math.min(edge, xs[i]);
|
|
2050
2256
|
}
|
|
2051
2257
|
}
|
|
@@ -2100,7 +2306,7 @@ function clear(items, list, xs, gap) {
|
|
|
2100
2306
|
for (const j of list.slice(k + 1)) {
|
|
2101
2307
|
const pin = (k2) => items[k2].fixed !== void 0 && items[k2].group === void 0;
|
|
2102
2308
|
if (pin(i) && pin(j)) continue;
|
|
2103
|
-
const apart = xs[j] >= xs[i] + items[i].width + gap -
|
|
2309
|
+
const apart = xs[j] >= xs[i] + items[i].width + gap - EPS3 || xs[i] >= xs[j] + items[j].width + gap - EPS3;
|
|
2104
2310
|
if (!apart) return false;
|
|
2105
2311
|
}
|
|
2106
2312
|
}
|
|
@@ -2118,7 +2324,7 @@ function jump(items, list, xs, gap) {
|
|
|
2118
2324
|
for (let moved = true; moved; ) {
|
|
2119
2325
|
moved = false;
|
|
2120
2326
|
for (const b of blocks) {
|
|
2121
|
-
if (x < b.hi -
|
|
2327
|
+
if (x < b.hi - EPS3 && x + width > b.lo + EPS3) [x, moved] = [dir === 1 ? b.hi : b.lo - width, true];
|
|
2122
2328
|
}
|
|
2123
2329
|
}
|
|
2124
2330
|
out[i] = x;
|
|
@@ -2134,7 +2340,7 @@ function jump(items, list, xs, gap) {
|
|
|
2134
2340
|
}
|
|
2135
2341
|
|
|
2136
2342
|
// src/layered/bands.ts
|
|
2137
|
-
var
|
|
2343
|
+
var EPS4 = 1e-6;
|
|
2138
2344
|
function placeBands(input, covers) {
|
|
2139
2345
|
const { natural, minGaps } = input;
|
|
2140
2346
|
const n = natural.length;
|
|
@@ -2143,7 +2349,7 @@ function placeBands(input, covers) {
|
|
|
2143
2349
|
for (let k = 0, lo = -Infinity; k < n; k++) {
|
|
2144
2350
|
earliest.push(lo);
|
|
2145
2351
|
const cover = covers.get(k);
|
|
2146
|
-
if (cover !== void 0 && lo > cover.lo +
|
|
2352
|
+
if (cover !== void 0 && lo > cover.lo + EPS4) return void 0;
|
|
2147
2353
|
lo = hiOf(k, lo) + (minGaps[k] ?? 0);
|
|
2148
2354
|
}
|
|
2149
2355
|
const los = preferred(input, covers, hiOf).map((lo, k) => Math.max(lo, earliest[k]));
|
|
@@ -2185,7 +2391,7 @@ function spread(input, covers, los, hiOf) {
|
|
|
2185
2391
|
const share = (k) => {
|
|
2186
2392
|
if (room >= usual) return gaps[k] + (usual > 0 ? (room - usual) * gaps[k] / usual : (room - usual) / ks.length);
|
|
2187
2393
|
const slack = usual - least;
|
|
2188
|
-
return minGaps[k] + (slack >
|
|
2394
|
+
return minGaps[k] + (slack > EPS4 ? (room - least) * (gaps[k] - minGaps[k]) / slack : (room - least) / ks.length);
|
|
2189
2395
|
};
|
|
2190
2396
|
for (let k = f + 1; k < g; k++) los[k] = hiOf(k - 1, los[k - 1]) + share(k - 1);
|
|
2191
2397
|
}
|
|
@@ -2490,12 +2696,12 @@ function planOnce(graph, opts = {}) {
|
|
|
2490
2696
|
spaced[r] = spaced[r] - rankGap * (1 - LABEL_GAP);
|
|
2491
2697
|
}
|
|
2492
2698
|
const pinned = pinnedSet(graph, opts);
|
|
2493
|
-
const { crossAt, gaps, depths, rankAt, unheld } = holdPins({ graph, rows, crossAt: packed, gaps: spaced, pinned, axes, nodeGap, minGaps });
|
|
2699
|
+
const { crossAt, gaps, depths: depths2, rankAt, unheld } = holdPins({ graph, rows, crossAt: packed, gaps: spaced, pinned, axes, nodeGap, minGaps });
|
|
2494
2700
|
const slots = /* @__PURE__ */ new Map();
|
|
2495
2701
|
const bands = [];
|
|
2496
2702
|
let along = 0;
|
|
2497
2703
|
for (const [i, row] of rows.entries()) {
|
|
2498
|
-
const depth =
|
|
2704
|
+
const depth = depths2[i];
|
|
2499
2705
|
bands.push([along, along + depth]);
|
|
2500
2706
|
for (const node of row) {
|
|
2501
2707
|
slots.set(node.id, { cross: crossAt.get(node.id), rank: rankAt.get(node.id) ?? along + (depth - extent(node.bounds, axes.rank)) / 2 });
|
|
@@ -2557,6 +2763,173 @@ var layered = Object.assign(
|
|
|
2557
2763
|
{ plan: layeredPlan }
|
|
2558
2764
|
);
|
|
2559
2765
|
|
|
2766
|
+
// src/chainGroups.ts
|
|
2767
|
+
function depths(groups) {
|
|
2768
|
+
const byId = new Map(groups.map((g) => [g.id, g]));
|
|
2769
|
+
const depth = /* @__PURE__ */ new Map();
|
|
2770
|
+
const of = (g) => {
|
|
2771
|
+
if (!depth.has(g.id)) {
|
|
2772
|
+
const parent = g.parent === void 0 ? void 0 : byId.get(g.parent);
|
|
2773
|
+
depth.set(g.id, parent === void 0 ? 0 : of(parent) + 1);
|
|
2774
|
+
}
|
|
2775
|
+
return depth.get(g.id);
|
|
2776
|
+
};
|
|
2777
|
+
groups.forEach(of);
|
|
2778
|
+
return depth;
|
|
2779
|
+
}
|
|
2780
|
+
var deepestFirst = (groups) => {
|
|
2781
|
+
const depth = depths(groups);
|
|
2782
|
+
return [...groups].sort((p, q) => depth.get(q.id) - depth.get(p.id));
|
|
2783
|
+
};
|
|
2784
|
+
function groupHanging(graph, line, hanging) {
|
|
2785
|
+
const groups = graph.groups ?? [];
|
|
2786
|
+
if (groups.length === 0) return hanging;
|
|
2787
|
+
const index = new Map(line.map((n, i) => [n.id, i]));
|
|
2788
|
+
const byId = new Map(groups.map((g) => [g.id, g]));
|
|
2789
|
+
const onLine = new Map(groups.map((g) => [g.id, g.members.filter((m) => index.has(m))]));
|
|
2790
|
+
const owner = new Map(hanging.owner);
|
|
2791
|
+
for (const node of graph.nodes) {
|
|
2792
|
+
if (index.has(node.id)) continue;
|
|
2793
|
+
const first = index.get(hanging.owner.get(node.id));
|
|
2794
|
+
for (let g = node.group === void 0 ? void 0 : byId.get(node.group); g !== void 0; g = g.parent === void 0 ? void 0 : byId.get(g.parent)) {
|
|
2795
|
+
const members = onLine.get(g.id);
|
|
2796
|
+
if (members.length === 0) continue;
|
|
2797
|
+
owner.set(node.id, nearest(members, first, index));
|
|
2798
|
+
break;
|
|
2799
|
+
}
|
|
2800
|
+
}
|
|
2801
|
+
const ordered = deepestFirst(groups);
|
|
2802
|
+
for (const g of ordered) {
|
|
2803
|
+
if (onLine.get(g.id).length > 0) continue;
|
|
2804
|
+
const hung = g.members.filter((m) => owner.has(m));
|
|
2805
|
+
if (hung.length === 0) continue;
|
|
2806
|
+
const counts = /* @__PURE__ */ new Map();
|
|
2807
|
+
for (const m of hung) counts.set(owner.get(m), (counts.get(owner.get(m)) ?? 0) + 1);
|
|
2808
|
+
let best = owner.get(hung[0]);
|
|
2809
|
+
for (const [id, n] of counts) {
|
|
2810
|
+
const lead = counts.get(best);
|
|
2811
|
+
if (n > lead || n === lead && index.get(id) < index.get(best)) best = id;
|
|
2812
|
+
}
|
|
2813
|
+
for (const m of hung) owner.set(m, best);
|
|
2814
|
+
}
|
|
2815
|
+
return { owner, level: clearColumns(graph, ordered, index, owner, hanging.level) };
|
|
2816
|
+
}
|
|
2817
|
+
function nearest(members, from, index) {
|
|
2818
|
+
let best = members[0];
|
|
2819
|
+
for (const m of members) {
|
|
2820
|
+
const d = Math.abs(index.get(m) - from);
|
|
2821
|
+
const lead = Math.abs(index.get(best) - from);
|
|
2822
|
+
if (d < lead || d === lead && index.get(m) < index.get(best)) best = m;
|
|
2823
|
+
}
|
|
2824
|
+
return best;
|
|
2825
|
+
}
|
|
2826
|
+
function clearColumns(graph, ordered, index, owner, start) {
|
|
2827
|
+
const level = new Map(start);
|
|
2828
|
+
const columns = /* @__PURE__ */ new Map();
|
|
2829
|
+
for (const node of graph.nodes) {
|
|
2830
|
+
if (index.has(node.id)) continue;
|
|
2831
|
+
const id = owner.get(node.id);
|
|
2832
|
+
columns.set(id, [...columns.get(id) ?? [], node.id]);
|
|
2833
|
+
}
|
|
2834
|
+
for (const [lineId, hung] of columns) {
|
|
2835
|
+
const holding = ordered.filter((g) => g.members.some((m) => m === lineId || hung.includes(m)));
|
|
2836
|
+
const atLine = holding.filter((g) => g.members.includes(lineId));
|
|
2837
|
+
const kept = new Set(atLine.flatMap((g) => g.members));
|
|
2838
|
+
const clear2 = (g, fixed) => {
|
|
2839
|
+
const members = new Set(g.members);
|
|
2840
|
+
const own = hung.filter((id) => members.has(id)).map((id) => level.get(id));
|
|
2841
|
+
const low = members.has(lineId) ? 0 : Math.min(...own);
|
|
2842
|
+
const deep = Math.max(0, ...own);
|
|
2843
|
+
const movers = hung.filter((id) => !members.has(id) && !fixed.has(id) && level.get(id) >= low);
|
|
2844
|
+
if (!movers.some((id) => level.get(id) <= deep)) return;
|
|
2845
|
+
const steps = [...new Set(movers.map((id) => level.get(id)))].sort((p, q) => p - q);
|
|
2846
|
+
for (const id of movers) level.set(id, deep + 1 + steps.indexOf(level.get(id)));
|
|
2847
|
+
};
|
|
2848
|
+
for (const g of holding) if (!atLine.includes(g)) clear2(g, kept);
|
|
2849
|
+
for (const g of atLine) clear2(g, /* @__PURE__ */ new Set());
|
|
2850
|
+
}
|
|
2851
|
+
return level;
|
|
2852
|
+
}
|
|
2853
|
+
function lineGaps(graph, line, hanging, rankGap, axes, packed) {
|
|
2854
|
+
const index = new Map(line.map((n, i) => [n.id, i]));
|
|
2855
|
+
const columns = line.map((n) => [n]);
|
|
2856
|
+
for (const node of graph.nodes) {
|
|
2857
|
+
if (!index.has(node.id)) columns[index.get(hanging.owner.get(node.id))].push(node);
|
|
2858
|
+
}
|
|
2859
|
+
return bandGaps(graph, columns, axes, columns.slice(1).map(() => rankGap), (id) => packed.get(id)?.rank);
|
|
2860
|
+
}
|
|
2861
|
+
function levelGaps(graph, hanging, levelSize, axes, before, base) {
|
|
2862
|
+
const levels = Array.from(levelSize, () => []);
|
|
2863
|
+
for (const node of graph.nodes) (levels[hanging.level.get(node.id)] ??= []).push(node);
|
|
2864
|
+
const outward = { rank: axes.cross, cross: axes.rank, sign: before ? -1 : 1 };
|
|
2865
|
+
const from = [0];
|
|
2866
|
+
for (let k = 1; k < levelSize.length; k++) from[k] = from[k - 1] + (levelSize[k - 1] ?? 0);
|
|
2867
|
+
return bandGaps(graph, levels, outward, base, (id) => {
|
|
2868
|
+
const node = graph.node(id);
|
|
2869
|
+
const at2 = hanging.level.get(id);
|
|
2870
|
+
if (node === void 0 || at2 === void 0) return void 0;
|
|
2871
|
+
return at2 === 0 ? (levelSize[0] - extent(node.bounds, outward.rank)) / 2 : from[at2];
|
|
2872
|
+
});
|
|
2873
|
+
}
|
|
2874
|
+
function bandGaps(graph, bands, axes, gaps, start) {
|
|
2875
|
+
const insets = rankGaps(graph, bands, axes, 0);
|
|
2876
|
+
const out = gaps.map((gap, i) => gap + (insets[i] ?? 0));
|
|
2877
|
+
const groups = graph.groups ?? [];
|
|
2878
|
+
if (axes.rank !== "x" || !groups.some((g) => g.minWidth !== void 0)) return out;
|
|
2879
|
+
const bandOf = /* @__PURE__ */ new Map();
|
|
2880
|
+
bands.forEach((band, i) => band.forEach((n) => bandOf.set(n.id, i)));
|
|
2881
|
+
const children = /* @__PURE__ */ new Map();
|
|
2882
|
+
for (const g of groups) if (g.parent !== void 0) children.set(g.parent, [...children.get(g.parent) ?? [], g.id]);
|
|
2883
|
+
const byId = new Map(groups.map((g) => [g.id, g]));
|
|
2884
|
+
const span = (id, now) => {
|
|
2885
|
+
let [lo, hi] = [Infinity, -Infinity];
|
|
2886
|
+
for (const m of byId.get(id).members) {
|
|
2887
|
+
const at2 = start(m);
|
|
2888
|
+
const band = bandOf.get(m);
|
|
2889
|
+
const node = graph.node(m);
|
|
2890
|
+
if (at2 === void 0 || band === void 0 || node === void 0) continue;
|
|
2891
|
+
const from = at2 + now.slice(0, band).reduce((s, gap) => s + gap, 0);
|
|
2892
|
+
[lo, hi] = [Math.min(lo, from), Math.max(hi, from + extent(node.bounds, axes.rank))];
|
|
2893
|
+
}
|
|
2894
|
+
return { lo, hi };
|
|
2895
|
+
};
|
|
2896
|
+
widenForMinWidth(deepestFirst(groups).map((g) => {
|
|
2897
|
+
const placed = g.members.flatMap((id) => bandOf.has(id) && start(id) !== void 0 ? [bandOf.get(id)] : []);
|
|
2898
|
+
return {
|
|
2899
|
+
id: g.id,
|
|
2900
|
+
...g.minWidth !== void 0 ? { minWidth: g.minWidth } : {},
|
|
2901
|
+
inset: rankInset(g.inset, axes),
|
|
2902
|
+
children: children.get(g.id) ?? [],
|
|
2903
|
+
before: placed.length === 0 ? -1 : Math.min(...placed) - 1,
|
|
2904
|
+
after: placed.length === 0 ? -1 : Math.max(...placed)
|
|
2905
|
+
};
|
|
2906
|
+
}), out, span);
|
|
2907
|
+
return out;
|
|
2908
|
+
}
|
|
2909
|
+
function widenForMinWidth(groups, gaps, span) {
|
|
2910
|
+
const byId = new Map(groups.map((g) => [g.id, g]));
|
|
2911
|
+
const boxOf2 = (g, minWidth) => {
|
|
2912
|
+
let { lo, hi } = span(g.id, gaps);
|
|
2913
|
+
[lo, hi] = [lo - g.inset.lo, hi + g.inset.hi];
|
|
2914
|
+
for (const id of g.children) {
|
|
2915
|
+
const child = byId.get(id);
|
|
2916
|
+
if (child === void 0) continue;
|
|
2917
|
+
const box = boxOf2(child, child.minWidth ?? 0);
|
|
2918
|
+
[lo, hi] = [Math.min(lo, box.lo - g.inset.lo), Math.max(hi, box.hi + g.inset.hi)];
|
|
2919
|
+
}
|
|
2920
|
+
const grow = Math.max(0, minWidth - (hi - lo)) / 2;
|
|
2921
|
+
return { lo: lo - grow, hi: hi + grow };
|
|
2922
|
+
};
|
|
2923
|
+
for (const g of groups) {
|
|
2924
|
+
if (g.minWidth === void 0) continue;
|
|
2925
|
+
const box = boxOf2(g, 0);
|
|
2926
|
+
if (!(box.lo <= box.hi)) continue;
|
|
2927
|
+
const half = Math.max(0, g.minWidth - (box.hi - box.lo)) / 2;
|
|
2928
|
+
if (g.before >= 0 && g.before < gaps.length) gaps[g.before] += half;
|
|
2929
|
+
if (g.after >= 0 && g.after < gaps.length) gaps[g.after] += half;
|
|
2930
|
+
}
|
|
2931
|
+
}
|
|
2932
|
+
|
|
2560
2933
|
// src/chainRoutes.ts
|
|
2561
2934
|
var portOf3 = (node, id) => id === void 0 ? void 0 : node.ports?.find((p) => p.id === id);
|
|
2562
2935
|
function coord(node, at2, id, axis) {
|
|
@@ -2712,7 +3085,7 @@ function chainPlan(graph, opts = {}) {
|
|
|
2712
3085
|
const rankGap = opts.rankGap ?? DEFAULT_RANK_GAP;
|
|
2713
3086
|
const line = lineOf(graph, opts.chain);
|
|
2714
3087
|
if (line.length === 0) return { moves: /* @__PURE__ */ new Map() };
|
|
2715
|
-
const hanging = hangFrom(graph, line);
|
|
3088
|
+
const hanging = groupHanging(graph, line, hangFrom(graph, line));
|
|
2716
3089
|
const { owner, level } = hanging;
|
|
2717
3090
|
const rows = new Map(line.map((n) => [n.id, []]));
|
|
2718
3091
|
const levelSize = [Math.max(...line.map((n) => extent(n.bounds, axes.cross)))];
|
|
@@ -2725,24 +3098,31 @@ function chainPlan(graph, opts = {}) {
|
|
|
2725
3098
|
}
|
|
2726
3099
|
for (const [id, column] of rows) if (column[1]) column[1] = inPortOrder(graph, id, column[1], axes);
|
|
2727
3100
|
const before = opts.chainSide === "before";
|
|
2728
|
-
const
|
|
3101
|
+
const grouped = (graph.groups?.length ?? 0) > 0;
|
|
3102
|
+
const across = (side2) => {
|
|
3103
|
+
const base = Array.from(levelSize.slice(1), (_, k) => k === 0 ? side2 : nodeGap);
|
|
3104
|
+
return grouped ? levelGaps(graph, hanging, levelSize, axes, before, base) : base;
|
|
3105
|
+
};
|
|
3106
|
+
const slots = (rank, level2) => slotsFor(line, rows, levelSize, axes, { node: nodeGap, rank, level: level2 }, before);
|
|
3107
|
+
const gaps = grouped ? lineGaps(graph, line, hanging, rankGap, axes, slots(line.map(() => 0), [])) : line.map(() => rankGap);
|
|
3108
|
+
const place = (side2) => settle(graph, slots(gaps, across(side2)), opts);
|
|
2729
3109
|
let moves = place(nodeGap);
|
|
2730
3110
|
const side = (tracksNeeded(graph, hanging, moves, axes, before) + 1) * SIDE_TRACK_GAP;
|
|
2731
3111
|
if (side > nodeGap) moves = place(side);
|
|
2732
3112
|
return { moves, waypoints: sideRoutes(graph, hanging, moves, axes, before) };
|
|
2733
3113
|
}
|
|
2734
3114
|
function slotsFor(line, rows, levelSize, axes, gaps, before) {
|
|
2735
|
-
const { node: nodeGap, rank: rankGap } = gaps;
|
|
3115
|
+
const { node: nodeGap, rank: rankGap, level: levelGap } = gaps;
|
|
2736
3116
|
const rowSpan = (row) => row.reduce((sum, n) => sum + extent(n.bounds, axes.rank), 0) + nodeGap * Math.max(row.length - 1, 0);
|
|
2737
3117
|
const bandStart = (at2) => {
|
|
2738
3118
|
let offset = 0;
|
|
2739
|
-
|
|
2740
|
-
for (let k =
|
|
3119
|
+
if (before) for (let k = 1; k <= at2; k++) offset += (levelSize[k] ?? 0) + (levelGap[k - 1] ?? 0);
|
|
3120
|
+
else for (let k = 0; k < at2; k++) offset += (levelSize[k] ?? 0) + (levelGap[k] ?? 0);
|
|
2741
3121
|
return before ? -offset : offset;
|
|
2742
3122
|
};
|
|
2743
3123
|
const slots = /* @__PURE__ */ new Map();
|
|
2744
3124
|
let cursor = 0;
|
|
2745
|
-
|
|
3125
|
+
line.forEach((node, i) => {
|
|
2746
3126
|
const column = rows.get(node.id);
|
|
2747
3127
|
const span = Math.max(extent(node.bounds, axes.rank), ...Array.from(column, (row) => row ? rowSpan(row) : 0));
|
|
2748
3128
|
slots.set(node.id, {
|
|
@@ -2758,8 +3138,8 @@ function slotsFor(line, rows, levelSize, axes, gaps, before) {
|
|
|
2758
3138
|
along += extent(hung.bounds, axes.rank) + nodeGap;
|
|
2759
3139
|
}
|
|
2760
3140
|
});
|
|
2761
|
-
cursor += span + rankGap;
|
|
2762
|
-
}
|
|
3141
|
+
cursor += span + (rankGap[i] ?? 0);
|
|
3142
|
+
});
|
|
2763
3143
|
return slots;
|
|
2764
3144
|
}
|
|
2765
3145
|
|
|
@@ -2807,13 +3187,13 @@ var treeOnce = (graph, opts = {}) => {
|
|
|
2807
3187
|
const at2 = depth.get(node.id) ?? 0;
|
|
2808
3188
|
bands.set(at2, Math.max(bands.get(at2) ?? 0, extent(node.bounds, axes.rank)));
|
|
2809
3189
|
}
|
|
2810
|
-
const
|
|
2811
|
-
const rowsAt =
|
|
3190
|
+
const depths2 = [...bands.keys()].sort((a, b) => a - b);
|
|
3191
|
+
const rowsAt = depths2.map((at2) => graph.nodes.filter((n) => (depth.get(n.id) ?? 0) === at2));
|
|
2812
3192
|
const grouped = (graph.groups?.length ?? 0) > 0;
|
|
2813
|
-
const gaps = grouped ? rankGaps(graph, rowsAt, axes, rankGap) :
|
|
3193
|
+
const gaps = grouped ? rankGaps(graph, rowsAt, axes, rankGap) : depths2.slice(1).map(() => rankGap);
|
|
2814
3194
|
const bandStart = /* @__PURE__ */ new Map();
|
|
2815
3195
|
let along = 0;
|
|
2816
|
-
for (const [i, at2] of
|
|
3196
|
+
for (const [i, at2] of depths2.entries()) {
|
|
2817
3197
|
bandStart.set(at2, along);
|
|
2818
3198
|
along += bands.get(at2) + (gaps[i] ?? 0);
|
|
2819
3199
|
}
|
|
@@ -2860,6 +3240,6 @@ var treeOnce = (graph, opts = {}) => {
|
|
|
2860
3240
|
return settle(graph, slots, opts);
|
|
2861
3241
|
};
|
|
2862
3242
|
|
|
2863
|
-
export { COMPASS, DEFAULT_GROUP_INSET, DEFAULT_NODE_GAP, DEFAULT_PORTS, DEFAULT_RANK_GAP, DIAGRAM_TRAIT_KEY, PORT_LABEL_GAP, SIDE_TRACK_GAP, anchorOffset, authoredOver, axesFor, backEdges, bodyOutline, bodyTrait, boxForContent, buildBody, canvasMeasure, center, chain, contentBox, createDiagramNodes, dataKeyReader, diagramNodeOf, expandGroupEdges, extent, footprintNode, force, forceRelaxation, forestOf, graphOrder, grownBy, insetOf, isPinned, isPromise, layered, layeredPlan, layeredRoutes, layoutBody, layoutRowPorts, marginOf, measureBody, outlinePath, outlinePolyline, packAcross, packClusters, pinnedSet, planOf, plannerPlan, portLabelBox, portLabelsOf, portOf, portSitesOf, portsOf, portsOnOutline, rankGaps, ranksByLength, ranksOf, rayHit, seededOrder, settle, sizeToBody, translated, tree, untilSettled };
|
|
2864
|
-
//# sourceMappingURL=chunk-
|
|
2865
|
-
//# sourceMappingURL=chunk-
|
|
3243
|
+
export { COMPASS, DEFAULT_GROUP_INSET, DEFAULT_NODE_GAP, DEFAULT_PORTS, DEFAULT_RANK_GAP, DIAGRAM_TRAIT_KEY, PORT_LABEL_GAP, SIDE_TRACK_GAP, anchorOffset, authoredOver, axesFor, backEdges, bodyOutline, bodyTrait, boxForContent, buildBody, canvasMeasure, center, chain, contentBox, createDiagramNodes, dataKeyReader, diagramEdgeOf, diagramNodeOf, expandGroupEdges, extent, footprintNode, force, forceRelaxation, forestOf, graphOrder, grownBy, insetOf, isPinned, isPromise, labelCenter, labelSpotAt, layered, layeredPlan, layeredRoutes, layoutBody, layoutOwnsPort, layoutOwnsRoute, layoutRowPorts, layoutWritesRoute, marginOf, measureBody, outlinePath, outlinePolyline, packAcross, packClusters, pinnedSet, planOf, plannerPlan, portLabelBox, portLabelsOf, portOf, portSitesOf, portsOf, portsOnOutline, rankGaps, ranksByLength, ranksOf, rayHit, routeHolds, samePoints, seededOrder, settle, sizeToBody, subpathOf, translated, tree, untilSettled, widenForMinWidth };
|
|
3244
|
+
//# sourceMappingURL=chunk-R2XB6D32.js.map
|
|
3245
|
+
//# sourceMappingURL=chunk-R2XB6D32.js.map
|