@statelyai/layout 0.5.1 → 0.5.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/elkjs/index.cjs +2 -2
- package/dist/elkjs/index.mjs +2 -2
- package/dist/elkjs/main.cjs +1 -1
- package/dist/elkjs/main.mjs +1 -1
- package/dist/elkjs/worker.cjs +2 -2
- package/dist/elkjs/worker.mjs +2 -2
- package/dist/{elkjs-Dk9yOk9U.mjs → elkjs-DBkalvt1.mjs} +2 -2
- package/dist/{elkjs-Bh_E59N_.cjs → elkjs-DonMqGjf.cjs} +2 -2
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/layered/index.cjs +1 -1
- package/dist/layered/index.mjs +1 -1
- package/dist/{layered-CUwft7on.mjs → layered-CmL7oynw.mjs} +22 -243
- package/dist/{layered-QzYtokgN.cjs → layered-SB2mlAqt.cjs} +22 -243
- package/dist/{layout-engine-DvDkMQM3.mjs → layout-engine-BXoIpYL4.mjs} +1 -1
- package/dist/{layout-engine-CQ5FcBPC.cjs → layout-engine-CAyJ-I-u.cjs} +1 -1
- package/package.json +1 -1
- package/src/layered/index.ts +1 -13
- package/src/layered/loop-envelopes.ts +26 -96
- package/src/layered/strategies.ts +17 -40
- package/src/layered/self-loop-ports.ts +0 -158
package/dist/elkjs/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
2
|
-
require('../layered-
|
|
3
|
-
const require_elkjs = require('../elkjs-
|
|
2
|
+
require('../layered-SB2mlAqt.cjs');
|
|
3
|
+
const require_elkjs = require('../elkjs-DonMqGjf.cjs');
|
|
4
4
|
|
|
5
5
|
exports.compileStatechartLayout = require_elkjs.compileStatechartLayout;
|
|
6
6
|
exports.default = require_elkjs.ELK;
|
package/dist/elkjs/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "../layered-
|
|
2
|
-
import { a as scoreStatechartLayout, i as layoutStatechart, n as getElkRoutes, r as compileStatechartLayout, t as ELK } from "../elkjs-
|
|
1
|
+
import "../layered-CmL7oynw.mjs";
|
|
2
|
+
import { a as scoreStatechartLayout, i as layoutStatechart, n as getElkRoutes, r as compileStatechartLayout, t as ELK } from "../elkjs-DBkalvt1.mjs";
|
|
3
3
|
|
|
4
4
|
export { compileStatechartLayout, ELK as default, getElkRoutes, layoutStatechart, scoreStatechartLayout };
|
package/dist/elkjs/main.cjs
CHANGED
package/dist/elkjs/main.mjs
CHANGED
package/dist/elkjs/worker.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
require('../layered-
|
|
2
|
-
const require_elkjs = require('../elkjs-
|
|
1
|
+
require('../layered-SB2mlAqt.cjs');
|
|
2
|
+
const require_elkjs = require('../elkjs-DonMqGjf.cjs');
|
|
3
3
|
|
|
4
4
|
//#region src/elkjs/worker.ts
|
|
5
5
|
/*******************************************************************************
|
package/dist/elkjs/worker.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import "../layered-
|
|
2
|
-
import { t as ELK } from "../elkjs-
|
|
1
|
+
import "../layered-CmL7oynw.mjs";
|
|
2
|
+
import { t as ELK } from "../elkjs-DBkalvt1.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/elkjs/worker.ts
|
|
5
5
|
/*******************************************************************************
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { E as pathFromPoints, N as freeze, _ as pathFromSplinePoints } from "./routing-D-LfMXOF.mjs";
|
|
2
|
-
import { $ as attachExternalPortDummy, R as createLayerSweepSession, S as CROSSING_MODEL, Z as minimizeHierarchyCrossings, b as elkjs0111ResultPolicy, c as elkLayeredOptionDefinitions, et as createExternalPortDummy, h as separateOpposingTracks, nt as createOrthogonalHypersegments, t as createLayeredScopePipeline, tt as externalPortDummyOf, v as isPerpendicularPortRestored, y as hierarchicalPortSides } from "./layered-
|
|
3
|
-
import { n as executeElkjs0111Layout } from "./layout-engine-
|
|
2
|
+
import { $ as attachExternalPortDummy, R as createLayerSweepSession, S as CROSSING_MODEL, Z as minimizeHierarchyCrossings, b as elkjs0111ResultPolicy, c as elkLayeredOptionDefinitions, et as createExternalPortDummy, h as separateOpposingTracks, nt as createOrthogonalHypersegments, t as createLayeredScopePipeline, tt as externalPortDummyOf, v as isPerpendicularPortRestored, y as hierarchicalPortSides } from "./layered-CmL7oynw.mjs";
|
|
3
|
+
import { n as executeElkjs0111Layout } from "./layout-engine-BXoIpYL4.mjs";
|
|
4
4
|
import { createGraph } from "@statelyai/graph";
|
|
5
5
|
|
|
6
6
|
//#region src/layered/hierarchy-sweepiness.ts
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const require_routing = require('./routing-Phxu1R0x.cjs');
|
|
2
|
-
const require_layered = require('./layered-
|
|
3
|
-
const require_layout_engine = require('./layout-engine-
|
|
2
|
+
const require_layered = require('./layered-SB2mlAqt.cjs');
|
|
3
|
+
const require_layout_engine = require('./layout-engine-CAyJ-I-u.cjs');
|
|
4
4
|
let _statelyai_graph = require("@statelyai/graph");
|
|
5
5
|
|
|
6
6
|
//#region src/layered/hierarchy-sweepiness.ts
|
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const require_routing = require('./routing-Phxu1R0x.cjs');
|
|
2
|
-
const require_layered = require('./layered-
|
|
3
|
-
const require_layout_engine = require('./layout-engine-
|
|
2
|
+
const require_layered = require('./layered-SB2mlAqt.cjs');
|
|
3
|
+
const require_layout_engine = require('./layout-engine-CAyJ-I-u.cjs');
|
|
4
4
|
let _statelyai_graph = require("@statelyai/graph");
|
|
5
5
|
|
|
6
6
|
//#region src/layout.ts
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { C as getPathLength, D as roundCorners, E as pathFromPoints, O as segmentCrossesRect, P as routingPolicies, R as LayoutError, S as getPathBounds, T as getTangentAtLength, _ as pathFromSplinePoints, a as fanRouting, b as routeToPolylines, c as orthogonalRouting, d as routingStrategies, f as selfLoopRouting, g as getLayoutRoutes, h as trimBezierPathStart, i as curvedRouting, k as toSvgPath, l as parallelRouting, m as applyRoutePatches, n as bundleRouting, o as octilinearRouting, p as straightRouting, r as busRouting, s as organicRouting, t as bezierRouting, u as polylineRouting, v as routeToGraphPatch, w as getPointAtLength, x as flattenPath, y as routeToPoints, z as UnsupportedLayoutError } from "./routing-D-LfMXOF.mjs";
|
|
2
|
-
import { A as breakCyclesByStronglyConnectedConnectivity, B as minimizeCrossingsInteractively, C as assignLayersByBreadthFirstModelOrder, D as assignLayersInteractively, E as assignLayersByLongestPathToSink, F as breakCyclesWithDepthFirstSearch, G as placeNodesInteractively, H as minimizeCrossingsWithMedian, I as breakCyclesWithModelOrderBreadthFirstSearch, J as routeEdgesWithPolylines, L as breakCyclesWithModelOrderDepthFirstSearch, M as breakCyclesGreedily, N as breakCyclesGreedilyByModelOrder, O as assignLayersWithCoffmanGraham, P as breakCyclesInteractively, Q as assignLayersWithNetworkSimplex, T as assignLayersByLongestPath, U as minimizeCrossingsWithModelOrder, V as minimizeCrossingsWithBarycenter, W as placeNodesInLayers, Y as routeEdgesWithSplines, _ as statechartHints, a as fromElkLayeredOptionId, c as elkLayeredOptionDefinitions, f as assignLayersWithStretchWidth, g as hint, i as layeredAlgorithm, j as breakCyclesByStronglyConnectedNodeType, k as breakCyclesByModelOrder, m as c, o as toElkLayeredOptions, p as assignLayersWithMinWidth, q as routeEdgesOrthogonally, r as getLayeredLayout, s as elkLayeredEnumValues, w as assignLayersByDepthFirstModelOrder } from "./layered-
|
|
3
|
-
import { a as getSporeCompactionLayout, c as sporeOverlapRemovalAlgorithm, d as getRectanglePackingLayout, f as rectanglePackingAlgorithm, g as getFixedLayout, h as fixedAlgorithm, i as getBuiltInLayoutAlgorithm, l as getRandomLayout, m as getBoxLayout, o as getSporeOverlapRemovalLayout, p as boxAlgorithm, r as executeLayoutAlgorithm, s as sporeCompactionAlgorithm, t as builtInLayoutAlgorithms, u as randomAlgorithm } from "./layout-engine-
|
|
2
|
+
import { A as breakCyclesByStronglyConnectedConnectivity, B as minimizeCrossingsInteractively, C as assignLayersByBreadthFirstModelOrder, D as assignLayersInteractively, E as assignLayersByLongestPathToSink, F as breakCyclesWithDepthFirstSearch, G as placeNodesInteractively, H as minimizeCrossingsWithMedian, I as breakCyclesWithModelOrderBreadthFirstSearch, J as routeEdgesWithPolylines, L as breakCyclesWithModelOrderDepthFirstSearch, M as breakCyclesGreedily, N as breakCyclesGreedilyByModelOrder, O as assignLayersWithCoffmanGraham, P as breakCyclesInteractively, Q as assignLayersWithNetworkSimplex, T as assignLayersByLongestPath, U as minimizeCrossingsWithModelOrder, V as minimizeCrossingsWithBarycenter, W as placeNodesInLayers, Y as routeEdgesWithSplines, _ as statechartHints, a as fromElkLayeredOptionId, c as elkLayeredOptionDefinitions, f as assignLayersWithStretchWidth, g as hint, i as layeredAlgorithm, j as breakCyclesByStronglyConnectedNodeType, k as breakCyclesByModelOrder, m as c, o as toElkLayeredOptions, p as assignLayersWithMinWidth, q as routeEdgesOrthogonally, r as getLayeredLayout, s as elkLayeredEnumValues, w as assignLayersByDepthFirstModelOrder } from "./layered-CmL7oynw.mjs";
|
|
3
|
+
import { a as getSporeCompactionLayout, c as sporeOverlapRemovalAlgorithm, d as getRectanglePackingLayout, f as rectanglePackingAlgorithm, g as getFixedLayout, h as fixedAlgorithm, i as getBuiltInLayoutAlgorithm, l as getRandomLayout, m as getBoxLayout, o as getSporeOverlapRemovalLayout, p as boxAlgorithm, r as executeLayoutAlgorithm, s as sporeCompactionAlgorithm, t as builtInLayoutAlgorithms, u as randomAlgorithm } from "./layout-engine-BXoIpYL4.mjs";
|
|
4
4
|
import { getGraphIssues } from "@statelyai/graph";
|
|
5
5
|
|
|
6
6
|
//#region src/layout.ts
|
package/dist/layered/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_layered = require('../layered-
|
|
1
|
+
const require_layered = require('../layered-SB2mlAqt.cjs');
|
|
2
2
|
|
|
3
3
|
exports.assignLayersByBreadthFirstModelOrder = require_layered.assignLayersByBreadthFirstModelOrder;
|
|
4
4
|
exports.assignLayersByDepthFirstModelOrder = require_layered.assignLayersByDepthFirstModelOrder;
|
package/dist/layered/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { A as breakCyclesByStronglyConnectedConnectivity, B as minimizeCrossingsInteractively, C as assignLayersByBreadthFirstModelOrder, D as assignLayersInteractively, E as assignLayersByLongestPathToSink, F as breakCyclesWithDepthFirstSearch, G as placeNodesInteractively, H as minimizeCrossingsWithMedian, I as breakCyclesWithModelOrderBreadthFirstSearch, J as routeEdgesWithPolylines, L as breakCyclesWithModelOrderDepthFirstSearch, M as breakCyclesGreedily, N as breakCyclesGreedilyByModelOrder, O as assignLayersWithCoffmanGraham, P as breakCyclesInteractively, Q as assignLayersWithNetworkSimplex, T as assignLayersByLongestPath, U as minimizeCrossingsWithModelOrder, V as minimizeCrossingsWithBarycenter, W as placeNodesInLayers, Y as routeEdgesWithSplines, a as fromElkLayeredOptionId, c as elkLayeredOptionDefinitions, d as placeNodesWithBrandesKoepf, f as assignLayersWithStretchWidth, i as layeredAlgorithm, j as breakCyclesByStronglyConnectedNodeType, k as breakCyclesByModelOrder, l as placeNodesWithNetworkSimplex, n as elkjs0111LayeredAlgorithm, o as toElkLayeredOptions, p as assignLayersWithMinWidth, q as routeEdgesOrthogonally, r as getLayeredLayout, s as elkLayeredEnumValues, t as createLayeredScopePipeline, u as placeNodesWithLinearSegments, w as assignLayersByDepthFirstModelOrder } from "../layered-
|
|
1
|
+
import { A as breakCyclesByStronglyConnectedConnectivity, B as minimizeCrossingsInteractively, C as assignLayersByBreadthFirstModelOrder, D as assignLayersInteractively, E as assignLayersByLongestPathToSink, F as breakCyclesWithDepthFirstSearch, G as placeNodesInteractively, H as minimizeCrossingsWithMedian, I as breakCyclesWithModelOrderBreadthFirstSearch, J as routeEdgesWithPolylines, L as breakCyclesWithModelOrderDepthFirstSearch, M as breakCyclesGreedily, N as breakCyclesGreedilyByModelOrder, O as assignLayersWithCoffmanGraham, P as breakCyclesInteractively, Q as assignLayersWithNetworkSimplex, T as assignLayersByLongestPath, U as minimizeCrossingsWithModelOrder, V as minimizeCrossingsWithBarycenter, W as placeNodesInLayers, Y as routeEdgesWithSplines, a as fromElkLayeredOptionId, c as elkLayeredOptionDefinitions, d as placeNodesWithBrandesKoepf, f as assignLayersWithStretchWidth, i as layeredAlgorithm, j as breakCyclesByStronglyConnectedNodeType, k as breakCyclesByModelOrder, l as placeNodesWithNetworkSimplex, n as elkjs0111LayeredAlgorithm, o as toElkLayeredOptions, p as assignLayersWithMinWidth, q as routeEdgesOrthogonally, r as getLayeredLayout, s as elkLayeredEnumValues, t as createLayeredScopePipeline, u as placeNodesWithLinearSegments, w as assignLayersByDepthFirstModelOrder } from "../layered-CmL7oynw.mjs";
|
|
2
2
|
|
|
3
3
|
export { assignLayersByBreadthFirstModelOrder, assignLayersByDepthFirstModelOrder, assignLayersByLongestPath, assignLayersByLongestPathToSink, assignLayersInteractively, assignLayersWithCoffmanGraham, assignLayersWithMinWidth, assignLayersWithNetworkSimplex, assignLayersWithStretchWidth, breakCyclesByModelOrder, breakCyclesByStronglyConnectedConnectivity, breakCyclesByStronglyConnectedNodeType, breakCyclesGreedily, breakCyclesGreedilyByModelOrder, breakCyclesInteractively, breakCyclesWithDepthFirstSearch, breakCyclesWithModelOrderBreadthFirstSearch, breakCyclesWithModelOrderDepthFirstSearch, createLayeredScopePipeline, elkLayeredEnumValues, elkLayeredOptionDefinitions, elkjs0111LayeredAlgorithm, fromElkLayeredOptionId, getLayeredLayout, layeredAlgorithm, minimizeCrossingsInteractively, minimizeCrossingsWithBarycenter, minimizeCrossingsWithMedian, minimizeCrossingsWithModelOrder, placeNodesInLayers, placeNodesInteractively, placeNodesWithBrandesKoepf, placeNodesWithLinearSegments, placeNodesWithNetworkSimplex, routeEdgesOrthogonally, routeEdgesWithPolylines, routeEdgesWithSplines, toElkLayeredOptions };
|
|
@@ -1608,174 +1608,8 @@ function findNode(nodes, id) {
|
|
|
1608
1608
|
return position !== void 0 && nodes[position]?.id === id ? nodes[position] : nodes.find((node) => node.id === id);
|
|
1609
1609
|
}
|
|
1610
1610
|
|
|
1611
|
-
//#endregion
|
|
1612
|
-
//#region src/layered/self-loop-ports.ts
|
|
1613
|
-
const hiddenBySettings = /* @__PURE__ */ new WeakMap();
|
|
1614
|
-
/** Sizes of the ports SelfLoopPreProcessor hid from a loop, if any. */
|
|
1615
|
-
function hiddenLoopPorts(settings, edgeId) {
|
|
1616
|
-
return hiddenBySettings.get(settings)?.get(edgeId);
|
|
1617
|
-
}
|
|
1618
|
-
/**
|
|
1619
|
-
* ELK's SelfLoopPreProcessor removes ports that carry only self loops from
|
|
1620
|
-
* nodes whose port order is not fixed, and SelfLoopPortRestorer later puts
|
|
1621
|
-
* them on the loop's side. The layered phases then see implicit loop ports;
|
|
1622
|
-
* {@link restoreSelfLoopPorts} places the hidden ports at the loop ends.
|
|
1623
|
-
*/
|
|
1624
|
-
function hideSelfLoopPorts(graph, options) {
|
|
1625
|
-
const uses = /* @__PURE__ */ new Map();
|
|
1626
|
-
const nonLoop = /* @__PURE__ */ new Set();
|
|
1627
|
-
for (const edge of graph.edges) for (const [node, port] of [[edge.sourceId, edge.sourcePort], [edge.targetId, edge.targetPort]]) {
|
|
1628
|
-
if (port === void 0) continue;
|
|
1629
|
-
const key = `${node}\0${port}`;
|
|
1630
|
-
uses.set(key, (uses.get(key) ?? 0) + 1);
|
|
1631
|
-
if (edge.sourceId !== edge.targetId) nonLoop.add(key);
|
|
1632
|
-
}
|
|
1633
|
-
const nodeById = new Map(graph.nodes.map((node) => [node.id, node]));
|
|
1634
|
-
const hidden = /* @__PURE__ */ new Map();
|
|
1635
|
-
const edges = /* @__PURE__ */ new Map();
|
|
1636
|
-
const hiddenPorts = /* @__PURE__ */ new Set();
|
|
1637
|
-
for (const edge of graph.edges) {
|
|
1638
|
-
if (edge.sourceId !== edge.targetId || edge.sourcePort === void 0 || edge.targetPort === void 0 || edge.sourcePort === edge.targetPort) continue;
|
|
1639
|
-
const node = nodeById.get(edge.sourceId);
|
|
1640
|
-
const constraints = node && options.nodeSettings?.(node)?.portConstraints;
|
|
1641
|
-
if (!node || constraints !== void 0 && constraints !== "FREE" && constraints !== "UNDEFINED") continue;
|
|
1642
|
-
const ports = [edge.sourcePort, edge.targetPort].map((name) => node.ports?.find((port) => port.name === name));
|
|
1643
|
-
if (ports.some((port) => !port || uses.get(`${node.id}\0${port.name}`) !== 1 || nonLoop.has(`${node.id}\0${port.name}`))) continue;
|
|
1644
|
-
const size$1 = (port) => ({
|
|
1645
|
-
width: port.width ?? 0,
|
|
1646
|
-
height: port.height ?? 0
|
|
1647
|
-
});
|
|
1648
|
-
hidden.set(edge.id, {
|
|
1649
|
-
source: size$1(ports[0]),
|
|
1650
|
-
target: size$1(ports[1])
|
|
1651
|
-
});
|
|
1652
|
-
edges.set(edge.id, edge);
|
|
1653
|
-
for (const port of ports) hiddenPorts.add(`${node.id}\0${port.name}`);
|
|
1654
|
-
}
|
|
1655
|
-
if (hidden.size === 0) return void 0;
|
|
1656
|
-
const settings = { ...options.settings };
|
|
1657
|
-
hiddenBySettings.set(settings, hidden);
|
|
1658
|
-
return {
|
|
1659
|
-
graph: {
|
|
1660
|
-
...graph,
|
|
1661
|
-
nodes: graph.nodes.map((node) => node.ports?.some((port) => hiddenPorts.has(`${node.id}\0${port.name}`)) ? {
|
|
1662
|
-
...node,
|
|
1663
|
-
ports: node.ports.filter((port) => !hiddenPorts.has(`${node.id}\0${port.name}`))
|
|
1664
|
-
} : node),
|
|
1665
|
-
edges: graph.edges.map((edge) => hidden.has(edge.id) ? {
|
|
1666
|
-
...edge,
|
|
1667
|
-
sourcePort: void 0,
|
|
1668
|
-
targetPort: void 0
|
|
1669
|
-
} : edge)
|
|
1670
|
-
},
|
|
1671
|
-
options: {
|
|
1672
|
-
...options,
|
|
1673
|
-
settings
|
|
1674
|
-
},
|
|
1675
|
-
edges
|
|
1676
|
-
};
|
|
1677
|
-
}
|
|
1678
|
-
/** Put hidden loop ports back, anchored on the side their loop leaves from. */
|
|
1679
|
-
function restoreSelfLoopPorts(graph, result, edges) {
|
|
1680
|
-
const anchors = /* @__PURE__ */ new Map();
|
|
1681
|
-
for (const edge of result.edges) {
|
|
1682
|
-
const original = edges.get(edge.id);
|
|
1683
|
-
const points = edge.points;
|
|
1684
|
-
if (!original || !points?.length) continue;
|
|
1685
|
-
anchors.set(`${edge.sourceId}\0${original.sourcePort}`, points[0]);
|
|
1686
|
-
anchors.set(`${edge.targetId}\0${original.targetPort}`, points.at(-1));
|
|
1687
|
-
}
|
|
1688
|
-
const originalById = new Map(graph.nodes.map((node) => [node.id, node]));
|
|
1689
|
-
return {
|
|
1690
|
-
...result,
|
|
1691
|
-
nodes: result.nodes.map((node) => {
|
|
1692
|
-
const original = originalById.get(node.id)?.ports;
|
|
1693
|
-
if (!original?.some((port) => anchors.has(`${node.id}\0${port.name}`))) return node;
|
|
1694
|
-
const placed = new Map(node.ports?.map((port) => [port.name, port]));
|
|
1695
|
-
return {
|
|
1696
|
-
...node,
|
|
1697
|
-
ports: original.map((port) => {
|
|
1698
|
-
const anchor = anchors.get(`${node.id}\0${port.name}`);
|
|
1699
|
-
const width = port.width ?? 0, height = port.height ?? 0;
|
|
1700
|
-
if (!anchor) return placed.get(port.name) ?? {
|
|
1701
|
-
...port,
|
|
1702
|
-
width,
|
|
1703
|
-
height,
|
|
1704
|
-
x: 0,
|
|
1705
|
-
y: 0
|
|
1706
|
-
};
|
|
1707
|
-
const x = anchor.x - node.x, y = anchor.y - node.y;
|
|
1708
|
-
return {
|
|
1709
|
-
...port,
|
|
1710
|
-
width,
|
|
1711
|
-
height,
|
|
1712
|
-
x: x <= 0 ? x : x >= node.width ? x - width : x - width / 2,
|
|
1713
|
-
y: x <= 0 || x >= node.width ? y - height / 2 : y <= 0 ? y : y - height
|
|
1714
|
-
};
|
|
1715
|
-
})
|
|
1716
|
-
};
|
|
1717
|
-
}),
|
|
1718
|
-
edges: result.edges.map((edge) => {
|
|
1719
|
-
const original = edges.get(edge.id);
|
|
1720
|
-
return original ? {
|
|
1721
|
-
...edge,
|
|
1722
|
-
sourcePort: original.sourcePort,
|
|
1723
|
-
targetPort: original.targetPort
|
|
1724
|
-
} : edge;
|
|
1725
|
-
})
|
|
1726
|
-
};
|
|
1727
|
-
}
|
|
1728
|
-
|
|
1729
1611
|
//#endregion
|
|
1730
1612
|
//#region src/layered/loop-envelopes.ts
|
|
1731
|
-
const crossSide = (side) => side === "NORTH" || side === "SOUTH";
|
|
1732
|
-
/**
|
|
1733
|
-
* Extents of a movable loop's hidden ports in the canonical rightward frame:
|
|
1734
|
-
* along its side, and protruding from it.
|
|
1735
|
-
*/
|
|
1736
|
-
function loopPortExtents(input, edge, side) {
|
|
1737
|
-
const ports = hiddenLoopPorts(input.settings, edge.id);
|
|
1738
|
-
const horizontal$1 = input.direction === "right" || input.direction === "left";
|
|
1739
|
-
const along = crossSide(side) === horizontal$1 ? "width" : "height";
|
|
1740
|
-
const normal = along === "width" ? "height" : "width";
|
|
1741
|
-
return {
|
|
1742
|
-
along: ports ? ports.source[along] + ports.target[along] : 0,
|
|
1743
|
-
normal: ports ? Math.max(ports.source[normal], ports.target[normal]) : 0
|
|
1744
|
-
};
|
|
1745
|
-
}
|
|
1746
|
-
/** A movable loop's label extent away from its side, in the canonical frame. */
|
|
1747
|
-
function movableLoopLabelExtent(input, edge, side) {
|
|
1748
|
-
const horizontal$1 = input.direction === "right" || input.direction === "left";
|
|
1749
|
-
const size$1 = (crossSide(side) === horizontal$1 ? edge.height : edge.width) ?? 0;
|
|
1750
|
-
return size$1 > 0 ? size$1 + Number(input.settings["spacing.edgeLabel"] ?? 2) : 0;
|
|
1751
|
-
}
|
|
1752
|
-
/**
|
|
1753
|
-
* ELK's OrthogonalSelfLoopRouter routing slot of a movable loop, measured
|
|
1754
|
-
* from its node side in the canonical frame: past the protruding ports and
|
|
1755
|
-
* the self-loop spacing, then one edge spacing plus any label per inner slot.
|
|
1756
|
-
*/
|
|
1757
|
-
function movableLoopTrack(input, sideLoops, edge, side, ordering) {
|
|
1758
|
-
const ordered = ordering === "REVERSE_STACKED" ? [...sideLoops].reverse() : sideLoops;
|
|
1759
|
-
const inner = ordering === "SEQUENCED" ? [] : ordered.slice(0, ordered.indexOf(edge));
|
|
1760
|
-
const edgeSpacing = Number(input.settings["spacing.edgeEdge"] ?? 10);
|
|
1761
|
-
return Math.max(0, ...sideLoops.map((loop) => loopPortExtents(input, loop, side).normal)) + Number(input.settings["spacing.nodeSelfLoop"] ?? 10) + inner.reduce((sum, loop) => sum + edgeSpacing + (crossSide(side) ? movableLoopLabelExtent(input, loop, side) : 0), 0);
|
|
1762
|
-
}
|
|
1763
|
-
/**
|
|
1764
|
-
* Canonical position of a movable loop port along its side, given its
|
|
1765
|
-
* DISTRIBUTED ratio among the side's implicit ports (ELK's port placement
|
|
1766
|
-
* with equal gaps between hidden ports of their own size).
|
|
1767
|
-
*/
|
|
1768
|
-
function movableLoopPortOffset(input, sideLoops, side, length, ratio) {
|
|
1769
|
-
const count = sideLoops.length * 2;
|
|
1770
|
-
const extents = sideLoops.map((loop) => loopPortExtents(input, loop, side));
|
|
1771
|
-
const total = extents.reduce((sum, extent$2) => sum + extent$2.along, 0);
|
|
1772
|
-
const size$1 = total / count;
|
|
1773
|
-
const index = Math.round(ratio * (count + 1)) - 1;
|
|
1774
|
-
return {
|
|
1775
|
-
along: (length - total) / (count + 1) * (index + 1) + size$1 * index + size$1 / 2,
|
|
1776
|
-
normal: Math.max(0, ...extents.map((extent$2) => extent$2.normal))
|
|
1777
|
-
};
|
|
1778
|
-
}
|
|
1779
1613
|
/** Unconstrained implicit loop ports are restored on loop faces after the sweep. */
|
|
1780
1614
|
function hasMovableLoopPorts(input, edge) {
|
|
1781
1615
|
if (edge.sourceId !== edge.targetId || edge.sourcePort !== void 0 || edge.targetPort !== void 0) return false;
|
|
@@ -1813,7 +1647,7 @@ function loopEnvelopes(input) {
|
|
|
1813
1647
|
};
|
|
1814
1648
|
const horizontal$1 = input.direction === "right" || input.direction === "left";
|
|
1815
1649
|
const reverse = input.direction === "left" || input.direction === "up";
|
|
1816
|
-
const spacing = Number(input.settings["spacing.nodeSelfLoop"] ?? 10);
|
|
1650
|
+
const spacing$1 = Number(input.settings["spacing.nodeSelfLoop"] ?? 10);
|
|
1817
1651
|
let supported = true;
|
|
1818
1652
|
const tracks = selfLoopTracks(allLoops);
|
|
1819
1653
|
for (const edge of allLoops) {
|
|
@@ -1832,7 +1666,7 @@ function loopEnvelopes(input) {
|
|
|
1832
1666
|
}, input.direction, input), getPortPoint(node, edge.targetPort, rect, {
|
|
1833
1667
|
x: 0,
|
|
1834
1668
|
y: 0
|
|
1835
|
-
}, input.direction, input), sourceSide, targetSide, spacing * (tracks.get(edge.id) + 1), input.direction);
|
|
1669
|
+
}, input.direction, input), sourceSide, targetSide, spacing$1 * (tracks.get(edge.id) + 1), input.direction);
|
|
1836
1670
|
if (labeled) {
|
|
1837
1671
|
const labelSpacing = Number(input.settings["spacing.edgeLabel"] ?? 2);
|
|
1838
1672
|
const { width = 0, height = 0 } = edge;
|
|
@@ -1857,10 +1691,11 @@ function loopEnvelopes(input) {
|
|
|
1857
1691
|
}
|
|
1858
1692
|
}
|
|
1859
1693
|
const loops = allLoops.filter((edge) => hasMovableLoopPorts(input, edge));
|
|
1860
|
-
if (loops.length === 0) continue;
|
|
1694
|
+
if (loops.length === 0 || loops.some((edge) => input.edgeSettings?.(edge)?.["edgeLabels.inline"] === true)) continue;
|
|
1861
1695
|
const settings = input.nodeSettings?.(node);
|
|
1862
1696
|
const distribution = settings?.["edgeRouting.selfLoopDistribution"] ?? "NORTH";
|
|
1863
1697
|
const ordering = settings?.["edgeRouting.selfLoopOrdering"] ?? "STACKED";
|
|
1698
|
+
const spacing = Number(input.settings["spacing.nodeSelfLoop"] ?? 10);
|
|
1864
1699
|
const envelope = {
|
|
1865
1700
|
before: 0,
|
|
1866
1701
|
after: 0,
|
|
@@ -1873,16 +1708,12 @@ function loopEnvelopes(input) {
|
|
|
1873
1708
|
"flowAfter",
|
|
1874
1709
|
"flowBefore"
|
|
1875
1710
|
] : distribution === "NORTH_SOUTH" ? ["before", "after"] : ["before"];
|
|
1876
|
-
const canonicalSides = {
|
|
1877
|
-
before: "NORTH",
|
|
1878
|
-
after: "SOUTH",
|
|
1879
|
-
flowAfter: "EAST",
|
|
1880
|
-
flowBefore: "WEST"
|
|
1881
|
-
};
|
|
1882
1711
|
for (const side of sides$1) {
|
|
1883
1712
|
const selected = loops.filter((_, index) => sides$1[index % sides$1.length] === side);
|
|
1884
|
-
const
|
|
1885
|
-
|
|
1713
|
+
const horizontal$1 = input.direction === "right" || input.direction === "left";
|
|
1714
|
+
const crossSize$3 = side === "before" || side === "after" ? horizontal$1 ? "height" : "width" : horizontal$1 ? "width" : "height";
|
|
1715
|
+
const labelSpacing = Number(input.settings["spacing.edgeLabel"] ?? 2);
|
|
1716
|
+
envelope[side] = spacing * (ordering === "SEQUENCED" ? Math.min(1, selected.length) : selected.length) + selected.reduce((sum, edge) => sum + ((edge[crossSize$3] ?? 0) > 0 ? (edge[crossSize$3] ?? 0) + labelSpacing : 0), 0);
|
|
1886
1717
|
}
|
|
1887
1718
|
envelopes.set(node.id, envelope);
|
|
1888
1719
|
}
|
|
@@ -3050,7 +2881,7 @@ function compactJoinedGeometryUnchecked(input, placement, routes, orientation) {
|
|
|
3050
2881
|
if (point.x >= rect.x + rect.width - 1e-9) return "EAST";
|
|
3051
2882
|
return point.y <= rect.y ? "NORTH" : "SOUTH";
|
|
3052
2883
|
};
|
|
3053
|
-
const crossSide
|
|
2884
|
+
const crossSide = (side) => side === "NORTH" || side === "SOUTH";
|
|
3054
2885
|
const segments = [];
|
|
3055
2886
|
for (const [edgeId, points] of canonicalRoutes) {
|
|
3056
2887
|
const edge = edgeById.get(edgeId);
|
|
@@ -3060,8 +2891,8 @@ function compactJoinedGeometryUnchecked(input, placement, routes, orientation) {
|
|
|
3060
2891
|
const first = points[index];
|
|
3061
2892
|
const second = points[index + 1];
|
|
3062
2893
|
if (Math.abs(first.x - second.x) > 1e-9 || Math.abs(first.y - second.y) < 1e-9) continue;
|
|
3063
|
-
if (index === 0 && !crossSide
|
|
3064
|
-
if (index === points.length - 2 && !crossSide
|
|
2894
|
+
if (index === 0 && !crossSide(endpointSide(edge.sourceId, edge.sourcePort, first))) continue;
|
|
2895
|
+
if (index === points.length - 2 && !crossSide(endpointSide(edge.targetId, edge.targetPort, second))) continue;
|
|
3065
2896
|
const owner = index === 0 ? nodes.get(edge.sourceId) : index === points.length - 2 ? nodes.get(edge.targetId) : void 0;
|
|
3066
2897
|
const ownerSide = owner ? endpointSide(index === 0 ? edge.sourceId : edge.targetId, index === 0 ? edge.sourcePort : edge.targetPort, index === 0 ? first : second) : void 0;
|
|
3067
2898
|
const bend = index === 0 ? second : first;
|
|
@@ -3224,7 +3055,7 @@ function compactJoinedGeometryUnchecked(input, placement, routes, orientation) {
|
|
|
3224
3055
|
const points = canonicalRoutes.get(edge.id);
|
|
3225
3056
|
const sourceSide = endpointSide(edge.sourceId, edge.sourcePort, points?.[0]);
|
|
3226
3057
|
const targetSide = endpointSide(edge.targetId, edge.targetPort, points?.at(-1));
|
|
3227
|
-
if (crossSide
|
|
3058
|
+
if (crossSide(sourceSide) && crossSide(targetSide)) continue;
|
|
3228
3059
|
const reversed = orientation?.reversedEdgeIds.has(edge.id) ?? source.x > target.x;
|
|
3229
3060
|
const from = reversed ? target : source, to = reversed ? source : target;
|
|
3230
3061
|
constraints.push({
|
|
@@ -3318,8 +3149,8 @@ function compactJoinedGeometryUnchecked(input, placement, routes, orientation) {
|
|
|
3318
3149
|
const start = pointToCanonical(originals[0]);
|
|
3319
3150
|
const next = pointToCanonical(originals[1]);
|
|
3320
3151
|
const previous = pointToCanonical(originals.at(-2));
|
|
3321
|
-
if (!crossSide
|
|
3322
|
-
if (!crossSide
|
|
3152
|
+
if (!crossSide(endpointSide(edge.sourceId, edge.sourcePort, start)) && Math.abs(start.x - next.x) < 1e-9) points[1].x = points[0].x;
|
|
3153
|
+
if (!crossSide(endpointSide(edge.targetId, edge.targetPort, end)) && Math.abs(end.x - previous.x) < 1e-9) points[points.length - 2].x = points.at(-1).x;
|
|
3323
3154
|
}
|
|
3324
3155
|
}
|
|
3325
3156
|
const extent$2 = Math.max(...items.map((item) => item.x + item.width), ...[...canonicalRoutes.values()].flatMap((points) => points.map((point) => point.x)));
|
|
@@ -6596,13 +6427,13 @@ function routeEdges(style) {
|
|
|
6596
6427
|
"WEST"
|
|
6597
6428
|
][index % 4] : distribution === "NORTH_SOUTH" && index % 2 === 1 ? "SOUTH" : "NORTH";
|
|
6598
6429
|
};
|
|
6599
|
-
const loopDistance = (loops, edge, side, ordering) => {
|
|
6600
|
-
const axis = side === "NORTH" || side === "SOUTH" ? "height" : "width";
|
|
6430
|
+
const loopDistance = (loops, edge, side, ordering, canonical = false) => {
|
|
6431
|
+
const axis = (side === "NORTH" || side === "SOUTH") === (!canonical || horizontal$1) ? "height" : "width";
|
|
6601
6432
|
const ordered = ordering === "REVERSE_STACKED" ? [...loops].reverse() : loops;
|
|
6602
6433
|
const index = ordered.indexOf(edge);
|
|
6603
6434
|
const spacing = Number(input.settings["spacing.nodeSelfLoop"] ?? 10);
|
|
6604
6435
|
const labelSpacing = Number(input.settings["spacing.edgeLabel"] ?? 2);
|
|
6605
|
-
const size$1 = (candidate) => input.edgeSettings?.(candidate)?.["edgeLabels.inline"] === true ? candidate[axis] ?? 0 : 0;
|
|
6436
|
+
const size$1 = (candidate) => canonical || input.edgeSettings?.(candidate)?.["edgeLabels.inline"] === true ? candidate[axis] ?? 0 : 0;
|
|
6606
6437
|
return spacing * (ordering === "SEQUENCED" ? 1 : index + 1) + ordered.slice(0, index).reduce((extent$2, candidate) => extent$2 + (size$1(candidate) > 0 ? size$1(candidate) + labelSpacing : 0), 0) + (size$1(edge) > 0 && input.edgeSettings?.(edge)?.["edgeLabels.inline"] === true ? size$1(edge) / 2 + labelSpacing : 0);
|
|
6607
6438
|
};
|
|
6608
6439
|
const hasFixedLoopPorts = (node) => {
|
|
@@ -6657,7 +6488,7 @@ function routeEdges(style) {
|
|
|
6657
6488
|
for (const [id, loops] of selfLoopsByNodeId) {
|
|
6658
6489
|
const rect = mutableRects.get(id);
|
|
6659
6490
|
const node = nodeById.get(id);
|
|
6660
|
-
if (!rect || !node
|
|
6491
|
+
if (!rect || !node) continue;
|
|
6661
6492
|
const settings = input.nodeSettings?.(node);
|
|
6662
6493
|
const distribution = settings?.["edgeRouting.selfLoopDistribution"] ?? "NORTH";
|
|
6663
6494
|
const ordering = settings?.["edgeRouting.selfLoopOrdering"] ?? "STACKED";
|
|
@@ -7772,7 +7603,7 @@ function routeEdges(style) {
|
|
|
7772
7603
|
outsideFeedbackEdgeIds.add(edge.id);
|
|
7773
7604
|
continue;
|
|
7774
7605
|
}
|
|
7775
|
-
const movable = hasMovableLoopPorts(input, edge) && hasPlacementLoopEnvelope(placement, source.id);
|
|
7606
|
+
const movable = hasMovableLoopPorts(input, edge) && hasPlacementLoopEnvelope(placement, source.id) && input.edgeSettings?.(edge)?.["edgeLabels.inline"] !== true;
|
|
7776
7607
|
const loopRect = movable ? {
|
|
7777
7608
|
x: 0,
|
|
7778
7609
|
y: 0,
|
|
@@ -7812,32 +7643,7 @@ function routeEdges(style) {
|
|
|
7812
7643
|
startRatio = (countOnSide + nestingIndex + 1) / denominator;
|
|
7813
7644
|
endRatio = (countOnSide - nestingIndex) / denominator;
|
|
7814
7645
|
}
|
|
7815
|
-
const
|
|
7816
|
-
if (movable) {
|
|
7817
|
-
const track$1 = movableLoopTrack(input, sideLoops, edge, side, ordering);
|
|
7818
|
-
const sign = side === "NORTH" ? -1 : 1;
|
|
7819
|
-
const base = side === "NORTH" ? 0 : loopRect.height;
|
|
7820
|
-
const [first, last] = [startRatio, endRatio].map((ratio) => movableLoopPortOffset(input, sideLoops, side, loopRect.width, ratio));
|
|
7821
|
-
return [
|
|
7822
|
-
{
|
|
7823
|
-
x: first.along,
|
|
7824
|
-
y: base + sign * first.normal
|
|
7825
|
-
},
|
|
7826
|
-
{
|
|
7827
|
-
x: first.along,
|
|
7828
|
-
y: base + sign * track$1
|
|
7829
|
-
},
|
|
7830
|
-
{
|
|
7831
|
-
x: last.along,
|
|
7832
|
-
y: base + sign * track$1
|
|
7833
|
-
},
|
|
7834
|
-
{
|
|
7835
|
-
x: last.along,
|
|
7836
|
-
y: base + sign * last.normal
|
|
7837
|
-
}
|
|
7838
|
-
];
|
|
7839
|
-
}
|
|
7840
|
-
const distance = loopDistance(sideLoops, edge, side, ordering);
|
|
7646
|
+
const distance = loopDistance(loops.filter((candidate, i) => loopSide(distribution, i, candidate) === side), edge, side, ordering, movable);
|
|
7841
7647
|
const y = side === "NORTH" ? loopRect.y - distance : loopRect.y + loopRect.height + distance;
|
|
7842
7648
|
const start$2 = {
|
|
7843
7649
|
x: loopRect.x + loopRect.width * startRatio,
|
|
@@ -7867,32 +7673,7 @@ function routeEdges(style) {
|
|
|
7867
7673
|
const secondRatio = sequenced ? 1 / denominator : 2 / denominator;
|
|
7868
7674
|
const startRatio = side === "EAST" ? firstRatio : secondRatio;
|
|
7869
7675
|
const endRatio = side === "EAST" ? secondRatio : firstRatio;
|
|
7870
|
-
const
|
|
7871
|
-
if (movable) {
|
|
7872
|
-
const track$1 = movableLoopTrack(input, sideLoops, edge, side, ordering);
|
|
7873
|
-
const sign = side === "WEST" ? -1 : 1;
|
|
7874
|
-
const base = side === "WEST" ? 0 : loopRect.width;
|
|
7875
|
-
const [first, last] = [startRatio, endRatio].map((ratio) => movableLoopPortOffset(input, sideLoops, side, loopRect.height, ratio));
|
|
7876
|
-
return [
|
|
7877
|
-
{
|
|
7878
|
-
x: base + sign * first.normal,
|
|
7879
|
-
y: first.along
|
|
7880
|
-
},
|
|
7881
|
-
{
|
|
7882
|
-
x: base + sign * track$1,
|
|
7883
|
-
y: first.along
|
|
7884
|
-
},
|
|
7885
|
-
{
|
|
7886
|
-
x: base + sign * track$1,
|
|
7887
|
-
y: last.along
|
|
7888
|
-
},
|
|
7889
|
-
{
|
|
7890
|
-
x: base + sign * last.normal,
|
|
7891
|
-
y: last.along
|
|
7892
|
-
}
|
|
7893
|
-
];
|
|
7894
|
-
}
|
|
7895
|
-
const distance = input.edgeSettings?.(edge)?.["edgeLabels.inline"] === true ? loopDistance(sideLoops, edge, side, ordering) : spacing * (indexOnSide + 1);
|
|
7676
|
+
const distance = movable || input.edgeSettings?.(edge)?.["edgeLabels.inline"] === true ? loopDistance(loops.filter((candidate, i) => loopSide(distribution, i, candidate) === side), edge, side, ordering, movable) : spacing * (indexOnSide + 1);
|
|
7896
7677
|
const x = side === "EAST" ? loopRect.x + loopRect.width + distance : loopRect.x - distance;
|
|
7897
7678
|
const start$2 = {
|
|
7898
7679
|
x: side === "EAST" ? loopRect.x + loopRect.width : loopRect.x,
|
|
@@ -19155,8 +18936,6 @@ function* createLayeredScopePipeline(graph, options, context, fallbacks = {
|
|
|
19155
18936
|
const separated$1 = runSeparatedComponents(graph, options, context);
|
|
19156
18937
|
if (separated$1) return separated$1;
|
|
19157
18938
|
}
|
|
19158
|
-
const hiddenLoopPorts$1 = hideSelfLoopPorts(graph, options);
|
|
19159
|
-
if (hiddenLoopPorts$1) return restoreSelfLoopPorts(graph, yield* createLayeredScopePipeline(hiddenLoopPorts$1.graph, hiddenLoopPorts$1.options, context, fallbacks), hiddenLoopPorts$1.edges);
|
|
19160
18939
|
const direction = options.direction ?? graph.direction ?? "right";
|
|
19161
18940
|
const padding = typeof options.padding === "number" ? {
|
|
19162
18941
|
top: options.padding,
|
|
@@ -20238,7 +20017,7 @@ function* createLayeredScopePipeline(graph, options, context, fallbacks = {
|
|
|
20238
20017
|
y: (points[1].y + points[2].y - height) / 2
|
|
20239
20018
|
} : void 0;
|
|
20240
20019
|
const movableExteriorLoopLabelPosition = (() => {
|
|
20241
|
-
if (edgeRouting !== "ORTHOGONAL" || labelPlacement !== "CENTER" || !hasMovableLoopPorts(input, edge) || !sourceRect || points.length !== 4) return void 0;
|
|
20020
|
+
if (edgeRouting !== "ORTHOGONAL" || labelPlacement !== "CENTER" || inlineLabel || !hasMovableLoopPorts(input, edge) || !sourceRect || points.length !== 4) return void 0;
|
|
20242
20021
|
const first = points[1], last = points[2];
|
|
20243
20022
|
if (first.y === last.y) {
|
|
20244
20023
|
const low = first.y < sourceRect.y;
|