@dagrejs/dagre 1.0.4 → 1.1.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/index.d.ts +10 -2
- package/lib/acyclic.js +10 -18
- package/lib/add-border-segments.js +19 -11
- package/lib/coordinate-system.js +5 -15
- package/lib/data/list.js +8 -7
- package/lib/debug.js +25 -14
- package/lib/greedy-fas.js +35 -30
- package/lib/index.js +38 -0
- package/lib/layout.js +105 -102
- package/lib/nesting-graph.js +18 -21
- package/lib/normalize.js +22 -18
- package/lib/order/add-subgraph-constraints.js +6 -2
- package/lib/order/barycenter.js +14 -6
- package/lib/order/build-layer-graph.js +19 -13
- package/lib/order/cross-count.js +13 -10
- package/lib/order/index.js +33 -24
- package/lib/order/init-order.js +8 -7
- package/lib/order/resolve-conflicts.js +9 -19
- package/lib/order/sort-subgraph.js +16 -22
- package/lib/order/sort.js +13 -12
- package/lib/parent-dummy-chains.js +17 -19
- package/lib/position/bk.js +42 -84
- package/lib/position/index.js +10 -9
- package/lib/rank/feasible-tree.js +14 -17
- package/lib/rank/index.js +25 -15
- package/lib/rank/network-simplex.js +18 -39
- package/lib/rank/util.js +6 -12
- package/lib/util.js +42 -57
- package/lib/version.js +8 -1
- package/mjs-lib/acyclic.js +62 -0
- package/mjs-lib/add-border-segments.js +35 -0
- package/mjs-lib/coordinate-system.js +65 -0
- package/mjs-lib/data/list.js +56 -0
- package/mjs-lib/debug.js +30 -0
- package/mjs-lib/greedy-fas.js +125 -0
- package/mjs-lib/index.js +9 -0
- package/mjs-lib/layout.js +405 -0
- package/mjs-lib/nesting-graph.js +120 -0
- package/mjs-lib/normalize.js +84 -0
- package/mjs-lib/order/add-subgraph-constraints.js +49 -0
- package/mjs-lib/order/barycenter.js +24 -0
- package/mjs-lib/order/build-layer-graph.js +71 -0
- package/mjs-lib/order/cross-count.js +64 -0
- package/mjs-lib/order/index.js +70 -0
- package/mjs-lib/order/init-order.js +34 -0
- package/mjs-lib/order/resolve-conflicts.js +116 -0
- package/mjs-lib/order/sort-subgraph.js +71 -0
- package/mjs-lib/order/sort.js +54 -0
- package/mjs-lib/parent-dummy-chains.js +82 -0
- package/mjs-lib/position/bk.js +409 -0
- package/mjs-lib/position/index.js +30 -0
- package/mjs-lib/rank/feasible-tree.js +93 -0
- package/mjs-lib/rank/index.js +46 -0
- package/mjs-lib/rank/network-simplex.js +233 -0
- package/mjs-lib/rank/util.js +58 -0
- package/mjs-lib/util.js +305 -0
- package/mjs-lib/version.js +1 -0
- package/package.json +14 -3
package/lib/layout.js
CHANGED
|
@@ -1,59 +1,61 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = layout;
|
|
7
|
+
var acyclic = _interopRequireWildcard(require("./acyclic.js"));
|
|
8
|
+
var normalize = _interopRequireWildcard(require("./normalize.js"));
|
|
9
|
+
var _index = _interopRequireDefault(require("./rank/index.js"));
|
|
10
|
+
var _parentDummyChains = _interopRequireDefault(require("./parent-dummy-chains.js"));
|
|
11
|
+
var nestingGraph = _interopRequireWildcard(require("./nesting-graph.js"));
|
|
12
|
+
var _addBorderSegments = _interopRequireDefault(require("./add-border-segments.js"));
|
|
13
|
+
var coordinateSystem = _interopRequireWildcard(require("./coordinate-system.js"));
|
|
14
|
+
var _index2 = _interopRequireDefault(require("./order/index.js"));
|
|
15
|
+
var _index3 = _interopRequireDefault(require("./position/index.js"));
|
|
16
|
+
var util = _interopRequireWildcard(require("./util.js"));
|
|
17
|
+
var _graphlib = require("@dagrejs/graphlib");
|
|
18
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
19
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
20
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
21
|
+
const removeEmptyRanks = util.removeEmptyRanks;
|
|
22
|
+
const normalizeRanks = util.normalizeRanks;
|
|
19
23
|
function layout(g, opts) {
|
|
20
24
|
let time = opts && opts.debugTiming ? util.time : util.notime;
|
|
21
25
|
time("layout", () => {
|
|
22
|
-
let layoutGraph =
|
|
23
|
-
|
|
24
|
-
time(" runLayout", () => runLayout(layoutGraph, time));
|
|
26
|
+
let layoutGraph = time(" buildLayoutGraph", () => buildLayoutGraph(g));
|
|
27
|
+
time(" runLayout", () => runLayout(layoutGraph, time));
|
|
25
28
|
time(" updateInputGraph", () => updateInputGraph(g, layoutGraph));
|
|
26
29
|
});
|
|
27
30
|
}
|
|
28
|
-
|
|
29
31
|
function runLayout(g, time) {
|
|
30
32
|
time(" makeSpaceForEdgeLabels", () => makeSpaceForEdgeLabels(g));
|
|
31
|
-
time(" removeSelfEdges",
|
|
32
|
-
time(" acyclic",
|
|
33
|
-
time(" nestingGraph.run",
|
|
34
|
-
time(" rank",
|
|
33
|
+
time(" removeSelfEdges", () => removeSelfEdges(g));
|
|
34
|
+
time(" acyclic", () => acyclic.run(g));
|
|
35
|
+
time(" nestingGraph.run", () => nestingGraph.run(g));
|
|
36
|
+
time(" rank", () => (0, _index.default)(util.asNonCompoundGraph(g)));
|
|
35
37
|
time(" injectEdgeLabelProxies", () => injectEdgeLabelProxies(g));
|
|
36
|
-
time(" removeEmptyRanks",
|
|
37
|
-
time(" nestingGraph.cleanup",
|
|
38
|
-
time(" normalizeRanks",
|
|
39
|
-
time(" assignRankMinMax",
|
|
38
|
+
time(" removeEmptyRanks", () => removeEmptyRanks(g));
|
|
39
|
+
time(" nestingGraph.cleanup", () => nestingGraph.cleanup(g));
|
|
40
|
+
time(" normalizeRanks", () => normalizeRanks(g));
|
|
41
|
+
time(" assignRankMinMax", () => assignRankMinMax(g));
|
|
40
42
|
time(" removeEdgeLabelProxies", () => removeEdgeLabelProxies(g));
|
|
41
|
-
time(" normalize.run",
|
|
42
|
-
time(" parentDummyChains",
|
|
43
|
-
time(" addBorderSegments",
|
|
44
|
-
time(" order",
|
|
45
|
-
time(" insertSelfEdges",
|
|
43
|
+
time(" normalize.run", () => normalize.run(g));
|
|
44
|
+
time(" parentDummyChains", () => (0, _parentDummyChains.default)(g));
|
|
45
|
+
time(" addBorderSegments", () => (0, _addBorderSegments.default)(g));
|
|
46
|
+
time(" order", () => (0, _index2.default)(g));
|
|
47
|
+
time(" insertSelfEdges", () => insertSelfEdges(g));
|
|
46
48
|
time(" adjustCoordinateSystem", () => coordinateSystem.adjust(g));
|
|
47
|
-
time(" position",
|
|
48
|
-
time(" positionSelfEdges",
|
|
49
|
-
time(" removeBorderNodes",
|
|
50
|
-
time(" normalize.undo",
|
|
51
|
-
time(" fixupEdgeLabelCoords",
|
|
52
|
-
time(" undoCoordinateSystem",
|
|
53
|
-
time(" translateGraph",
|
|
54
|
-
time(" assignNodeIntersects",
|
|
55
|
-
time(" reversePoints",
|
|
56
|
-
time(" acyclic.undo",
|
|
49
|
+
time(" position", () => (0, _index3.default)(g));
|
|
50
|
+
time(" positionSelfEdges", () => positionSelfEdges(g));
|
|
51
|
+
time(" removeBorderNodes", () => removeBorderNodes(g));
|
|
52
|
+
time(" normalize.undo", () => normalize.undo(g));
|
|
53
|
+
time(" fixupEdgeLabelCoords", () => fixupEdgeLabelCoords(g));
|
|
54
|
+
time(" undoCoordinateSystem", () => coordinateSystem.undo(g));
|
|
55
|
+
time(" translateGraph", () => translateGraph(g));
|
|
56
|
+
time(" assignNodeIntersects", () => assignNodeIntersects(g));
|
|
57
|
+
time(" reversePoints", () => reversePointsForReversedEdges(g));
|
|
58
|
+
time(" acyclic.undo", () => acyclic.undo(g));
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
/*
|
|
@@ -66,43 +68,49 @@ function updateInputGraph(inputGraph, layoutGraph) {
|
|
|
66
68
|
inputGraph.nodes().forEach(v => {
|
|
67
69
|
let inputLabel = inputGraph.node(v);
|
|
68
70
|
let layoutLabel = layoutGraph.node(v);
|
|
69
|
-
|
|
70
71
|
if (inputLabel) {
|
|
71
72
|
inputLabel.x = layoutLabel.x;
|
|
72
73
|
inputLabel.y = layoutLabel.y;
|
|
73
74
|
inputLabel.rank = layoutLabel.rank;
|
|
74
|
-
|
|
75
75
|
if (layoutGraph.children(v).length) {
|
|
76
76
|
inputLabel.width = layoutLabel.width;
|
|
77
77
|
inputLabel.height = layoutLabel.height;
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
});
|
|
81
|
-
|
|
82
81
|
inputGraph.edges().forEach(e => {
|
|
83
82
|
let inputLabel = inputGraph.edge(e);
|
|
84
83
|
let layoutLabel = layoutGraph.edge(e);
|
|
85
|
-
|
|
86
84
|
inputLabel.points = layoutLabel.points;
|
|
87
85
|
if (layoutLabel.hasOwnProperty("x")) {
|
|
88
86
|
inputLabel.x = layoutLabel.x;
|
|
89
87
|
inputLabel.y = layoutLabel.y;
|
|
90
88
|
}
|
|
91
89
|
});
|
|
92
|
-
|
|
93
90
|
inputGraph.graph().width = layoutGraph.graph().width;
|
|
94
91
|
inputGraph.graph().height = layoutGraph.graph().height;
|
|
95
92
|
}
|
|
96
|
-
|
|
97
93
|
let graphNumAttrs = ["nodesep", "edgesep", "ranksep", "marginx", "marginy"];
|
|
98
|
-
let graphDefaults = {
|
|
94
|
+
let graphDefaults = {
|
|
95
|
+
ranksep: 50,
|
|
96
|
+
edgesep: 20,
|
|
97
|
+
nodesep: 50,
|
|
98
|
+
rankdir: "tb"
|
|
99
|
+
};
|
|
99
100
|
let graphAttrs = ["acyclicer", "ranker", "rankdir", "align"];
|
|
100
101
|
let nodeNumAttrs = ["width", "height"];
|
|
101
|
-
let nodeDefaults = {
|
|
102
|
+
let nodeDefaults = {
|
|
103
|
+
width: 0,
|
|
104
|
+
height: 0
|
|
105
|
+
};
|
|
102
106
|
let edgeNumAttrs = ["minlen", "weight", "width", "height", "labeloffset"];
|
|
103
107
|
let edgeDefaults = {
|
|
104
|
-
minlen: 1,
|
|
105
|
-
|
|
108
|
+
minlen: 1,
|
|
109
|
+
weight: 1,
|
|
110
|
+
width: 0,
|
|
111
|
+
height: 0,
|
|
112
|
+
labeloffset: 10,
|
|
113
|
+
labelpos: "r"
|
|
106
114
|
};
|
|
107
115
|
let edgeAttrs = ["labelpos"];
|
|
108
116
|
|
|
@@ -113,14 +121,12 @@ let edgeAttrs = ["labelpos"];
|
|
|
113
121
|
* attributes can influence layout.
|
|
114
122
|
*/
|
|
115
123
|
function buildLayoutGraph(inputGraph) {
|
|
116
|
-
let g = new Graph({
|
|
124
|
+
let g = new _graphlib.Graph({
|
|
125
|
+
multigraph: true,
|
|
126
|
+
compound: true
|
|
127
|
+
});
|
|
117
128
|
let graph = canonicalize(inputGraph.graph());
|
|
118
|
-
|
|
119
|
-
g.setGraph(Object.assign({},
|
|
120
|
-
graphDefaults,
|
|
121
|
-
selectNumberAttrs(graph, graphNumAttrs),
|
|
122
|
-
util.pick(graph, graphAttrs)));
|
|
123
|
-
|
|
129
|
+
g.setGraph(Object.assign({}, graphDefaults, selectNumberAttrs(graph, graphNumAttrs), util.pick(graph, graphAttrs)));
|
|
124
130
|
inputGraph.nodes().forEach(v => {
|
|
125
131
|
let node = canonicalize(inputGraph.node(v));
|
|
126
132
|
const newNode = selectNumberAttrs(node, nodeNumAttrs);
|
|
@@ -129,19 +135,13 @@ function buildLayoutGraph(inputGraph) {
|
|
|
129
135
|
newNode[k] = nodeDefaults[k];
|
|
130
136
|
}
|
|
131
137
|
});
|
|
132
|
-
|
|
133
138
|
g.setNode(v, newNode);
|
|
134
139
|
g.setParent(v, inputGraph.parent(v));
|
|
135
140
|
});
|
|
136
|
-
|
|
137
141
|
inputGraph.edges().forEach(e => {
|
|
138
142
|
let edge = canonicalize(inputGraph.edge(e));
|
|
139
|
-
g.setEdge(e, Object.assign({},
|
|
140
|
-
edgeDefaults,
|
|
141
|
-
selectNumberAttrs(edge, edgeNumAttrs),
|
|
142
|
-
util.pick(edge, edgeAttrs)));
|
|
143
|
+
g.setEdge(e, Object.assign({}, edgeDefaults, selectNumberAttrs(edge, edgeNumAttrs), util.pick(edge, edgeAttrs)));
|
|
143
144
|
});
|
|
144
|
-
|
|
145
145
|
return g;
|
|
146
146
|
}
|
|
147
147
|
|
|
@@ -181,12 +181,14 @@ function injectEdgeLabelProxies(g) {
|
|
|
181
181
|
if (edge.width && edge.height) {
|
|
182
182
|
let v = g.node(e.v);
|
|
183
183
|
let w = g.node(e.w);
|
|
184
|
-
let label = {
|
|
184
|
+
let label = {
|
|
185
|
+
rank: (w.rank - v.rank) / 2 + v.rank,
|
|
186
|
+
e: e
|
|
187
|
+
};
|
|
185
188
|
util.addDummyNode(g, "edge-proxy", label, "_ep");
|
|
186
189
|
}
|
|
187
190
|
});
|
|
188
191
|
}
|
|
189
|
-
|
|
190
192
|
function assignRankMinMax(g) {
|
|
191
193
|
let maxRank = 0;
|
|
192
194
|
g.nodes().forEach(v => {
|
|
@@ -199,7 +201,6 @@ function assignRankMinMax(g) {
|
|
|
199
201
|
});
|
|
200
202
|
g.graph().maxRank = maxRank;
|
|
201
203
|
}
|
|
202
|
-
|
|
203
204
|
function removeEdgeLabelProxies(g) {
|
|
204
205
|
g.nodes().forEach(v => {
|
|
205
206
|
let node = g.node(v);
|
|
@@ -209,7 +210,6 @@ function removeEdgeLabelProxies(g) {
|
|
|
209
210
|
}
|
|
210
211
|
});
|
|
211
212
|
}
|
|
212
|
-
|
|
213
213
|
function translateGraph(g) {
|
|
214
214
|
let minX = Number.POSITIVE_INFINITY;
|
|
215
215
|
let maxX = 0;
|
|
@@ -218,7 +218,6 @@ function translateGraph(g) {
|
|
|
218
218
|
let graphLabel = g.graph();
|
|
219
219
|
let marginX = graphLabel.marginx || 0;
|
|
220
220
|
let marginY = graphLabel.marginy || 0;
|
|
221
|
-
|
|
222
221
|
function getExtremes(attrs) {
|
|
223
222
|
let x = attrs.x;
|
|
224
223
|
let y = attrs.y;
|
|
@@ -229,7 +228,6 @@ function translateGraph(g) {
|
|
|
229
228
|
minY = Math.min(minY, y - h / 2);
|
|
230
229
|
maxY = Math.max(maxY, y + h / 2);
|
|
231
230
|
}
|
|
232
|
-
|
|
233
231
|
g.nodes().forEach(v => getExtremes(g.node(v)));
|
|
234
232
|
g.edges().forEach(e => {
|
|
235
233
|
let edge = g.edge(e);
|
|
@@ -237,30 +235,29 @@ function translateGraph(g) {
|
|
|
237
235
|
getExtremes(edge);
|
|
238
236
|
}
|
|
239
237
|
});
|
|
240
|
-
|
|
241
238
|
minX -= marginX;
|
|
242
239
|
minY -= marginY;
|
|
243
|
-
|
|
244
240
|
g.nodes().forEach(v => {
|
|
245
241
|
let node = g.node(v);
|
|
246
242
|
node.x -= minX;
|
|
247
243
|
node.y -= minY;
|
|
248
244
|
});
|
|
249
|
-
|
|
250
245
|
g.edges().forEach(e => {
|
|
251
246
|
let edge = g.edge(e);
|
|
252
247
|
edge.points.forEach(p => {
|
|
253
248
|
p.x -= minX;
|
|
254
249
|
p.y -= minY;
|
|
255
250
|
});
|
|
256
|
-
if (edge.hasOwnProperty("x")) {
|
|
257
|
-
|
|
251
|
+
if (edge.hasOwnProperty("x")) {
|
|
252
|
+
edge.x -= minX;
|
|
253
|
+
}
|
|
254
|
+
if (edge.hasOwnProperty("y")) {
|
|
255
|
+
edge.y -= minY;
|
|
256
|
+
}
|
|
258
257
|
});
|
|
259
|
-
|
|
260
258
|
graphLabel.width = maxX - minX + marginX;
|
|
261
259
|
graphLabel.height = maxY - minY + marginY;
|
|
262
260
|
}
|
|
263
|
-
|
|
264
261
|
function assignNodeIntersects(g) {
|
|
265
262
|
g.edges().forEach(e => {
|
|
266
263
|
let edge = g.edge(e);
|
|
@@ -279,7 +276,6 @@ function assignNodeIntersects(g) {
|
|
|
279
276
|
edge.points.push(util.intersectRect(nodeW, p2));
|
|
280
277
|
});
|
|
281
278
|
}
|
|
282
|
-
|
|
283
279
|
function fixupEdgeLabelCoords(g) {
|
|
284
280
|
g.edges().forEach(e => {
|
|
285
281
|
let edge = g.edge(e);
|
|
@@ -288,13 +284,16 @@ function fixupEdgeLabelCoords(g) {
|
|
|
288
284
|
edge.width -= edge.labeloffset;
|
|
289
285
|
}
|
|
290
286
|
switch (edge.labelpos) {
|
|
291
|
-
|
|
292
|
-
|
|
287
|
+
case "l":
|
|
288
|
+
edge.x -= edge.width / 2 + edge.labeloffset;
|
|
289
|
+
break;
|
|
290
|
+
case "r":
|
|
291
|
+
edge.x += edge.width / 2 + edge.labeloffset;
|
|
292
|
+
break;
|
|
293
293
|
}
|
|
294
294
|
}
|
|
295
295
|
});
|
|
296
296
|
}
|
|
297
|
-
|
|
298
297
|
function reversePointsForReversedEdges(g) {
|
|
299
298
|
g.edges().forEach(e => {
|
|
300
299
|
let edge = g.edge(e);
|
|
@@ -303,7 +302,6 @@ function reversePointsForReversedEdges(g) {
|
|
|
303
302
|
}
|
|
304
303
|
});
|
|
305
304
|
}
|
|
306
|
-
|
|
307
305
|
function removeBorderNodes(g) {
|
|
308
306
|
g.nodes().forEach(v => {
|
|
309
307
|
if (g.children(v).length) {
|
|
@@ -312,21 +310,18 @@ function removeBorderNodes(g) {
|
|
|
312
310
|
let b = g.node(node.borderBottom);
|
|
313
311
|
let l = g.node(node.borderLeft[node.borderLeft.length - 1]);
|
|
314
312
|
let r = g.node(node.borderRight[node.borderRight.length - 1]);
|
|
315
|
-
|
|
316
313
|
node.width = Math.abs(r.x - l.x);
|
|
317
314
|
node.height = Math.abs(b.y - t.y);
|
|
318
315
|
node.x = l.x + node.width / 2;
|
|
319
316
|
node.y = t.y + node.height / 2;
|
|
320
317
|
}
|
|
321
318
|
});
|
|
322
|
-
|
|
323
319
|
g.nodes().forEach(v => {
|
|
324
320
|
if (g.node(v).dummy === "border") {
|
|
325
321
|
g.removeNode(v);
|
|
326
322
|
}
|
|
327
323
|
});
|
|
328
324
|
}
|
|
329
|
-
|
|
330
325
|
function removeSelfEdges(g) {
|
|
331
326
|
g.edges().forEach(e => {
|
|
332
327
|
if (e.v === e.w) {
|
|
@@ -334,12 +329,14 @@ function removeSelfEdges(g) {
|
|
|
334
329
|
if (!node.selfEdges) {
|
|
335
330
|
node.selfEdges = [];
|
|
336
331
|
}
|
|
337
|
-
node.selfEdges.push({
|
|
332
|
+
node.selfEdges.push({
|
|
333
|
+
e: e,
|
|
334
|
+
label: g.edge(e)
|
|
335
|
+
});
|
|
338
336
|
g.removeEdge(e);
|
|
339
337
|
}
|
|
340
338
|
});
|
|
341
339
|
}
|
|
342
|
-
|
|
343
340
|
function insertSelfEdges(g) {
|
|
344
341
|
var layers = util.buildLayerMatrix(g);
|
|
345
342
|
layers.forEach(layer => {
|
|
@@ -352,7 +349,7 @@ function insertSelfEdges(g) {
|
|
|
352
349
|
width: selfEdge.label.width,
|
|
353
350
|
height: selfEdge.label.height,
|
|
354
351
|
rank: node.rank,
|
|
355
|
-
order: i +
|
|
352
|
+
order: i + ++orderShift,
|
|
356
353
|
e: selfEdge.e,
|
|
357
354
|
label: selfEdge.label
|
|
358
355
|
}, "_se");
|
|
@@ -361,7 +358,6 @@ function insertSelfEdges(g) {
|
|
|
361
358
|
});
|
|
362
359
|
});
|
|
363
360
|
}
|
|
364
|
-
|
|
365
361
|
function positionSelfEdges(g) {
|
|
366
362
|
g.nodes().forEach(v => {
|
|
367
363
|
var node = g.node(v);
|
|
@@ -373,23 +369,30 @@ function positionSelfEdges(g) {
|
|
|
373
369
|
var dy = selfNode.height / 2;
|
|
374
370
|
g.setEdge(node.e, node.label);
|
|
375
371
|
g.removeNode(v);
|
|
376
|
-
node.label.points = [
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
372
|
+
node.label.points = [{
|
|
373
|
+
x: x + 2 * dx / 3,
|
|
374
|
+
y: y - dy
|
|
375
|
+
}, {
|
|
376
|
+
x: x + 5 * dx / 6,
|
|
377
|
+
y: y - dy
|
|
378
|
+
}, {
|
|
379
|
+
x: x + dx,
|
|
380
|
+
y: y
|
|
381
|
+
}, {
|
|
382
|
+
x: x + 5 * dx / 6,
|
|
383
|
+
y: y + dy
|
|
384
|
+
}, {
|
|
385
|
+
x: x + 2 * dx / 3,
|
|
386
|
+
y: y + dy
|
|
387
|
+
}];
|
|
383
388
|
node.label.x = node.x;
|
|
384
389
|
node.label.y = node.y;
|
|
385
390
|
}
|
|
386
391
|
});
|
|
387
392
|
}
|
|
388
|
-
|
|
389
393
|
function selectNumberAttrs(obj, attrs) {
|
|
390
394
|
return util.mapValues(util.pick(obj, attrs), Number);
|
|
391
395
|
}
|
|
392
|
-
|
|
393
396
|
function canonicalize(attrs) {
|
|
394
397
|
var newAttrs = {};
|
|
395
398
|
if (attrs) {
|
|
@@ -397,9 +400,9 @@ function canonicalize(attrs) {
|
|
|
397
400
|
if (typeof k === "string") {
|
|
398
401
|
k = k.toLowerCase();
|
|
399
402
|
}
|
|
400
|
-
|
|
401
403
|
newAttrs[k] = v;
|
|
402
404
|
});
|
|
403
405
|
}
|
|
404
406
|
return newAttrs;
|
|
405
407
|
}
|
|
408
|
+
module.exports = exports.default;
|
package/lib/nesting-graph.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.cleanup = cleanup;
|
|
7
|
+
exports.run = run;
|
|
8
|
+
var util = _interopRequireWildcard(require("./util.js"));
|
|
9
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
10
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
8
11
|
/*
|
|
9
12
|
* A nesting graph creates dummy nodes for the tops and bottoms of subgraphs,
|
|
10
13
|
* adds appropriate edges to ensure that all cluster nodes are placed between
|
|
@@ -33,7 +36,6 @@ function run(g) {
|
|
|
33
36
|
let depths = treeDepths(g);
|
|
34
37
|
let height = Math.max(...Object.values(depths)) - 1; // Note: depths is an Object not an array
|
|
35
38
|
let nodeSep = 2 * height + 1;
|
|
36
|
-
|
|
37
39
|
g.graph().nestingRoot = root;
|
|
38
40
|
|
|
39
41
|
// Multiply minlen by nodeSep to align nodes on non-border ranks.
|
|
@@ -49,52 +51,49 @@ function run(g) {
|
|
|
49
51
|
// layers.
|
|
50
52
|
g.graph().nodeRankFactor = nodeSep;
|
|
51
53
|
}
|
|
52
|
-
|
|
53
54
|
function dfs(g, root, nodeSep, weight, height, depths, v) {
|
|
54
55
|
let children = g.children(v);
|
|
55
56
|
if (!children.length) {
|
|
56
57
|
if (v !== root) {
|
|
57
|
-
g.setEdge(root, v, {
|
|
58
|
+
g.setEdge(root, v, {
|
|
59
|
+
weight: 0,
|
|
60
|
+
minlen: nodeSep
|
|
61
|
+
});
|
|
58
62
|
}
|
|
59
63
|
return;
|
|
60
64
|
}
|
|
61
|
-
|
|
62
65
|
let top = util.addBorderNode(g, "_bt");
|
|
63
66
|
let bottom = util.addBorderNode(g, "_bb");
|
|
64
67
|
let label = g.node(v);
|
|
65
|
-
|
|
66
68
|
g.setParent(top, v);
|
|
67
69
|
label.borderTop = top;
|
|
68
70
|
g.setParent(bottom, v);
|
|
69
71
|
label.borderBottom = bottom;
|
|
70
|
-
|
|
71
72
|
children.forEach(child => {
|
|
72
73
|
dfs(g, root, nodeSep, weight, height, depths, child);
|
|
73
|
-
|
|
74
74
|
let childNode = g.node(child);
|
|
75
75
|
let childTop = childNode.borderTop ? childNode.borderTop : child;
|
|
76
76
|
let childBottom = childNode.borderBottom ? childNode.borderBottom : child;
|
|
77
77
|
let thisWeight = childNode.borderTop ? weight : 2 * weight;
|
|
78
78
|
let minlen = childTop !== childBottom ? 1 : height - depths[v] + 1;
|
|
79
|
-
|
|
80
79
|
g.setEdge(top, childTop, {
|
|
81
80
|
weight: thisWeight,
|
|
82
81
|
minlen: minlen,
|
|
83
82
|
nestingEdge: true
|
|
84
83
|
});
|
|
85
|
-
|
|
86
84
|
g.setEdge(childBottom, bottom, {
|
|
87
85
|
weight: thisWeight,
|
|
88
86
|
minlen: minlen,
|
|
89
87
|
nestingEdge: true
|
|
90
88
|
});
|
|
91
89
|
});
|
|
92
|
-
|
|
93
90
|
if (!g.parent(v)) {
|
|
94
|
-
g.setEdge(root, top, {
|
|
91
|
+
g.setEdge(root, top, {
|
|
92
|
+
weight: 0,
|
|
93
|
+
minlen: height + depths[v]
|
|
94
|
+
});
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
|
-
|
|
98
97
|
function treeDepths(g) {
|
|
99
98
|
var depths = {};
|
|
100
99
|
function dfs(v, depth) {
|
|
@@ -107,11 +106,9 @@ function treeDepths(g) {
|
|
|
107
106
|
g.children().forEach(v => dfs(v, 1));
|
|
108
107
|
return depths;
|
|
109
108
|
}
|
|
110
|
-
|
|
111
109
|
function sumWeights(g) {
|
|
112
110
|
return g.edges().reduce((acc, e) => acc + g.edge(e).weight, 0);
|
|
113
111
|
}
|
|
114
|
-
|
|
115
112
|
function cleanup(g) {
|
|
116
113
|
var graphLabel = g.graph();
|
|
117
114
|
g.removeNode(graphLabel.nestingRoot);
|
package/lib/normalize.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.run = run;
|
|
7
|
+
exports.undo = undo;
|
|
8
|
+
var util = _interopRequireWildcard(require("./util.js"));
|
|
9
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
10
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
10
11
|
/*
|
|
11
12
|
* Breaks any long edges in the graph into short segments that span 1 layer
|
|
12
13
|
* each. This operation is undoable with the denormalize function.
|
|
@@ -27,7 +28,6 @@ function run(g) {
|
|
|
27
28
|
g.graph().dummyChains = [];
|
|
28
29
|
g.edges().forEach(edge => normalizeEdge(g, edge));
|
|
29
30
|
}
|
|
30
|
-
|
|
31
31
|
function normalizeEdge(g, e) {
|
|
32
32
|
let v = e.v;
|
|
33
33
|
let vRank = g.node(v).rank;
|
|
@@ -36,17 +36,16 @@ function normalizeEdge(g, e) {
|
|
|
36
36
|
let name = e.name;
|
|
37
37
|
let edgeLabel = g.edge(e);
|
|
38
38
|
let labelRank = edgeLabel.labelRank;
|
|
39
|
-
|
|
40
39
|
if (wRank === vRank + 1) return;
|
|
41
|
-
|
|
42
40
|
g.removeEdge(e);
|
|
43
|
-
|
|
44
41
|
let dummy, attrs, i;
|
|
45
42
|
for (i = 0, ++vRank; vRank < wRank; ++i, ++vRank) {
|
|
46
43
|
edgeLabel.points = [];
|
|
47
44
|
attrs = {
|
|
48
|
-
width: 0,
|
|
49
|
-
|
|
45
|
+
width: 0,
|
|
46
|
+
height: 0,
|
|
47
|
+
edgeLabel: edgeLabel,
|
|
48
|
+
edgeObj: e,
|
|
50
49
|
rank: vRank
|
|
51
50
|
};
|
|
52
51
|
dummy = util.addDummyNode(g, "edge", attrs, "_d");
|
|
@@ -56,16 +55,18 @@ function normalizeEdge(g, e) {
|
|
|
56
55
|
attrs.dummy = "edge-label";
|
|
57
56
|
attrs.labelpos = edgeLabel.labelpos;
|
|
58
57
|
}
|
|
59
|
-
g.setEdge(v, dummy, {
|
|
58
|
+
g.setEdge(v, dummy, {
|
|
59
|
+
weight: edgeLabel.weight
|
|
60
|
+
}, name);
|
|
60
61
|
if (i === 0) {
|
|
61
62
|
g.graph().dummyChains.push(dummy);
|
|
62
63
|
}
|
|
63
64
|
v = dummy;
|
|
64
65
|
}
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
g.setEdge(v, w, {
|
|
67
|
+
weight: edgeLabel.weight
|
|
68
|
+
}, name);
|
|
67
69
|
}
|
|
68
|
-
|
|
69
70
|
function undo(g) {
|
|
70
71
|
g.graph().dummyChains.forEach(v => {
|
|
71
72
|
let node = g.node(v);
|
|
@@ -75,7 +76,10 @@ function undo(g) {
|
|
|
75
76
|
while (node.dummy) {
|
|
76
77
|
w = g.successors(v)[0];
|
|
77
78
|
g.removeNode(v);
|
|
78
|
-
origLabel.points.push({
|
|
79
|
+
origLabel.points.push({
|
|
80
|
+
x: node.x,
|
|
81
|
+
y: node.y
|
|
82
|
+
});
|
|
79
83
|
if (node.dummy === "edge-label") {
|
|
80
84
|
origLabel.x = node.x;
|
|
81
85
|
origLabel.y = node.y;
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
2
|
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = addSubgraphConstraints;
|
|
3
7
|
function addSubgraphConstraints(g, cg, vs) {
|
|
4
8
|
let prev = {},
|
|
5
9
|
rootPrev;
|
|
6
|
-
|
|
7
10
|
vs.forEach(v => {
|
|
8
11
|
let child = g.parent(v),
|
|
9
12
|
parent,
|
|
@@ -49,3 +52,4 @@ function addSubgraphConstraints(g, cg, vs) {
|
|
|
49
52
|
dfs(undefined);
|
|
50
53
|
*/
|
|
51
54
|
}
|
|
55
|
+
module.exports = exports.default;
|
package/lib/order/barycenter.js
CHANGED
|
@@ -1,20 +1,28 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
2
|
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = barycenter;
|
|
3
7
|
function barycenter(g, movable = []) {
|
|
4
8
|
return movable.map(v => {
|
|
5
9
|
let inV = g.inEdges(v);
|
|
6
10
|
if (!inV.length) {
|
|
7
|
-
return {
|
|
11
|
+
return {
|
|
12
|
+
v: v
|
|
13
|
+
};
|
|
8
14
|
} else {
|
|
9
15
|
let result = inV.reduce((acc, e) => {
|
|
10
16
|
let edge = g.edge(e),
|
|
11
17
|
nodeU = g.node(e.v);
|
|
12
18
|
return {
|
|
13
|
-
sum: acc.sum +
|
|
19
|
+
sum: acc.sum + edge.weight * nodeU.order,
|
|
14
20
|
weight: acc.weight + edge.weight
|
|
15
21
|
};
|
|
16
|
-
}, {
|
|
17
|
-
|
|
22
|
+
}, {
|
|
23
|
+
sum: 0,
|
|
24
|
+
weight: 0
|
|
25
|
+
});
|
|
18
26
|
return {
|
|
19
27
|
v: v,
|
|
20
28
|
barycenter: result.sum / result.weight,
|
|
@@ -23,4 +31,4 @@ function barycenter(g, movable = []) {
|
|
|
23
31
|
}
|
|
24
32
|
});
|
|
25
33
|
}
|
|
26
|
-
|
|
34
|
+
module.exports = exports.default;
|