@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/position/bk.js
CHANGED
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.addConflict = addConflict;
|
|
7
|
+
exports.alignCoordinates = alignCoordinates;
|
|
8
|
+
exports.balance = balance;
|
|
9
|
+
exports.findSmallestWidthAlignment = findSmallestWidthAlignment;
|
|
10
|
+
exports.findType1Conflicts = findType1Conflicts;
|
|
11
|
+
exports.findType2Conflicts = findType2Conflicts;
|
|
12
|
+
exports.hasConflict = hasConflict;
|
|
13
|
+
exports.horizontalCompaction = horizontalCompaction;
|
|
14
|
+
exports.positionX = positionX;
|
|
15
|
+
exports.verticalAlignment = verticalAlignment;
|
|
16
|
+
var _graphlib = require("@dagrejs/graphlib");
|
|
17
|
+
var util = _interopRequireWildcard(require("../util.js"));
|
|
18
|
+
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); }
|
|
19
|
+
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; }
|
|
6
20
|
/*
|
|
7
21
|
* This module provides coordinate assignment based on Brandes and Köpf, "Fast
|
|
8
22
|
* and Simple Horizontal Coordinate Assignment."
|
|
9
23
|
*/
|
|
10
24
|
|
|
11
|
-
module.exports = {
|
|
12
|
-
positionX: positionX,
|
|
13
|
-
findType1Conflicts: findType1Conflicts,
|
|
14
|
-
findType2Conflicts: findType2Conflicts,
|
|
15
|
-
addConflict: addConflict,
|
|
16
|
-
hasConflict: hasConflict,
|
|
17
|
-
verticalAlignment: verticalAlignment,
|
|
18
|
-
horizontalCompaction: horizontalCompaction,
|
|
19
|
-
alignCoordinates: alignCoordinates,
|
|
20
|
-
findSmallestWidthAlignment: findSmallestWidthAlignment,
|
|
21
|
-
balance: balance
|
|
22
|
-
};
|
|
23
|
-
|
|
24
25
|
/*
|
|
25
26
|
* Marks all edges in the graph with a type-1 conflict with the "type1Conflict"
|
|
26
27
|
* property. A type-1 conflict is one where a non-inner segment crosses an
|
|
@@ -40,7 +41,6 @@ module.exports = {
|
|
|
40
41
|
*/
|
|
41
42
|
function findType1Conflicts(g, layering) {
|
|
42
43
|
let conflicts = {};
|
|
43
|
-
|
|
44
44
|
function visitLayer(prevLayer, layer) {
|
|
45
45
|
let
|
|
46
46
|
// last visited node in the previous layer that is incident on an inner
|
|
@@ -51,18 +51,15 @@ function findType1Conflicts(g, layering) {
|
|
|
51
51
|
scanPos = 0,
|
|
52
52
|
prevLayerLength = prevLayer.length,
|
|
53
53
|
lastNode = layer[layer.length - 1];
|
|
54
|
-
|
|
55
54
|
layer.forEach((v, i) => {
|
|
56
55
|
let w = findOtherInnerSegmentNode(g, v),
|
|
57
56
|
k1 = w ? g.node(w).order : prevLayerLength;
|
|
58
|
-
|
|
59
57
|
if (w || v === lastNode) {
|
|
60
|
-
layer.slice(scanPos, i+1).forEach(scanNode => {
|
|
58
|
+
layer.slice(scanPos, i + 1).forEach(scanNode => {
|
|
61
59
|
g.predecessors(scanNode).forEach(u => {
|
|
62
60
|
let uLabel = g.node(u),
|
|
63
61
|
uPos = uLabel.order;
|
|
64
|
-
if ((uPos < k0 || k1 < uPos) &&
|
|
65
|
-
!(uLabel.dummy && g.node(scanNode).dummy)) {
|
|
62
|
+
if ((uPos < k0 || k1 < uPos) && !(uLabel.dummy && g.node(scanNode).dummy)) {
|
|
66
63
|
addConflict(conflicts, u, scanNode);
|
|
67
64
|
}
|
|
68
65
|
});
|
|
@@ -71,17 +68,13 @@ function findType1Conflicts(g, layering) {
|
|
|
71
68
|
k0 = k1;
|
|
72
69
|
}
|
|
73
70
|
});
|
|
74
|
-
|
|
75
71
|
return layer;
|
|
76
72
|
}
|
|
77
|
-
|
|
78
|
-
layering.reduce(visitLayer);
|
|
73
|
+
layering.length && layering.reduce(visitLayer);
|
|
79
74
|
return conflicts;
|
|
80
75
|
}
|
|
81
|
-
|
|
82
76
|
function findType2Conflicts(g, layering) {
|
|
83
77
|
let conflicts = {};
|
|
84
|
-
|
|
85
78
|
function scan(south, southPos, southEnd, prevNorthBorder, nextNorthBorder) {
|
|
86
79
|
let v;
|
|
87
80
|
util.range(southPos, southEnd).forEach(i => {
|
|
@@ -89,21 +82,17 @@ function findType2Conflicts(g, layering) {
|
|
|
89
82
|
if (g.node(v).dummy) {
|
|
90
83
|
g.predecessors(v).forEach(u => {
|
|
91
84
|
let uNode = g.node(u);
|
|
92
|
-
if (uNode.dummy &&
|
|
93
|
-
(uNode.order < prevNorthBorder || uNode.order > nextNorthBorder)) {
|
|
85
|
+
if (uNode.dummy && (uNode.order < prevNorthBorder || uNode.order > nextNorthBorder)) {
|
|
94
86
|
addConflict(conflicts, u, v);
|
|
95
87
|
}
|
|
96
88
|
});
|
|
97
89
|
}
|
|
98
90
|
});
|
|
99
91
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
92
|
function visitLayer(north, south) {
|
|
103
93
|
let prevNorthPos = -1,
|
|
104
94
|
nextNorthPos,
|
|
105
95
|
southPos = 0;
|
|
106
|
-
|
|
107
96
|
south.forEach((v, southLookahead) => {
|
|
108
97
|
if (g.node(v).dummy === "border") {
|
|
109
98
|
let predecessors = g.predecessors(v);
|
|
@@ -116,34 +105,28 @@ function findType2Conflicts(g, layering) {
|
|
|
116
105
|
}
|
|
117
106
|
scan(south, southPos, south.length, nextNorthPos, north.length);
|
|
118
107
|
});
|
|
119
|
-
|
|
120
108
|
return south;
|
|
121
109
|
}
|
|
122
|
-
|
|
123
|
-
layering.reduce(visitLayer);
|
|
110
|
+
layering.length && layering.reduce(visitLayer);
|
|
124
111
|
return conflicts;
|
|
125
112
|
}
|
|
126
|
-
|
|
127
113
|
function findOtherInnerSegmentNode(g, v) {
|
|
128
114
|
if (g.node(v).dummy) {
|
|
129
115
|
return g.predecessors(v).find(u => g.node(u).dummy);
|
|
130
116
|
}
|
|
131
117
|
}
|
|
132
|
-
|
|
133
118
|
function addConflict(conflicts, v, w) {
|
|
134
119
|
if (v > w) {
|
|
135
120
|
let tmp = v;
|
|
136
121
|
v = w;
|
|
137
122
|
w = tmp;
|
|
138
123
|
}
|
|
139
|
-
|
|
140
124
|
let conflictsV = conflicts[v];
|
|
141
125
|
if (!conflictsV) {
|
|
142
126
|
conflicts[v] = conflictsV = {};
|
|
143
127
|
}
|
|
144
128
|
conflictsV[w] = true;
|
|
145
129
|
}
|
|
146
|
-
|
|
147
130
|
function hasConflict(conflicts, v, w) {
|
|
148
131
|
if (v > w) {
|
|
149
132
|
let tmp = v;
|
|
@@ -176,7 +159,6 @@ function verticalAlignment(g, layering, conflicts, neighborFn) {
|
|
|
176
159
|
pos[v] = order;
|
|
177
160
|
});
|
|
178
161
|
});
|
|
179
|
-
|
|
180
162
|
layering.forEach(layer => {
|
|
181
163
|
let prevIdx = -1;
|
|
182
164
|
layer.forEach(v => {
|
|
@@ -186,9 +168,7 @@ function verticalAlignment(g, layering, conflicts, neighborFn) {
|
|
|
186
168
|
let mp = (ws.length - 1) / 2;
|
|
187
169
|
for (let i = Math.floor(mp), il = Math.ceil(mp); i <= il; ++i) {
|
|
188
170
|
let w = ws[i];
|
|
189
|
-
if (align[v] === v &&
|
|
190
|
-
prevIdx < pos[w] &&
|
|
191
|
-
!hasConflict(conflicts, v, w)) {
|
|
171
|
+
if (align[v] === v && prevIdx < pos[w] && !hasConflict(conflicts, v, w)) {
|
|
192
172
|
align[w] = v;
|
|
193
173
|
align[v] = root[v] = root[w];
|
|
194
174
|
prevIdx = pos[w];
|
|
@@ -197,10 +177,11 @@ function verticalAlignment(g, layering, conflicts, neighborFn) {
|
|
|
197
177
|
}
|
|
198
178
|
});
|
|
199
179
|
});
|
|
200
|
-
|
|
201
|
-
|
|
180
|
+
return {
|
|
181
|
+
root: root,
|
|
182
|
+
align: align
|
|
183
|
+
};
|
|
202
184
|
}
|
|
203
|
-
|
|
204
185
|
function horizontalCompaction(g, layering, root, align, reverseSep) {
|
|
205
186
|
// This portion of the algorithm differs from BK due to a number of problems.
|
|
206
187
|
// Instead of their algorithm we construct a new block graph and do two
|
|
@@ -210,7 +191,6 @@ function horizontalCompaction(g, layering, root, align, reverseSep) {
|
|
|
210
191
|
let xs = {},
|
|
211
192
|
blockG = buildBlockGraph(g, layering, root, reverseSep),
|
|
212
193
|
borderType = reverseSep ? "borderLeft" : "borderRight";
|
|
213
|
-
|
|
214
194
|
function iterate(setXsFunc, nextNodesFunc) {
|
|
215
195
|
let stack = blockG.nodes();
|
|
216
196
|
let elem = stack.pop();
|
|
@@ -223,7 +203,6 @@ function horizontalCompaction(g, layering, root, align, reverseSep) {
|
|
|
223
203
|
stack.push(elem);
|
|
224
204
|
stack = stack.concat(nextNodesFunc(elem));
|
|
225
205
|
}
|
|
226
|
-
|
|
227
206
|
elem = stack.pop();
|
|
228
207
|
}
|
|
229
208
|
}
|
|
@@ -240,28 +219,22 @@ function horizontalCompaction(g, layering, root, align, reverseSep) {
|
|
|
240
219
|
let min = blockG.outEdges(elem).reduce((acc, e) => {
|
|
241
220
|
return Math.min(acc, xs[e.w] - blockG.edge(e));
|
|
242
221
|
}, Number.POSITIVE_INFINITY);
|
|
243
|
-
|
|
244
222
|
let node = g.node(elem);
|
|
245
223
|
if (min !== Number.POSITIVE_INFINITY && node.borderType !== borderType) {
|
|
246
224
|
xs[elem] = Math.max(xs[elem], min);
|
|
247
225
|
}
|
|
248
226
|
}
|
|
249
|
-
|
|
250
227
|
iterate(pass1, blockG.predecessors.bind(blockG));
|
|
251
228
|
iterate(pass2, blockG.successors.bind(blockG));
|
|
252
229
|
|
|
253
230
|
// Assign x coordinates to all nodes
|
|
254
231
|
Object.keys(align).forEach(v => xs[v] = xs[root[v]]);
|
|
255
|
-
|
|
256
232
|
return xs;
|
|
257
233
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
234
|
function buildBlockGraph(g, layering, root, reverseSep) {
|
|
261
|
-
let blockGraph = new Graph(),
|
|
235
|
+
let blockGraph = new _graphlib.Graph(),
|
|
262
236
|
graphLabel = g.graph(),
|
|
263
237
|
sepFn = sep(graphLabel.nodesep, graphLabel.edgesep, reverseSep);
|
|
264
|
-
|
|
265
238
|
layering.forEach(layer => {
|
|
266
239
|
let u;
|
|
267
240
|
layer.forEach(v => {
|
|
@@ -275,7 +248,6 @@ function buildBlockGraph(g, layering, root, reverseSep) {
|
|
|
275
248
|
u = v;
|
|
276
249
|
});
|
|
277
250
|
});
|
|
278
|
-
|
|
279
251
|
return blockGraph;
|
|
280
252
|
}
|
|
281
253
|
|
|
@@ -286,14 +258,11 @@ function findSmallestWidthAlignment(g, xss) {
|
|
|
286
258
|
return Object.values(xss).reduce((currentMinAndXs, xs) => {
|
|
287
259
|
let max = Number.NEGATIVE_INFINITY;
|
|
288
260
|
let min = Number.POSITIVE_INFINITY;
|
|
289
|
-
|
|
290
261
|
Object.entries(xs).forEach(([v, x]) => {
|
|
291
262
|
let halfWidth = width(g, v) / 2;
|
|
292
|
-
|
|
293
263
|
max = Math.max(x + halfWidth, max);
|
|
294
264
|
min = Math.min(x - halfWidth, min);
|
|
295
265
|
});
|
|
296
|
-
|
|
297
266
|
const newMin = max - min;
|
|
298
267
|
if (newMin < currentMinAndXs[0]) {
|
|
299
268
|
currentMinAndXs = [newMin, xs];
|
|
@@ -313,27 +282,22 @@ function alignCoordinates(xss, alignTo) {
|
|
|
313
282
|
let alignToVals = Object.values(alignTo),
|
|
314
283
|
alignToMin = Math.min(...alignToVals),
|
|
315
284
|
alignToMax = Math.max(...alignToVals);
|
|
316
|
-
|
|
317
285
|
["u", "d"].forEach(vert => {
|
|
318
286
|
["l", "r"].forEach(horiz => {
|
|
319
287
|
let alignment = vert + horiz,
|
|
320
288
|
xs = xss[alignment];
|
|
321
|
-
|
|
322
289
|
if (xs === alignTo) return;
|
|
323
|
-
|
|
324
290
|
let xsVals = Object.values(xs);
|
|
325
291
|
let delta = alignToMin - Math.min(...xsVals);
|
|
326
292
|
if (horiz !== "l") {
|
|
327
293
|
delta = alignToMax - Math.max(...xsVals);
|
|
328
294
|
}
|
|
329
|
-
|
|
330
295
|
if (delta) {
|
|
331
296
|
xss[alignment] = util.mapValues(xs, x => x + delta);
|
|
332
297
|
}
|
|
333
298
|
});
|
|
334
299
|
});
|
|
335
300
|
}
|
|
336
|
-
|
|
337
301
|
function balance(xss, align) {
|
|
338
302
|
return util.mapValues(xss.ul, (num, v) => {
|
|
339
303
|
if (align) {
|
|
@@ -344,13 +308,9 @@ function balance(xss, align) {
|
|
|
344
308
|
}
|
|
345
309
|
});
|
|
346
310
|
}
|
|
347
|
-
|
|
348
311
|
function positionX(g) {
|
|
349
312
|
let layering = util.buildLayerMatrix(g);
|
|
350
|
-
let conflicts = Object.assign(
|
|
351
|
-
findType1Conflicts(g, layering),
|
|
352
|
-
findType2Conflicts(g, layering));
|
|
353
|
-
|
|
313
|
+
let conflicts = Object.assign(findType1Conflicts(g, layering), findType2Conflicts(g, layering));
|
|
354
314
|
let xss = {};
|
|
355
315
|
let adjustedLayering;
|
|
356
316
|
["u", "d"].forEach(vert => {
|
|
@@ -361,62 +321,60 @@ function positionX(g) {
|
|
|
361
321
|
return Object.values(inner).reverse();
|
|
362
322
|
});
|
|
363
323
|
}
|
|
364
|
-
|
|
365
324
|
let neighborFn = (vert === "u" ? g.predecessors : g.successors).bind(g);
|
|
366
325
|
let align = verticalAlignment(g, adjustedLayering, conflicts, neighborFn);
|
|
367
|
-
let xs = horizontalCompaction(g, adjustedLayering,
|
|
368
|
-
align.root, align.align, horiz === "r");
|
|
326
|
+
let xs = horizontalCompaction(g, adjustedLayering, align.root, align.align, horiz === "r");
|
|
369
327
|
if (horiz === "r") {
|
|
370
328
|
xs = util.mapValues(xs, x => -x);
|
|
371
329
|
}
|
|
372
330
|
xss[vert + horiz] = xs;
|
|
373
331
|
});
|
|
374
332
|
});
|
|
375
|
-
|
|
376
|
-
|
|
377
333
|
let smallestWidth = findSmallestWidthAlignment(g, xss);
|
|
378
334
|
alignCoordinates(xss, smallestWidth);
|
|
379
335
|
return balance(xss, g.graph().align);
|
|
380
336
|
}
|
|
381
|
-
|
|
382
337
|
function sep(nodeSep, edgeSep, reverseSep) {
|
|
383
338
|
return (g, v, w) => {
|
|
384
339
|
let vLabel = g.node(v);
|
|
385
340
|
let wLabel = g.node(w);
|
|
386
341
|
let sum = 0;
|
|
387
342
|
let delta;
|
|
388
|
-
|
|
389
343
|
sum += vLabel.width / 2;
|
|
390
344
|
if (vLabel.hasOwnProperty("labelpos")) {
|
|
391
345
|
switch (vLabel.labelpos.toLowerCase()) {
|
|
392
|
-
|
|
393
|
-
|
|
346
|
+
case "l":
|
|
347
|
+
delta = -vLabel.width / 2;
|
|
348
|
+
break;
|
|
349
|
+
case "r":
|
|
350
|
+
delta = vLabel.width / 2;
|
|
351
|
+
break;
|
|
394
352
|
}
|
|
395
353
|
}
|
|
396
354
|
if (delta) {
|
|
397
355
|
sum += reverseSep ? delta : -delta;
|
|
398
356
|
}
|
|
399
357
|
delta = 0;
|
|
400
|
-
|
|
401
358
|
sum += (vLabel.dummy ? edgeSep : nodeSep) / 2;
|
|
402
359
|
sum += (wLabel.dummy ? edgeSep : nodeSep) / 2;
|
|
403
|
-
|
|
404
360
|
sum += wLabel.width / 2;
|
|
405
361
|
if (wLabel.hasOwnProperty("labelpos")) {
|
|
406
362
|
switch (wLabel.labelpos.toLowerCase()) {
|
|
407
|
-
|
|
408
|
-
|
|
363
|
+
case "l":
|
|
364
|
+
delta = wLabel.width / 2;
|
|
365
|
+
break;
|
|
366
|
+
case "r":
|
|
367
|
+
delta = -wLabel.width / 2;
|
|
368
|
+
break;
|
|
409
369
|
}
|
|
410
370
|
}
|
|
411
371
|
if (delta) {
|
|
412
372
|
sum += reverseSep ? delta : -delta;
|
|
413
373
|
}
|
|
414
374
|
delta = 0;
|
|
415
|
-
|
|
416
375
|
return sum;
|
|
417
376
|
};
|
|
418
377
|
}
|
|
419
|
-
|
|
420
378
|
function width(g, v) {
|
|
421
379
|
return g.node(v).width;
|
|
422
380
|
}
|
package/lib/position/index.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = position;
|
|
7
|
+
var util = _interopRequireWildcard(require("../util.js"));
|
|
8
|
+
var _bk = require("./bk.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
|
function position(g) {
|
|
9
12
|
g = util.asNonCompoundGraph(g);
|
|
10
|
-
|
|
11
13
|
positionY(g);
|
|
12
|
-
Object.entries(positionX(g)).forEach(([v, x]) => g.node(v).x = x);
|
|
14
|
+
Object.entries((0, _bk.positionX)(g)).forEach(([v, x]) => g.node(v).x = x);
|
|
13
15
|
}
|
|
14
|
-
|
|
15
16
|
function positionY(g) {
|
|
16
17
|
let layering = util.buildLayerMatrix(g);
|
|
17
18
|
let rankSep = g.graph().ranksep;
|
|
@@ -29,4 +30,4 @@ function positionY(g) {
|
|
|
29
30
|
prevY += maxHeight + rankSep;
|
|
30
31
|
});
|
|
31
32
|
}
|
|
32
|
-
|
|
33
|
+
module.exports = exports.default;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = feasibleTree;
|
|
7
|
+
var _graphlib = require("@dagrejs/graphlib");
|
|
8
|
+
var _util = require("./util.js");
|
|
8
9
|
/*
|
|
9
10
|
* Constructs a spanning tree with tight edges and adjusted the input node's
|
|
10
11
|
* ranks to achieve this. A tight edge is one that is has a length that matches
|
|
@@ -31,20 +32,20 @@ module.exports = feasibleTree;
|
|
|
31
32
|
* edges.
|
|
32
33
|
*/
|
|
33
34
|
function feasibleTree(g) {
|
|
34
|
-
var t = new Graph({
|
|
35
|
+
var t = new _graphlib.Graph({
|
|
36
|
+
directed: false
|
|
37
|
+
});
|
|
35
38
|
|
|
36
39
|
// Choose arbitrary node from which to start our tree
|
|
37
40
|
var start = g.nodes()[0];
|
|
38
41
|
var size = g.nodeCount();
|
|
39
42
|
t.setNode(start, {});
|
|
40
|
-
|
|
41
43
|
var edge, delta;
|
|
42
44
|
while (tightTree(t, g) < size) {
|
|
43
45
|
edge = findMinSlackEdge(t, g);
|
|
44
|
-
delta = t.hasNode(edge.v) ? slack(g, edge) : -slack(g, edge);
|
|
46
|
+
delta = t.hasNode(edge.v) ? (0, _util.slack)(g, edge) : -(0, _util.slack)(g, edge);
|
|
45
47
|
shiftRanks(t, g, delta);
|
|
46
48
|
}
|
|
47
|
-
|
|
48
49
|
return t;
|
|
49
50
|
}
|
|
50
51
|
|
|
@@ -56,15 +57,14 @@ function tightTree(t, g) {
|
|
|
56
57
|
function dfs(v) {
|
|
57
58
|
g.nodeEdges(v).forEach(e => {
|
|
58
59
|
var edgeV = e.v,
|
|
59
|
-
w =
|
|
60
|
-
if (!t.hasNode(w) && !slack(g, e)) {
|
|
60
|
+
w = v === edgeV ? e.w : edgeV;
|
|
61
|
+
if (!t.hasNode(w) && !(0, _util.slack)(g, e)) {
|
|
61
62
|
t.setNode(w, {});
|
|
62
63
|
t.setEdge(v, w, {});
|
|
63
64
|
dfs(w);
|
|
64
65
|
}
|
|
65
66
|
});
|
|
66
67
|
}
|
|
67
|
-
|
|
68
68
|
t.nodes().forEach(dfs);
|
|
69
69
|
return t.nodeCount();
|
|
70
70
|
}
|
|
@@ -75,21 +75,18 @@ function tightTree(t, g) {
|
|
|
75
75
|
*/
|
|
76
76
|
function findMinSlackEdge(t, g) {
|
|
77
77
|
const edges = g.edges();
|
|
78
|
-
|
|
79
78
|
return edges.reduce((acc, edge) => {
|
|
80
79
|
let edgeSlack = Number.POSITIVE_INFINITY;
|
|
81
80
|
if (t.hasNode(edge.v) !== t.hasNode(edge.w)) {
|
|
82
|
-
edgeSlack = slack(g, edge);
|
|
81
|
+
edgeSlack = (0, _util.slack)(g, edge);
|
|
83
82
|
}
|
|
84
|
-
|
|
85
83
|
if (edgeSlack < acc[0]) {
|
|
86
84
|
return [edgeSlack, edge];
|
|
87
85
|
}
|
|
88
|
-
|
|
89
86
|
return acc;
|
|
90
87
|
}, [Number.POSITIVE_INFINITY, null])[1];
|
|
91
88
|
}
|
|
92
|
-
|
|
93
89
|
function shiftRanks(t, g, delta) {
|
|
94
90
|
t.nodes().forEach(v => g.node(v).rank += delta);
|
|
95
91
|
}
|
|
92
|
+
module.exports = exports.default;
|
package/lib/rank/index.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = rank;
|
|
7
|
+
var rankUtil = _interopRequireWildcard(require("./util.js"));
|
|
8
|
+
var _feasibleTree = _interopRequireDefault(require("./feasible-tree.js"));
|
|
9
|
+
var _networkSimplex = _interopRequireDefault(require("./network-simplex.js"));
|
|
10
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
+
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); }
|
|
12
|
+
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; }
|
|
4
13
|
var longestPath = rankUtil.longestPath;
|
|
5
|
-
var feasibleTree = require("./feasible-tree");
|
|
6
|
-
var networkSimplex = require("./network-simplex");
|
|
7
|
-
|
|
8
|
-
module.exports = rank;
|
|
9
|
-
|
|
10
14
|
/*
|
|
11
15
|
* Assigns a rank to each node in the input graph that respects the "minlen"
|
|
12
16
|
* constraint specified on edges between nodes.
|
|
@@ -27,22 +31,28 @@ module.exports = rank;
|
|
|
27
31
|
* fix them up later.
|
|
28
32
|
*/
|
|
29
33
|
function rank(g) {
|
|
30
|
-
switch(g.graph().ranker) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
switch (g.graph().ranker) {
|
|
35
|
+
case "network-simplex":
|
|
36
|
+
networkSimplexRanker(g);
|
|
37
|
+
break;
|
|
38
|
+
case "tight-tree":
|
|
39
|
+
tightTreeRanker(g);
|
|
40
|
+
break;
|
|
41
|
+
case "longest-path":
|
|
42
|
+
longestPathRanker(g);
|
|
43
|
+
break;
|
|
44
|
+
default:
|
|
45
|
+
networkSimplexRanker(g);
|
|
35
46
|
}
|
|
36
47
|
}
|
|
37
48
|
|
|
38
49
|
// A fast and simple ranker, but results are far from optimal.
|
|
39
50
|
var longestPathRanker = longestPath;
|
|
40
|
-
|
|
41
51
|
function tightTreeRanker(g) {
|
|
42
52
|
longestPath(g);
|
|
43
|
-
|
|
53
|
+
(0, _feasibleTree.default)(g);
|
|
44
54
|
}
|
|
45
|
-
|
|
46
55
|
function networkSimplexRanker(g) {
|
|
47
|
-
|
|
56
|
+
(0, _networkSimplex.default)(g);
|
|
48
57
|
}
|
|
58
|
+
module.exports = exports.default;
|