@dagrejs/dagre 1.1.3 → 1.1.5
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 +1 -1
- package/dist/dagre.js +97 -60
- package/dist/dagre.min.js +32 -32
- package/index.d.ts +4 -4
- package/lib/acyclic.js +2 -2
- package/lib/add-border-segments.js +1 -1
- package/lib/coordinate-system.js +2 -2
- package/lib/layout.js +6 -6
- package/lib/nesting-graph.js +2 -1
- package/lib/order/build-layer-graph.js +1 -1
- package/lib/order/init-order.js +2 -1
- package/lib/order/sort-subgraph.js +2 -2
- package/lib/order/sort.js +1 -1
- package/lib/position/bk.js +7 -7
- package/lib/rank/index.js +6 -0
- package/lib/rank/network-simplex.js +1 -1
- package/lib/rank/util.js +7 -3
- package/lib/util.js +36 -11
- package/lib/version.js +1 -1
- package/package.json +2 -2
package/lib/position/bk.js
CHANGED
|
@@ -152,7 +152,7 @@ function hasConflict(conflicts, v, w) {
|
|
|
152
152
|
v = w;
|
|
153
153
|
w = tmp;
|
|
154
154
|
}
|
|
155
|
-
return !!conflicts[v] && conflicts[v]
|
|
155
|
+
return !!conflicts[v] && Object.hasOwn(conflicts[v], w);
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
/*
|
|
@@ -313,8 +313,8 @@ function findSmallestWidthAlignment(g, xss) {
|
|
|
313
313
|
*/
|
|
314
314
|
function alignCoordinates(xss, alignTo) {
|
|
315
315
|
let alignToVals = Object.values(alignTo),
|
|
316
|
-
alignToMin = Math.min
|
|
317
|
-
alignToMax = Math.max
|
|
316
|
+
alignToMin = util.applyWithChunking(Math.min, alignToVals),
|
|
317
|
+
alignToMax = util.applyWithChunking(Math.max, alignToVals);
|
|
318
318
|
|
|
319
319
|
["u", "d"].forEach(vert => {
|
|
320
320
|
["l", "r"].forEach(horiz => {
|
|
@@ -324,9 +324,9 @@ function alignCoordinates(xss, alignTo) {
|
|
|
324
324
|
if (xs === alignTo) return;
|
|
325
325
|
|
|
326
326
|
let xsVals = Object.values(xs);
|
|
327
|
-
let delta = alignToMin - Math.min
|
|
327
|
+
let delta = alignToMin - util.applyWithChunking(Math.min, xsVals);
|
|
328
328
|
if (horiz !== "l") {
|
|
329
|
-
delta = alignToMax - Math.max
|
|
329
|
+
delta = alignToMax - util.applyWithChunking(Math.max,xsVals);
|
|
330
330
|
}
|
|
331
331
|
|
|
332
332
|
if (delta) {
|
|
@@ -389,7 +389,7 @@ function sep(nodeSep, edgeSep, reverseSep) {
|
|
|
389
389
|
let delta;
|
|
390
390
|
|
|
391
391
|
sum += vLabel.width / 2;
|
|
392
|
-
if (
|
|
392
|
+
if (Object.hasOwn(vLabel, "labelpos")) {
|
|
393
393
|
switch (vLabel.labelpos.toLowerCase()) {
|
|
394
394
|
case "l": delta = -vLabel.width / 2; break;
|
|
395
395
|
case "r": delta = vLabel.width / 2; break;
|
|
@@ -404,7 +404,7 @@ function sep(nodeSep, edgeSep, reverseSep) {
|
|
|
404
404
|
sum += (wLabel.dummy ? edgeSep : nodeSep) / 2;
|
|
405
405
|
|
|
406
406
|
sum += wLabel.width / 2;
|
|
407
|
-
if (
|
|
407
|
+
if (Object.hasOwn(wLabel, "labelpos")) {
|
|
408
408
|
switch (wLabel.labelpos.toLowerCase()) {
|
|
409
409
|
case "l": delta = wLabel.width / 2; break;
|
|
410
410
|
case "r": delta = -wLabel.width / 2; break;
|
package/lib/rank/index.js
CHANGED
|
@@ -27,10 +27,16 @@ module.exports = rank;
|
|
|
27
27
|
* fix them up later.
|
|
28
28
|
*/
|
|
29
29
|
function rank(g) {
|
|
30
|
+
var ranker = g.graph().ranker;
|
|
31
|
+
if (ranker instanceof Function) {
|
|
32
|
+
return ranker(g);
|
|
33
|
+
}
|
|
34
|
+
|
|
30
35
|
switch(g.graph().ranker) {
|
|
31
36
|
case "network-simplex": networkSimplexRanker(g); break;
|
|
32
37
|
case "tight-tree": tightTreeRanker(g); break;
|
|
33
38
|
case "longest-path": longestPathRanker(g); break;
|
|
39
|
+
case "none": break;
|
|
34
40
|
default: networkSimplexRanker(g);
|
|
35
41
|
}
|
|
36
42
|
}
|
|
@@ -132,7 +132,7 @@ function dfsAssignLowLim(tree, visited, nextLim, v, parent) {
|
|
|
132
132
|
|
|
133
133
|
visited[v] = true;
|
|
134
134
|
tree.neighbors(v).forEach(w => {
|
|
135
|
-
if (!
|
|
135
|
+
if (!Object.hasOwn(visited, w)) {
|
|
136
136
|
nextLim = dfsAssignLowLim(tree, visited, nextLim, w, v);
|
|
137
137
|
}
|
|
138
138
|
});
|
package/lib/rank/util.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
const { applyWithChunking } = require("../util");
|
|
4
|
+
|
|
3
5
|
module.exports = {
|
|
4
6
|
longestPath: longestPath,
|
|
5
7
|
slack: slack
|
|
@@ -31,18 +33,20 @@ function longestPath(g) {
|
|
|
31
33
|
|
|
32
34
|
function dfs(v) {
|
|
33
35
|
var label = g.node(v);
|
|
34
|
-
if (
|
|
36
|
+
if (Object.hasOwn(visited, v)) {
|
|
35
37
|
return label.rank;
|
|
36
38
|
}
|
|
37
39
|
visited[v] = true;
|
|
38
40
|
|
|
39
|
-
|
|
41
|
+
let outEdgesMinLens = g.outEdges(v).map(e => {
|
|
40
42
|
if (e == null) {
|
|
41
43
|
return Number.POSITIVE_INFINITY;
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
return dfs(e.w) - g.edge(e).minlen;
|
|
45
|
-
})
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
var rank = applyWithChunking(Math.min, outEdgesMinLens);
|
|
46
50
|
|
|
47
51
|
if (rank === Number.POSITIVE_INFINITY) {
|
|
48
52
|
rank = 0;
|
package/lib/util.js
CHANGED
|
@@ -7,6 +7,7 @@ let Graph = require("@dagrejs/graphlib").Graph;
|
|
|
7
7
|
module.exports = {
|
|
8
8
|
addBorderNode,
|
|
9
9
|
addDummyNode,
|
|
10
|
+
applyWithChunking,
|
|
10
11
|
asNonCompoundGraph,
|
|
11
12
|
buildLayerMatrix,
|
|
12
13
|
intersectRect,
|
|
@@ -30,10 +31,10 @@ module.exports = {
|
|
|
30
31
|
* Adds a dummy node to the graph and return v.
|
|
31
32
|
*/
|
|
32
33
|
function addDummyNode(g, type, attrs, name) {
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
var v = name;
|
|
35
|
+
while (g.hasNode(v)) {
|
|
35
36
|
v = uniqueId(name);
|
|
36
|
-
}
|
|
37
|
+
}
|
|
37
38
|
|
|
38
39
|
attrs.dummy = type;
|
|
39
40
|
g.setNode(v, attrs);
|
|
@@ -153,17 +154,18 @@ function buildLayerMatrix(g) {
|
|
|
153
154
|
* rank(v) >= 0 and at least one node w has rank(w) = 0.
|
|
154
155
|
*/
|
|
155
156
|
function normalizeRanks(g) {
|
|
156
|
-
let
|
|
157
|
+
let nodeRanks = g.nodes().map(v => {
|
|
157
158
|
let rank = g.node(v).rank;
|
|
158
159
|
if (rank === undefined) {
|
|
159
160
|
return Number.MAX_VALUE;
|
|
160
161
|
}
|
|
161
162
|
|
|
162
163
|
return rank;
|
|
163
|
-
})
|
|
164
|
+
});
|
|
165
|
+
let min = applyWithChunking(Math.min, nodeRanks);
|
|
164
166
|
g.nodes().forEach(v => {
|
|
165
167
|
let node = g.node(v);
|
|
166
|
-
if (
|
|
168
|
+
if (Object.hasOwn(node, "rank")) {
|
|
167
169
|
node.rank -= min;
|
|
168
170
|
}
|
|
169
171
|
});
|
|
@@ -171,7 +173,8 @@ function normalizeRanks(g) {
|
|
|
171
173
|
|
|
172
174
|
function removeEmptyRanks(g) {
|
|
173
175
|
// Ranks may not start at 0, so we need to offset them
|
|
174
|
-
let
|
|
176
|
+
let nodeRanks = g.nodes().map(v => g.node(v).rank);
|
|
177
|
+
let offset = applyWithChunking(Math.min, nodeRanks);
|
|
175
178
|
|
|
176
179
|
let layers = [];
|
|
177
180
|
g.nodes().forEach(v => {
|
|
@@ -205,15 +208,37 @@ function addBorderNode(g, prefix, rank, order) {
|
|
|
205
208
|
return addDummyNode(g, "border", node, prefix);
|
|
206
209
|
}
|
|
207
210
|
|
|
211
|
+
function splitToChunks(array, chunkSize = CHUNKING_THRESHOLD) {
|
|
212
|
+
const chunks = [];
|
|
213
|
+
for (let i = 0; i < array.length; i += chunkSize) {
|
|
214
|
+
const chunk = array.slice(i, i + chunkSize);
|
|
215
|
+
chunks.push(chunk);
|
|
216
|
+
}
|
|
217
|
+
return chunks;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const CHUNKING_THRESHOLD = 65535;
|
|
221
|
+
|
|
222
|
+
function applyWithChunking(fn, argsArray) {
|
|
223
|
+
if(argsArray.length > CHUNKING_THRESHOLD) {
|
|
224
|
+
const chunks = splitToChunks(argsArray);
|
|
225
|
+
return fn.apply(null, chunks.map(chunk => fn.apply(null, chunk)));
|
|
226
|
+
} else {
|
|
227
|
+
return fn.apply(null, argsArray);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
208
231
|
function maxRank(g) {
|
|
209
|
-
|
|
232
|
+
const nodes = g.nodes();
|
|
233
|
+
const nodeRanks = nodes.map(v => {
|
|
210
234
|
let rank = g.node(v).rank;
|
|
211
235
|
if (rank === undefined) {
|
|
212
236
|
return Number.MIN_VALUE;
|
|
213
237
|
}
|
|
214
|
-
|
|
215
238
|
return rank;
|
|
216
|
-
})
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
return applyWithChunking(Math.max, nodeRanks);
|
|
217
242
|
}
|
|
218
243
|
|
|
219
244
|
/*
|
|
@@ -253,7 +278,7 @@ function notime(name, fn) {
|
|
|
253
278
|
let idCounter = 0;
|
|
254
279
|
function uniqueId(prefix) {
|
|
255
280
|
var id = ++idCounter;
|
|
256
|
-
return
|
|
281
|
+
return prefix + ("" + id);
|
|
257
282
|
}
|
|
258
283
|
|
|
259
284
|
function range(start, limit, step = 1) {
|
package/lib/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports = "1.1.
|
|
1
|
+
module.exports = "1.1.5";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dagrejs/dagre",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.5",
|
|
4
4
|
"description": "Graph layout for JavaScript",
|
|
5
5
|
"author": "Chris Pettitt <cpettitt@gmail.com>",
|
|
6
6
|
"contributors": [
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"layout"
|
|
25
25
|
],
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@dagrejs/graphlib": "2.2.
|
|
27
|
+
"@dagrejs/graphlib": "2.2.4"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"benchmark": "2.1.4",
|