@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
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
var
|
|
8
|
-
var
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
var preorder = _graphlib.alg.preorder;
|
|
13
|
-
var postorder = _graphlib.alg.postorder;
|
|
3
|
+
var feasibleTree = require("./feasible-tree");
|
|
4
|
+
var slack = require("./util").slack;
|
|
5
|
+
var initRank = require("./util").longestPath;
|
|
6
|
+
var preorder = require("@dagrejs/graphlib").alg.preorder;
|
|
7
|
+
var postorder = require("@dagrejs/graphlib").alg.postorder;
|
|
8
|
+
var simplify = require("../util").simplify;
|
|
9
|
+
|
|
10
|
+
module.exports = networkSimplex;
|
|
11
|
+
|
|
14
12
|
// Expose some internals for testing purposes
|
|
15
13
|
networkSimplex.initLowLimValues = initLowLimValues;
|
|
16
14
|
networkSimplex.initCutValues = initCutValues;
|
|
@@ -53,13 +51,14 @@ networkSimplex.exchangeEdges = exchangeEdges;
|
|
|
53
51
|
* structure of the overall algorithm.
|
|
54
52
|
*/
|
|
55
53
|
function networkSimplex(g) {
|
|
56
|
-
g =
|
|
57
|
-
(
|
|
58
|
-
var t = (
|
|
54
|
+
g = simplify(g);
|
|
55
|
+
initRank(g);
|
|
56
|
+
var t = feasibleTree(g);
|
|
59
57
|
initLowLimValues(t);
|
|
60
58
|
initCutValues(t, g);
|
|
59
|
+
|
|
61
60
|
var e, f;
|
|
62
|
-
while (e = leaveEdge(t)) {
|
|
61
|
+
while ((e = leaveEdge(t))) {
|
|
63
62
|
f = enterEdge(t, g, e);
|
|
64
63
|
exchangeEdges(t, g, e, f);
|
|
65
64
|
}
|
|
@@ -73,6 +72,7 @@ function initCutValues(t, g) {
|
|
|
73
72
|
vs = vs.slice(0, vs.length - 1);
|
|
74
73
|
vs.forEach(v => assignCutValue(t, g, v));
|
|
75
74
|
}
|
|
75
|
+
|
|
76
76
|
function assignCutValue(t, g, child) {
|
|
77
77
|
var childLab = t.node(child);
|
|
78
78
|
var parent = childLab.parent;
|
|
@@ -92,17 +92,22 @@ function calcCutValue(t, g, child) {
|
|
|
92
92
|
var graphEdge = g.edge(child, parent);
|
|
93
93
|
// The accumulated cut value for the edge between this node and its parent
|
|
94
94
|
var cutValue = 0;
|
|
95
|
+
|
|
95
96
|
if (!graphEdge) {
|
|
96
97
|
childIsTail = false;
|
|
97
98
|
graphEdge = g.edge(parent, child);
|
|
98
99
|
}
|
|
100
|
+
|
|
99
101
|
cutValue = graphEdge.weight;
|
|
102
|
+
|
|
100
103
|
g.nodeEdges(child).forEach(e => {
|
|
101
104
|
var isOutEdge = e.v === child,
|
|
102
105
|
other = isOutEdge ? e.w : e.v;
|
|
106
|
+
|
|
103
107
|
if (other !== parent) {
|
|
104
108
|
var pointsToHead = isOutEdge === childIsTail,
|
|
105
109
|
otherWeight = g.edge(e).weight;
|
|
110
|
+
|
|
106
111
|
cutValue += pointsToHead ? otherWeight : -otherWeight;
|
|
107
112
|
if (isTreeEdge(t, child, other)) {
|
|
108
113
|
var otherCutValue = t.edge(child, other).cutvalue;
|
|
@@ -110,23 +115,28 @@ function calcCutValue(t, g, child) {
|
|
|
110
115
|
}
|
|
111
116
|
}
|
|
112
117
|
});
|
|
118
|
+
|
|
113
119
|
return cutValue;
|
|
114
120
|
}
|
|
121
|
+
|
|
115
122
|
function initLowLimValues(tree, root) {
|
|
116
123
|
if (arguments.length < 2) {
|
|
117
124
|
root = tree.nodes()[0];
|
|
118
125
|
}
|
|
119
126
|
dfsAssignLowLim(tree, {}, 1, root);
|
|
120
127
|
}
|
|
128
|
+
|
|
121
129
|
function dfsAssignLowLim(tree, visited, nextLim, v, parent) {
|
|
122
130
|
var low = nextLim;
|
|
123
131
|
var label = tree.node(v);
|
|
132
|
+
|
|
124
133
|
visited[v] = true;
|
|
125
134
|
tree.neighbors(v).forEach(w => {
|
|
126
135
|
if (!visited.hasOwnProperty(w)) {
|
|
127
136
|
nextLim = dfsAssignLowLim(tree, visited, nextLim, w, v);
|
|
128
137
|
}
|
|
129
138
|
});
|
|
139
|
+
|
|
130
140
|
label.low = low;
|
|
131
141
|
label.lim = nextLim++;
|
|
132
142
|
if (parent) {
|
|
@@ -135,11 +145,14 @@ function dfsAssignLowLim(tree, visited, nextLim, v, parent) {
|
|
|
135
145
|
// TODO should be able to remove this when we incrementally update low lim
|
|
136
146
|
delete label.parent;
|
|
137
147
|
}
|
|
148
|
+
|
|
138
149
|
return nextLim;
|
|
139
150
|
}
|
|
151
|
+
|
|
140
152
|
function leaveEdge(tree) {
|
|
141
153
|
return tree.edges().find(e => tree.edge(e).cutvalue < 0);
|
|
142
154
|
}
|
|
155
|
+
|
|
143
156
|
function enterEdge(t, g, edge) {
|
|
144
157
|
var v = edge.v;
|
|
145
158
|
var w = edge.w;
|
|
@@ -151,6 +164,7 @@ function enterEdge(t, g, edge) {
|
|
|
151
164
|
v = edge.w;
|
|
152
165
|
w = edge.v;
|
|
153
166
|
}
|
|
167
|
+
|
|
154
168
|
var vLabel = t.node(v);
|
|
155
169
|
var wLabel = t.node(w);
|
|
156
170
|
var tailLabel = vLabel;
|
|
@@ -162,16 +176,21 @@ function enterEdge(t, g, edge) {
|
|
|
162
176
|
tailLabel = wLabel;
|
|
163
177
|
flip = true;
|
|
164
178
|
}
|
|
179
|
+
|
|
165
180
|
var candidates = g.edges().filter(edge => {
|
|
166
|
-
return flip === isDescendant(t, t.node(edge.v), tailLabel) &&
|
|
181
|
+
return flip === isDescendant(t, t.node(edge.v), tailLabel) &&
|
|
182
|
+
flip !== isDescendant(t, t.node(edge.w), tailLabel);
|
|
167
183
|
});
|
|
184
|
+
|
|
168
185
|
return candidates.reduce((acc, edge) => {
|
|
169
|
-
if (
|
|
186
|
+
if (slack(g, edge) < slack(g, acc)) {
|
|
170
187
|
return edge;
|
|
171
188
|
}
|
|
189
|
+
|
|
172
190
|
return acc;
|
|
173
191
|
});
|
|
174
192
|
}
|
|
193
|
+
|
|
175
194
|
function exchangeEdges(t, g, e, f) {
|
|
176
195
|
var v = e.v;
|
|
177
196
|
var w = e.w;
|
|
@@ -181,6 +200,7 @@ function exchangeEdges(t, g, e, f) {
|
|
|
181
200
|
initCutValues(t, g);
|
|
182
201
|
updateRanks(t, g);
|
|
183
202
|
}
|
|
203
|
+
|
|
184
204
|
function updateRanks(t, g) {
|
|
185
205
|
var root = t.nodes().find(v => !g.node(v).parent);
|
|
186
206
|
var vs = preorder(t, root);
|
|
@@ -189,10 +209,12 @@ function updateRanks(t, g) {
|
|
|
189
209
|
var parent = t.node(v).parent,
|
|
190
210
|
edge = g.edge(v, parent),
|
|
191
211
|
flipped = false;
|
|
212
|
+
|
|
192
213
|
if (!edge) {
|
|
193
214
|
edge = g.edge(parent, v);
|
|
194
215
|
flipped = true;
|
|
195
216
|
}
|
|
217
|
+
|
|
196
218
|
g.node(v).rank = g.node(parent).rank + (flipped ? edge.minlen : -edge.minlen);
|
|
197
219
|
});
|
|
198
220
|
}
|
|
@@ -211,4 +233,3 @@ function isTreeEdge(tree, u, v) {
|
|
|
211
233
|
function isDescendant(tree, vLabel, rootLabel) {
|
|
212
234
|
return rootLabel.low <= vLabel.lim && vLabel.lim <= rootLabel.lim;
|
|
213
235
|
}
|
|
214
|
-
module.exports = exports.default;
|
package/lib/rank/util.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
module.exports = {
|
|
4
|
+
longestPath: longestPath,
|
|
5
|
+
slack: slack
|
|
6
|
+
};
|
|
7
|
+
|
|
3
8
|
/*
|
|
4
9
|
* Initializes ranks for the input graph using the longest path algorithm. This
|
|
5
10
|
* algorithm scales well and is fast in practice, it yields rather poor
|
|
@@ -21,30 +26,31 @@
|
|
|
21
26
|
*
|
|
22
27
|
* 1. Each node will be assign an (unnormalized) "rank" property.
|
|
23
28
|
*/
|
|
24
|
-
Object.defineProperty(exports, "__esModule", {
|
|
25
|
-
value: true
|
|
26
|
-
});
|
|
27
|
-
exports.longestPath = longestPath;
|
|
28
|
-
exports.slack = slack;
|
|
29
29
|
function longestPath(g) {
|
|
30
30
|
var visited = {};
|
|
31
|
+
|
|
31
32
|
function dfs(v) {
|
|
32
33
|
var label = g.node(v);
|
|
33
34
|
if (visited.hasOwnProperty(v)) {
|
|
34
35
|
return label.rank;
|
|
35
36
|
}
|
|
36
37
|
visited[v] = true;
|
|
38
|
+
|
|
37
39
|
var rank = Math.min(...g.outEdges(v).map(e => {
|
|
38
40
|
if (e == null) {
|
|
39
41
|
return Number.POSITIVE_INFINITY;
|
|
40
42
|
}
|
|
43
|
+
|
|
41
44
|
return dfs(e.w) - g.edge(e).minlen;
|
|
42
45
|
}));
|
|
46
|
+
|
|
43
47
|
if (rank === Number.POSITIVE_INFINITY) {
|
|
44
48
|
rank = 0;
|
|
45
49
|
}
|
|
46
|
-
|
|
50
|
+
|
|
51
|
+
return (label.rank = rank);
|
|
47
52
|
}
|
|
53
|
+
|
|
48
54
|
g.sources().forEach(dfs);
|
|
49
55
|
}
|
|
50
56
|
|
package/lib/util.js
CHANGED
|
@@ -2,29 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
"use strict";
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
5
|
+
let Graph = require("@dagrejs/graphlib").Graph;
|
|
6
|
+
|
|
7
|
+
module.exports = {
|
|
8
|
+
addBorderNode,
|
|
9
|
+
addDummyNode,
|
|
10
|
+
asNonCompoundGraph,
|
|
11
|
+
buildLayerMatrix,
|
|
12
|
+
intersectRect,
|
|
13
|
+
mapValues,
|
|
14
|
+
maxRank,
|
|
15
|
+
normalizeRanks,
|
|
16
|
+
notime,
|
|
17
|
+
partition,
|
|
18
|
+
pick,
|
|
19
|
+
predecessorWeights,
|
|
20
|
+
range,
|
|
21
|
+
removeEmptyRanks,
|
|
22
|
+
simplify,
|
|
23
|
+
successorWeights,
|
|
24
|
+
time,
|
|
25
|
+
uniqueId,
|
|
26
|
+
zipObject,
|
|
27
|
+
};
|
|
28
|
+
|
|
28
29
|
/*
|
|
29
30
|
* Adds a dummy node to the graph and return v.
|
|
30
31
|
*/
|
|
@@ -33,6 +34,7 @@ function addDummyNode(g, type, attrs, name) {
|
|
|
33
34
|
do {
|
|
34
35
|
v = uniqueId(name);
|
|
35
36
|
} while (g.hasNode(v));
|
|
37
|
+
|
|
36
38
|
attrs.dummy = type;
|
|
37
39
|
g.setNode(v, attrs);
|
|
38
40
|
return v;
|
|
@@ -43,13 +45,10 @@ function addDummyNode(g, type, attrs, name) {
|
|
|
43
45
|
* associated with multi-edges.
|
|
44
46
|
*/
|
|
45
47
|
function simplify(g) {
|
|
46
|
-
let simplified = new
|
|
48
|
+
let simplified = new Graph().setGraph(g.graph());
|
|
47
49
|
g.nodes().forEach(v => simplified.setNode(v, g.node(v)));
|
|
48
50
|
g.edges().forEach(e => {
|
|
49
|
-
let simpleLabel = simplified.edge(e.v, e.w) || {
|
|
50
|
-
weight: 0,
|
|
51
|
-
minlen: 1
|
|
52
|
-
};
|
|
51
|
+
let simpleLabel = simplified.edge(e.v, e.w) || { weight: 0, minlen: 1 };
|
|
53
52
|
let label = g.edge(e);
|
|
54
53
|
simplified.setEdge(e.v, e.w, {
|
|
55
54
|
weight: simpleLabel.weight + label.weight,
|
|
@@ -58,10 +57,9 @@ function simplify(g) {
|
|
|
58
57
|
});
|
|
59
58
|
return simplified;
|
|
60
59
|
}
|
|
60
|
+
|
|
61
61
|
function asNonCompoundGraph(g) {
|
|
62
|
-
let simplified = new
|
|
63
|
-
multigraph: g.isMultigraph()
|
|
64
|
-
}).setGraph(g.graph());
|
|
62
|
+
let simplified = new Graph({ multigraph: g.isMultigraph() }).setGraph(g.graph());
|
|
65
63
|
g.nodes().forEach(v => {
|
|
66
64
|
if (!g.children(v).length) {
|
|
67
65
|
simplified.setNode(v, g.node(v));
|
|
@@ -72,6 +70,7 @@ function asNonCompoundGraph(g) {
|
|
|
72
70
|
});
|
|
73
71
|
return simplified;
|
|
74
72
|
}
|
|
73
|
+
|
|
75
74
|
function successorWeights(g) {
|
|
76
75
|
let weightMap = g.nodes().map(v => {
|
|
77
76
|
let sucs = {};
|
|
@@ -82,6 +81,7 @@ function successorWeights(g) {
|
|
|
82
81
|
});
|
|
83
82
|
return zipObject(g.nodes(), weightMap);
|
|
84
83
|
}
|
|
84
|
+
|
|
85
85
|
function predecessorWeights(g) {
|
|
86
86
|
let weightMap = g.nodes().map(v => {
|
|
87
87
|
let preds = {};
|
|
@@ -107,9 +107,11 @@ function intersectRect(rect, point) {
|
|
|
107
107
|
let dy = point.y - y;
|
|
108
108
|
let w = rect.width / 2;
|
|
109
109
|
let h = rect.height / 2;
|
|
110
|
+
|
|
110
111
|
if (!dx && !dy) {
|
|
111
112
|
throw new Error("Not possible to find intersection inside of the rectangle");
|
|
112
113
|
}
|
|
114
|
+
|
|
113
115
|
let sx, sy;
|
|
114
116
|
if (Math.abs(dy) * w > Math.abs(dx) * h) {
|
|
115
117
|
// Intersection is top or bottom of rect.
|
|
@@ -126,10 +128,8 @@ function intersectRect(rect, point) {
|
|
|
126
128
|
sx = w;
|
|
127
129
|
sy = w * dy / dx;
|
|
128
130
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
y: y + sy
|
|
132
|
-
};
|
|
131
|
+
|
|
132
|
+
return { x: x + sx, y: y + sy };
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
/*
|
|
@@ -158,6 +158,7 @@ function normalizeRanks(g) {
|
|
|
158
158
|
if (rank === undefined) {
|
|
159
159
|
return Number.MAX_VALUE;
|
|
160
160
|
}
|
|
161
|
+
|
|
161
162
|
return rank;
|
|
162
163
|
}));
|
|
163
164
|
g.nodes().forEach(v => {
|
|
@@ -167,9 +168,11 @@ function normalizeRanks(g) {
|
|
|
167
168
|
}
|
|
168
169
|
});
|
|
169
170
|
}
|
|
171
|
+
|
|
170
172
|
function removeEmptyRanks(g) {
|
|
171
173
|
// Ranks may not start at 0, so we need to offset them
|
|
172
174
|
let offset = Math.min(...g.nodes().map(v => g.node(v).rank));
|
|
175
|
+
|
|
173
176
|
let layers = [];
|
|
174
177
|
g.nodes().forEach(v => {
|
|
175
178
|
let rank = g.node(v).rank - offset;
|
|
@@ -178,6 +181,7 @@ function removeEmptyRanks(g) {
|
|
|
178
181
|
}
|
|
179
182
|
layers[rank].push(v);
|
|
180
183
|
});
|
|
184
|
+
|
|
181
185
|
let delta = 0;
|
|
182
186
|
let nodeRankFactor = g.graph().nodeRankFactor;
|
|
183
187
|
Array.from(layers).forEach((vs, i) => {
|
|
@@ -188,6 +192,7 @@ function removeEmptyRanks(g) {
|
|
|
188
192
|
}
|
|
189
193
|
});
|
|
190
194
|
}
|
|
195
|
+
|
|
191
196
|
function addBorderNode(g, prefix, rank, order) {
|
|
192
197
|
let node = {
|
|
193
198
|
width: 0,
|
|
@@ -199,12 +204,14 @@ function addBorderNode(g, prefix, rank, order) {
|
|
|
199
204
|
}
|
|
200
205
|
return addDummyNode(g, "border", node, prefix);
|
|
201
206
|
}
|
|
207
|
+
|
|
202
208
|
function maxRank(g) {
|
|
203
209
|
return Math.max(...g.nodes().map(v => {
|
|
204
210
|
let rank = g.node(v).rank;
|
|
205
211
|
if (rank === undefined) {
|
|
206
212
|
return Number.MIN_VALUE;
|
|
207
213
|
}
|
|
214
|
+
|
|
208
215
|
return rank;
|
|
209
216
|
}));
|
|
210
217
|
}
|
|
@@ -215,10 +222,7 @@ function maxRank(g) {
|
|
|
215
222
|
* into `rhs.
|
|
216
223
|
*/
|
|
217
224
|
function partition(collection, fn) {
|
|
218
|
-
let result = {
|
|
219
|
-
lhs: [],
|
|
220
|
-
rhs: []
|
|
221
|
-
};
|
|
225
|
+
let result = { lhs: [], rhs: [] };
|
|
222
226
|
collection.forEach(value => {
|
|
223
227
|
if (fn(value)) {
|
|
224
228
|
result.lhs.push(value);
|
|
@@ -241,29 +245,36 @@ function time(name, fn) {
|
|
|
241
245
|
console.log(name + " time: " + (Date.now() - start) + "ms");
|
|
242
246
|
}
|
|
243
247
|
}
|
|
248
|
+
|
|
244
249
|
function notime(name, fn) {
|
|
245
250
|
return fn();
|
|
246
251
|
}
|
|
252
|
+
|
|
247
253
|
let idCounter = 0;
|
|
248
254
|
function uniqueId(prefix) {
|
|
249
255
|
var id = ++idCounter;
|
|
250
256
|
return toString(prefix) + id;
|
|
251
257
|
}
|
|
258
|
+
|
|
252
259
|
function range(start, limit, step = 1) {
|
|
253
260
|
if (limit == null) {
|
|
254
261
|
limit = start;
|
|
255
262
|
start = 0;
|
|
256
263
|
}
|
|
257
|
-
|
|
264
|
+
|
|
265
|
+
let endCon = (i) => i < limit;
|
|
258
266
|
if (step < 0) {
|
|
259
|
-
endCon = i => limit < i;
|
|
267
|
+
endCon = (i) => limit < i;
|
|
260
268
|
}
|
|
269
|
+
|
|
261
270
|
const range = [];
|
|
262
271
|
for (let i = start; endCon(i); i += step) {
|
|
263
272
|
range.push(i);
|
|
264
273
|
}
|
|
274
|
+
|
|
265
275
|
return range;
|
|
266
276
|
}
|
|
277
|
+
|
|
267
278
|
function pick(source, keys) {
|
|
268
279
|
const dest = {};
|
|
269
280
|
for (const key of keys) {
|
|
@@ -271,18 +282,22 @@ function pick(source, keys) {
|
|
|
271
282
|
dest[key] = source[key];
|
|
272
283
|
}
|
|
273
284
|
}
|
|
285
|
+
|
|
274
286
|
return dest;
|
|
275
287
|
}
|
|
288
|
+
|
|
276
289
|
function mapValues(obj, funcOrProp) {
|
|
277
290
|
let func = funcOrProp;
|
|
278
291
|
if (typeof funcOrProp === 'string') {
|
|
279
|
-
func = val => val[funcOrProp];
|
|
292
|
+
func = (val) => val[funcOrProp];
|
|
280
293
|
}
|
|
294
|
+
|
|
281
295
|
return Object.entries(obj).reduce((acc, [k, v]) => {
|
|
282
296
|
acc[k] = func(v, k);
|
|
283
297
|
return acc;
|
|
284
298
|
}, {});
|
|
285
299
|
}
|
|
300
|
+
|
|
286
301
|
function zipObject(props, values) {
|
|
287
302
|
return props.reduce((acc, key, i) => {
|
|
288
303
|
acc[key] = values[i];
|
package/lib/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dagrejs/dagre",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Graph layout for JavaScript",
|
|
5
5
|
"author": "Chris Pettitt <cpettitt@gmail.com>",
|
|
6
6
|
"contributors": [
|
|
@@ -12,17 +12,11 @@
|
|
|
12
12
|
"lint": "make lint",
|
|
13
13
|
"test": "make test"
|
|
14
14
|
},
|
|
15
|
-
"module": "./mjs-lib/index.js",
|
|
16
|
-
"exports": {
|
|
17
|
-
"import": "./mjs-lib/index.js",
|
|
18
|
-
"require": "./index.js"
|
|
19
|
-
},
|
|
20
15
|
"files": [
|
|
21
16
|
"index.js",
|
|
22
17
|
"index.d.ts",
|
|
23
18
|
"dist/",
|
|
24
|
-
"lib/"
|
|
25
|
-
"mjs-lib/"
|
|
19
|
+
"lib/"
|
|
26
20
|
],
|
|
27
21
|
"types": "index.d.ts",
|
|
28
22
|
"keywords": [
|
|
@@ -30,14 +24,9 @@
|
|
|
30
24
|
"layout"
|
|
31
25
|
],
|
|
32
26
|
"dependencies": {
|
|
33
|
-
"@dagrejs/graphlib": "2.2.
|
|
27
|
+
"@dagrejs/graphlib": "2.2.1"
|
|
34
28
|
},
|
|
35
29
|
"devDependencies": {
|
|
36
|
-
"@babel/cli": "^7.23.9",
|
|
37
|
-
"@babel/core": "^7.23.9",
|
|
38
|
-
"@babel/plugin-transform-export-namespace-from": "^7.23.4",
|
|
39
|
-
"@babel/plugin-transform-modules-commonjs": "^7.23.3",
|
|
40
|
-
"babel-plugin-add-module-exports": "^1.0.4",
|
|
41
30
|
"benchmark": "2.1.4",
|
|
42
31
|
"browserify": "17.0.0",
|
|
43
32
|
"chai": "4.3.6",
|
|
@@ -46,7 +35,6 @@
|
|
|
46
35
|
"jshint-stylish": "2.2.1",
|
|
47
36
|
"karma": "6.4.1",
|
|
48
37
|
"karma-chrome-launcher": "3.1.1",
|
|
49
|
-
"karma-firefox-launcher": "2.1.2",
|
|
50
38
|
"karma-mocha": "2.0.1",
|
|
51
39
|
"karma-requirejs": "1.1.0",
|
|
52
40
|
"karma-safari-launcher": "1.0.0",
|
package/lib/index.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
Object.defineProperty(exports, "debug", {
|
|
7
|
-
enumerable: true,
|
|
8
|
-
get: function () {
|
|
9
|
-
return _debug.default;
|
|
10
|
-
}
|
|
11
|
-
});
|
|
12
|
-
exports.graphlib = void 0;
|
|
13
|
-
Object.defineProperty(exports, "layout", {
|
|
14
|
-
enumerable: true,
|
|
15
|
-
get: function () {
|
|
16
|
-
return _layout.default;
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
exports.util = void 0;
|
|
20
|
-
Object.defineProperty(exports, "version", {
|
|
21
|
-
enumerable: true,
|
|
22
|
-
get: function () {
|
|
23
|
-
return _version.default;
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
var _graphlib = _interopRequireWildcard(require("@dagrejs/graphlib"));
|
|
27
|
-
exports.graphlib = _graphlib;
|
|
28
|
-
var _layout = _interopRequireDefault(require("./layout.js"));
|
|
29
|
-
var _debug = _interopRequireDefault(require("./debug.js"));
|
|
30
|
-
var _util = require("./util.js");
|
|
31
|
-
var _version = _interopRequireDefault(require("./version.js"));
|
|
32
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
33
|
-
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); }
|
|
34
|
-
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; }
|
|
35
|
-
const util = exports.util = {
|
|
36
|
-
time: _util.time,
|
|
37
|
-
notime: _util.notime
|
|
38
|
-
};
|
package/mjs-lib/acyclic.js
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { default as greedyFAS } from "./greedy-fas.js";
|
|
4
|
-
import { uniqueId as uniqueId } from "./util.js";
|
|
5
|
-
|
|
6
|
-
export function run(g) {
|
|
7
|
-
let fas = (g.graph().acyclicer === "greedy"
|
|
8
|
-
? greedyFAS(g, weightFn(g))
|
|
9
|
-
: dfsFAS(g));
|
|
10
|
-
fas.forEach(e => {
|
|
11
|
-
let label = g.edge(e);
|
|
12
|
-
g.removeEdge(e);
|
|
13
|
-
label.forwardName = e.name;
|
|
14
|
-
label.reversed = true;
|
|
15
|
-
g.setEdge(e.w, e.v, label, uniqueId("rev"));
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
function weightFn(g) {
|
|
19
|
-
return e => {
|
|
20
|
-
return g.edge(e).weight;
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function dfsFAS(g) {
|
|
26
|
-
let fas = [];
|
|
27
|
-
let stack = {};
|
|
28
|
-
let visited = {};
|
|
29
|
-
|
|
30
|
-
function dfs(v) {
|
|
31
|
-
if (visited.hasOwnProperty(v)) {
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
visited[v] = true;
|
|
35
|
-
stack[v] = true;
|
|
36
|
-
g.outEdges(v).forEach(e => {
|
|
37
|
-
if (stack.hasOwnProperty(e.w)) {
|
|
38
|
-
fas.push(e);
|
|
39
|
-
} else {
|
|
40
|
-
dfs(e.w);
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
delete stack[v];
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
g.nodes().forEach(dfs);
|
|
47
|
-
return fas;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export function undo(g) {
|
|
51
|
-
g.edges().forEach(e => {
|
|
52
|
-
let label = g.edge(e);
|
|
53
|
-
if (label.reversed) {
|
|
54
|
-
g.removeEdge(e);
|
|
55
|
-
|
|
56
|
-
let forwardName = label.forwardName;
|
|
57
|
-
delete label.reversed;
|
|
58
|
-
delete label.forwardName;
|
|
59
|
-
g.setEdge(e.w, e.v, label, forwardName);
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import * as util from "./util.js";
|
|
2
|
-
|
|
3
|
-
export default function addBorderSegments(g) {
|
|
4
|
-
function dfs(v) {
|
|
5
|
-
let children = g.children(v);
|
|
6
|
-
let node = g.node(v);
|
|
7
|
-
if (children.length) {
|
|
8
|
-
children.forEach(dfs);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
if (node.hasOwnProperty("minRank")) {
|
|
12
|
-
node.borderLeft = [];
|
|
13
|
-
node.borderRight = [];
|
|
14
|
-
for (let rank = node.minRank, maxRank = node.maxRank + 1;
|
|
15
|
-
rank < maxRank;
|
|
16
|
-
++rank) {
|
|
17
|
-
addBorderNode(g, "borderLeft", "_bl", v, node, rank);
|
|
18
|
-
addBorderNode(g, "borderRight", "_br", v, node, rank);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
g.children().forEach(dfs);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function addBorderNode(g, prop, prefix, sg, sgNode, rank) {
|
|
27
|
-
let label = { width: 0, height: 0, rank: rank, borderType: prop };
|
|
28
|
-
let prev = sgNode[prop][rank - 1];
|
|
29
|
-
let curr = util.addDummyNode(g, "border", label, prefix);
|
|
30
|
-
sgNode[prop][rank] = curr;
|
|
31
|
-
g.setParent(curr, sg);
|
|
32
|
-
if (prev) {
|
|
33
|
-
g.setEdge(prev, curr, { weight: 1 });
|
|
34
|
-
}
|
|
35
|
-
}
|