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