@dagrejs/dagre 1.0.2 → 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/README.md +0 -7
- package/dist/dagre.js +443 -445
- package/dist/dagre.min.js +52 -52
- package/index.d.ts +18 -3
- package/lib/acyclic.js +20 -28
- package/lib/add-border-segments.js +23 -15
- package/lib/coordinate-system.js +13 -23
- package/lib/data/list.js +40 -37
- package/lib/debug.js +31 -22
- package/lib/greedy-fas.js +60 -55
- package/lib/index.js +38 -0
- package/lib/layout.js +158 -155
- package/lib/nesting-graph.js +35 -40
- package/lib/normalize.js +34 -30
- package/lib/order/add-subgraph-constraints.js +9 -5
- package/lib/order/barycenter.js +17 -9
- package/lib/order/build-layer-graph.js +24 -18
- package/lib/order/cross-count.js +22 -19
- package/lib/order/index.js +37 -28
- package/lib/order/init-order.js +14 -13
- package/lib/order/resolve-conflicts.js +20 -30
- package/lib/order/sort-subgraph.js +25 -31
- package/lib/order/sort.js +18 -17
- package/lib/parent-dummy-chains.js +36 -38
- package/lib/position/bk.js +103 -145
- package/lib/position/index.js +14 -13
- package/lib/rank/feasible-tree.js +15 -18
- package/lib/rank/index.js +25 -15
- package/lib/rank/network-simplex.js +22 -43
- package/lib/rank/util.js +6 -12
- package/lib/util.js +69 -84
- 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
|
|
@@ -39,10 +40,9 @@ module.exports = {
|
|
|
39
40
|
* single node in the layers being scanned.
|
|
40
41
|
*/
|
|
41
42
|
function findType1Conflicts(g, layering) {
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
let conflicts = {};
|
|
44
44
|
function visitLayer(prevLayer, layer) {
|
|
45
|
-
|
|
45
|
+
let
|
|
46
46
|
// last visited node in the previous layer that is incident on an inner
|
|
47
47
|
// segment.
|
|
48
48
|
k0 = 0,
|
|
@@ -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
|
-
|
|
56
|
-
var w = findOtherInnerSegmentNode(g, v),
|
|
54
|
+
layer.forEach((v, i) => {
|
|
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(
|
|
61
|
-
g.predecessors(scanNode).forEach(
|
|
62
|
-
|
|
58
|
+
layer.slice(scanPos, i + 1).forEach(scanNode => {
|
|
59
|
+
g.predecessors(scanNode).forEach(u => {
|
|
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,42 +68,34 @@ 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
|
-
|
|
84
|
-
|
|
77
|
+
let conflicts = {};
|
|
85
78
|
function scan(south, southPos, southEnd, prevNorthBorder, nextNorthBorder) {
|
|
86
|
-
|
|
87
|
-
util.range(southPos, southEnd).forEach(
|
|
79
|
+
let v;
|
|
80
|
+
util.range(southPos, southEnd).forEach(i => {
|
|
88
81
|
v = south[i];
|
|
89
82
|
if (g.node(v).dummy) {
|
|
90
|
-
g.predecessors(v).forEach(
|
|
91
|
-
|
|
92
|
-
if (uNode.dummy &&
|
|
93
|
-
(uNode.order < prevNorthBorder || uNode.order > nextNorthBorder)) {
|
|
83
|
+
g.predecessors(v).forEach(u => {
|
|
84
|
+
let uNode = g.node(u);
|
|
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
|
-
south.forEach(function(v, southLookahead) {
|
|
96
|
+
south.forEach((v, southLookahead) => {
|
|
108
97
|
if (g.node(v).dummy === "border") {
|
|
109
|
-
|
|
98
|
+
let predecessors = g.predecessors(v);
|
|
110
99
|
if (predecessors.length) {
|
|
111
100
|
nextNorthPos = g.node(predecessors[0]).order;
|
|
112
101
|
scan(south, southPos, southLookahead, prevNorthPos, nextNorthPos);
|
|
@@ -116,37 +105,31 @@ 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
|
-
var conflictsV = conflicts[v];
|
|
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;
|
|
150
133
|
v = w;
|
|
151
134
|
w = tmp;
|
|
152
135
|
}
|
|
@@ -162,33 +145,30 @@ function hasConflict(conflicts, v, w) {
|
|
|
162
145
|
* blocks would be split in that scenario.
|
|
163
146
|
*/
|
|
164
147
|
function verticalAlignment(g, layering, conflicts, neighborFn) {
|
|
165
|
-
|
|
148
|
+
let root = {},
|
|
166
149
|
align = {},
|
|
167
150
|
pos = {};
|
|
168
151
|
|
|
169
152
|
// We cache the position here based on the layering because the graph and
|
|
170
153
|
// layering may be out of sync. The layering matrix is manipulated to
|
|
171
154
|
// generate different extreme alignments.
|
|
172
|
-
layering.forEach(
|
|
173
|
-
layer.forEach(
|
|
155
|
+
layering.forEach(layer => {
|
|
156
|
+
layer.forEach((v, order) => {
|
|
174
157
|
root[v] = v;
|
|
175
158
|
align[v] = v;
|
|
176
159
|
pos[v] = order;
|
|
177
160
|
});
|
|
178
161
|
});
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
var ws = neighborFn(v);
|
|
162
|
+
layering.forEach(layer => {
|
|
163
|
+
let prevIdx = -1;
|
|
164
|
+
layer.forEach(v => {
|
|
165
|
+
let ws = neighborFn(v);
|
|
184
166
|
if (ws.length) {
|
|
185
167
|
ws = ws.sort((a, b) => pos[a] - pos[b]);
|
|
186
|
-
|
|
187
|
-
for (
|
|
188
|
-
|
|
189
|
-
if (align[v] === v &&
|
|
190
|
-
prevIdx < pos[w] &&
|
|
191
|
-
!hasConflict(conflicts, v, w)) {
|
|
168
|
+
let mp = (ws.length - 1) / 2;
|
|
169
|
+
for (let i = Math.floor(mp), il = Math.ceil(mp); i <= il; ++i) {
|
|
170
|
+
let w = ws[i];
|
|
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,24 +177,24 @@ 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
|
|
207
188
|
// sweeps. The first sweep places blocks with the smallest possible
|
|
208
189
|
// coordinates. The second sweep removes unused space by moving blocks to the
|
|
209
190
|
// greatest coordinates without violating separation.
|
|
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
|
-
|
|
216
|
-
|
|
217
|
-
|
|
195
|
+
let stack = blockG.nodes();
|
|
196
|
+
let elem = stack.pop();
|
|
197
|
+
let visited = {};
|
|
218
198
|
while (elem) {
|
|
219
199
|
if (visited[elem]) {
|
|
220
200
|
setXsFunc(elem);
|
|
@@ -223,49 +203,42 @@ 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
|
}
|
|
230
209
|
|
|
231
210
|
// First pass, assign smallest coordinates
|
|
232
211
|
function pass1(elem) {
|
|
233
|
-
xs[elem] = blockG.inEdges(elem).reduce(
|
|
212
|
+
xs[elem] = blockG.inEdges(elem).reduce((acc, e) => {
|
|
234
213
|
return Math.max(acc, xs[e.v] + blockG.edge(e));
|
|
235
214
|
}, 0);
|
|
236
215
|
}
|
|
237
216
|
|
|
238
217
|
// Second pass, assign greatest coordinates
|
|
239
218
|
function pass2(elem) {
|
|
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
|
-
var node = g.node(elem);
|
|
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
|
-
|
|
235
|
+
let blockGraph = new _graphlib.Graph(),
|
|
262
236
|
graphLabel = g.graph(),
|
|
263
237
|
sepFn = sep(graphLabel.nodesep, graphLabel.edgesep, reverseSep);
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
var vRoot = root[v];
|
|
238
|
+
layering.forEach(layer => {
|
|
239
|
+
let u;
|
|
240
|
+
layer.forEach(v => {
|
|
241
|
+
let vRoot = root[v];
|
|
269
242
|
blockGraph.setNode(vRoot);
|
|
270
243
|
if (u) {
|
|
271
244
|
var uRoot = root[u],
|
|
@@ -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
|
|
|
@@ -284,16 +256,13 @@ function buildBlockGraph(g, layering, root, reverseSep) {
|
|
|
284
256
|
*/
|
|
285
257
|
function findSmallestWidthAlignment(g, xss) {
|
|
286
258
|
return Object.values(xss).reduce((currentMinAndXs, xs) => {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
259
|
+
let max = Number.NEGATIVE_INFINITY;
|
|
260
|
+
let min = Number.POSITIVE_INFINITY;
|
|
290
261
|
Object.entries(xs).forEach(([v, x]) => {
|
|
291
|
-
|
|
292
|
-
|
|
262
|
+
let halfWidth = width(g, v) / 2;
|
|
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];
|
|
@@ -310,113 +279,102 @@ function findSmallestWidthAlignment(g, xss) {
|
|
|
310
279
|
* coordinate of the smallest width alignment.
|
|
311
280
|
*/
|
|
312
281
|
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
|
-
|
|
318
|
-
|
|
319
|
-
var alignment = vert + horiz,
|
|
285
|
+
["u", "d"].forEach(vert => {
|
|
286
|
+
["l", "r"].forEach(horiz => {
|
|
287
|
+
let alignment = vert + horiz,
|
|
320
288
|
xs = xss[alignment];
|
|
321
|
-
|
|
322
289
|
if (xs === alignTo) return;
|
|
323
|
-
|
|
324
|
-
var xsVals = Object.values(xs);
|
|
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
|
-
return util.mapValues(xss.ul,
|
|
302
|
+
return util.mapValues(xss.ul, (num, v) => {
|
|
339
303
|
if (align) {
|
|
340
304
|
return xss[align.toLowerCase()][v];
|
|
341
305
|
} else {
|
|
342
|
-
|
|
306
|
+
let xs = Object.values(xss).map(xs => xs[v]).sort((a, b) => a - b);
|
|
343
307
|
return (xs[1] + xs[2]) / 2;
|
|
344
308
|
}
|
|
345
309
|
});
|
|
346
310
|
}
|
|
347
|
-
|
|
348
311
|
function positionX(g) {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
var xss = {};
|
|
355
|
-
var adjustedLayering;
|
|
356
|
-
["u", "d"].forEach(function(vert) {
|
|
312
|
+
let layering = util.buildLayerMatrix(g);
|
|
313
|
+
let conflicts = Object.assign(findType1Conflicts(g, layering), findType2Conflicts(g, layering));
|
|
314
|
+
let xss = {};
|
|
315
|
+
let adjustedLayering;
|
|
316
|
+
["u", "d"].forEach(vert => {
|
|
357
317
|
adjustedLayering = vert === "u" ? layering : Object.values(layering).reverse();
|
|
358
|
-
["l", "r"].forEach(
|
|
318
|
+
["l", "r"].forEach(horiz => {
|
|
359
319
|
if (horiz === "r") {
|
|
360
320
|
adjustedLayering = adjustedLayering.map(inner => {
|
|
361
321
|
return Object.values(inner).reverse();
|
|
362
322
|
});
|
|
363
323
|
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
var xs = horizontalCompaction(g, adjustedLayering,
|
|
368
|
-
align.root, align.align, horiz === "r");
|
|
324
|
+
let neighborFn = (vert === "u" ? g.predecessors : g.successors).bind(g);
|
|
325
|
+
let align = verticalAlignment(g, adjustedLayering, conflicts, neighborFn);
|
|
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
|
-
var smallestWidth = findSmallestWidthAlignment(g, xss);
|
|
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
|
-
return
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
338
|
+
return (g, v, w) => {
|
|
339
|
+
let vLabel = g.node(v);
|
|
340
|
+
let wLabel = g.node(w);
|
|
341
|
+
let sum = 0;
|
|
342
|
+
let delta;
|
|
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,22 +1,23 @@
|
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
layering.forEach(
|
|
17
|
+
let layering = util.buildLayerMatrix(g);
|
|
18
|
+
let rankSep = g.graph().ranksep;
|
|
19
|
+
let prevY = 0;
|
|
20
|
+
layering.forEach(layer => {
|
|
20
21
|
const maxHeight = layer.reduce((acc, v) => {
|
|
21
22
|
const height = g.node(v).height;
|
|
22
23
|
if (acc > height) {
|
|
@@ -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
|
|
|
@@ -54,17 +55,16 @@ function feasibleTree(g) {
|
|
|
54
55
|
*/
|
|
55
56
|
function tightTree(t, g) {
|
|
56
57
|
function dfs(v) {
|
|
57
|
-
g.nodeEdges(v).forEach(
|
|
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;
|