@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.
Files changed (61) hide show
  1. package/README.md +0 -7
  2. package/dist/dagre.js +443 -445
  3. package/dist/dagre.min.js +52 -52
  4. package/index.d.ts +18 -3
  5. package/lib/acyclic.js +20 -28
  6. package/lib/add-border-segments.js +23 -15
  7. package/lib/coordinate-system.js +13 -23
  8. package/lib/data/list.js +40 -37
  9. package/lib/debug.js +31 -22
  10. package/lib/greedy-fas.js +60 -55
  11. package/lib/index.js +38 -0
  12. package/lib/layout.js +158 -155
  13. package/lib/nesting-graph.js +35 -40
  14. package/lib/normalize.js +34 -30
  15. package/lib/order/add-subgraph-constraints.js +9 -5
  16. package/lib/order/barycenter.js +17 -9
  17. package/lib/order/build-layer-graph.js +24 -18
  18. package/lib/order/cross-count.js +22 -19
  19. package/lib/order/index.js +37 -28
  20. package/lib/order/init-order.js +14 -13
  21. package/lib/order/resolve-conflicts.js +20 -30
  22. package/lib/order/sort-subgraph.js +25 -31
  23. package/lib/order/sort.js +18 -17
  24. package/lib/parent-dummy-chains.js +36 -38
  25. package/lib/position/bk.js +103 -145
  26. package/lib/position/index.js +14 -13
  27. package/lib/rank/feasible-tree.js +15 -18
  28. package/lib/rank/index.js +25 -15
  29. package/lib/rank/network-simplex.js +22 -43
  30. package/lib/rank/util.js +6 -12
  31. package/lib/util.js +69 -84
  32. package/lib/version.js +8 -1
  33. package/mjs-lib/acyclic.js +62 -0
  34. package/mjs-lib/add-border-segments.js +35 -0
  35. package/mjs-lib/coordinate-system.js +65 -0
  36. package/mjs-lib/data/list.js +56 -0
  37. package/mjs-lib/debug.js +30 -0
  38. package/mjs-lib/greedy-fas.js +125 -0
  39. package/mjs-lib/index.js +9 -0
  40. package/mjs-lib/layout.js +405 -0
  41. package/mjs-lib/nesting-graph.js +120 -0
  42. package/mjs-lib/normalize.js +84 -0
  43. package/mjs-lib/order/add-subgraph-constraints.js +49 -0
  44. package/mjs-lib/order/barycenter.js +24 -0
  45. package/mjs-lib/order/build-layer-graph.js +71 -0
  46. package/mjs-lib/order/cross-count.js +64 -0
  47. package/mjs-lib/order/index.js +70 -0
  48. package/mjs-lib/order/init-order.js +34 -0
  49. package/mjs-lib/order/resolve-conflicts.js +116 -0
  50. package/mjs-lib/order/sort-subgraph.js +71 -0
  51. package/mjs-lib/order/sort.js +54 -0
  52. package/mjs-lib/parent-dummy-chains.js +82 -0
  53. package/mjs-lib/position/bk.js +409 -0
  54. package/mjs-lib/position/index.js +30 -0
  55. package/mjs-lib/rank/feasible-tree.js +93 -0
  56. package/mjs-lib/rank/index.js +46 -0
  57. package/mjs-lib/rank/network-simplex.js +233 -0
  58. package/mjs-lib/rank/util.js +58 -0
  59. package/mjs-lib/util.js +305 -0
  60. package/mjs-lib/version.js +1 -0
  61. package/package.json +14 -3
@@ -1,14 +1,16 @@
1
1
  "use strict";
2
2
 
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
-
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = networkSimplex;
7
+ var _feasibleTree = _interopRequireDefault(require("./feasible-tree.js"));
8
+ var _util = require("./util.js");
9
+ var _graphlib = require("@dagrejs/graphlib");
10
+ var _util2 = require("../util.js");
11
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
+ var preorder = _graphlib.alg.preorder;
13
+ var postorder = _graphlib.alg.postorder;
12
14
  // Expose some internals for testing purposes
13
15
  networkSimplex.initLowLimValues = initLowLimValues;
14
16
  networkSimplex.initCutValues = initCutValues;
@@ -51,14 +53,13 @@ networkSimplex.exchangeEdges = exchangeEdges;
51
53
  * structure of the overall algorithm.
52
54
  */
53
55
  function networkSimplex(g) {
54
- g = simplify(g);
55
- initRank(g);
56
- var t = feasibleTree(g);
56
+ g = (0, _util2.simplify)(g);
57
+ (0, _util.longestPath)(g);
58
+ var t = (0, _feasibleTree.default)(g);
57
59
  initLowLimValues(t);
58
60
  initCutValues(t, g);
59
-
60
61
  var e, f;
61
- while ((e = leaveEdge(t))) {
62
+ while (e = leaveEdge(t)) {
62
63
  f = enterEdge(t, g, e);
63
64
  exchangeEdges(t, g, e, f);
64
65
  }
@@ -72,7 +73,6 @@ function initCutValues(t, g) {
72
73
  vs = vs.slice(0, vs.length - 1);
73
74
  vs.forEach(v => assignCutValue(t, g, v));
74
75
  }
75
-
76
76
  function assignCutValue(t, g, child) {
77
77
  var childLab = t.node(child);
78
78
  var parent = childLab.parent;
@@ -92,22 +92,17 @@ 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
-
96
95
  if (!graphEdge) {
97
96
  childIsTail = false;
98
97
  graphEdge = g.edge(parent, child);
99
98
  }
100
-
101
99
  cutValue = graphEdge.weight;
102
-
103
- g.nodeEdges(child).forEach(function(e) {
100
+ g.nodeEdges(child).forEach(e => {
104
101
  var isOutEdge = e.v === child,
105
102
  other = isOutEdge ? e.w : e.v;
106
-
107
103
  if (other !== parent) {
108
104
  var pointsToHead = isOutEdge === childIsTail,
109
105
  otherWeight = g.edge(e).weight;
110
-
111
106
  cutValue += pointsToHead ? otherWeight : -otherWeight;
112
107
  if (isTreeEdge(t, child, other)) {
113
108
  var otherCutValue = t.edge(child, other).cutvalue;
@@ -115,28 +110,23 @@ function calcCutValue(t, g, child) {
115
110
  }
116
111
  }
117
112
  });
118
-
119
113
  return cutValue;
120
114
  }
121
-
122
115
  function initLowLimValues(tree, root) {
123
116
  if (arguments.length < 2) {
124
117
  root = tree.nodes()[0];
125
118
  }
126
119
  dfsAssignLowLim(tree, {}, 1, root);
127
120
  }
128
-
129
121
  function dfsAssignLowLim(tree, visited, nextLim, v, parent) {
130
122
  var low = nextLim;
131
123
  var label = tree.node(v);
132
-
133
124
  visited[v] = true;
134
- tree.neighbors(v).forEach(function(w) {
125
+ tree.neighbors(v).forEach(w => {
135
126
  if (!visited.hasOwnProperty(w)) {
136
127
  nextLim = dfsAssignLowLim(tree, visited, nextLim, w, v);
137
128
  }
138
129
  });
139
-
140
130
  label.low = low;
141
131
  label.lim = nextLim++;
142
132
  if (parent) {
@@ -145,14 +135,11 @@ function dfsAssignLowLim(tree, visited, nextLim, v, parent) {
145
135
  // TODO should be able to remove this when we incrementally update low lim
146
136
  delete label.parent;
147
137
  }
148
-
149
138
  return nextLim;
150
139
  }
151
-
152
140
  function leaveEdge(tree) {
153
141
  return tree.edges().find(e => tree.edge(e).cutvalue < 0);
154
142
  }
155
-
156
143
  function enterEdge(t, g, edge) {
157
144
  var v = edge.v;
158
145
  var w = edge.w;
@@ -164,7 +151,6 @@ function enterEdge(t, g, edge) {
164
151
  v = edge.w;
165
152
  w = edge.v;
166
153
  }
167
-
168
154
  var vLabel = t.node(v);
169
155
  var wLabel = t.node(w);
170
156
  var tailLabel = vLabel;
@@ -176,21 +162,16 @@ function enterEdge(t, g, edge) {
176
162
  tailLabel = wLabel;
177
163
  flip = true;
178
164
  }
179
-
180
- var candidates = g.edges().filter(function(edge) {
181
- return flip === isDescendant(t, t.node(edge.v), tailLabel) &&
182
- flip !== isDescendant(t, t.node(edge.w), tailLabel);
165
+ var candidates = g.edges().filter(edge => {
166
+ return flip === isDescendant(t, t.node(edge.v), tailLabel) && flip !== isDescendant(t, t.node(edge.w), tailLabel);
183
167
  });
184
-
185
168
  return candidates.reduce((acc, edge) => {
186
- if (slack(g, edge) < slack(g, acc)) {
169
+ if ((0, _util.slack)(g, edge) < (0, _util.slack)(g, acc)) {
187
170
  return edge;
188
171
  }
189
-
190
172
  return acc;
191
173
  });
192
174
  }
193
-
194
175
  function exchangeEdges(t, g, e, f) {
195
176
  var v = e.v;
196
177
  var w = e.w;
@@ -200,21 +181,18 @@ function exchangeEdges(t, g, e, f) {
200
181
  initCutValues(t, g);
201
182
  updateRanks(t, g);
202
183
  }
203
-
204
184
  function updateRanks(t, g) {
205
185
  var root = t.nodes().find(v => !g.node(v).parent);
206
186
  var vs = preorder(t, root);
207
187
  vs = vs.slice(1);
208
- vs.forEach(function(v) {
188
+ vs.forEach(v => {
209
189
  var parent = t.node(v).parent,
210
190
  edge = g.edge(v, parent),
211
191
  flipped = false;
212
-
213
192
  if (!edge) {
214
193
  edge = g.edge(parent, v);
215
194
  flipped = true;
216
195
  }
217
-
218
196
  g.node(v).rank = g.node(parent).rank + (flipped ? edge.minlen : -edge.minlen);
219
197
  });
220
198
  }
@@ -233,3 +211,4 @@ function isTreeEdge(tree, u, v) {
233
211
  function isDescendant(tree, vLabel, rootLabel) {
234
212
  return rootLabel.low <= vLabel.lim && vLabel.lim <= rootLabel.lim;
235
213
  }
214
+ module.exports = exports.default;
package/lib/rank/util.js CHANGED
@@ -1,10 +1,5 @@
1
1
  "use strict";
2
2
 
3
- module.exports = {
4
- longestPath: longestPath,
5
- slack: slack
6
- };
7
-
8
3
  /*
9
4
  * Initializes ranks for the input graph using the longest path algorithm. This
10
5
  * algorithm scales well and is fast in practice, it yields rather poor
@@ -26,31 +21,30 @@ module.exports = {
26
21
  *
27
22
  * 1. Each node will be assign an (unnormalized) "rank" property.
28
23
  */
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
-
32
31
  function dfs(v) {
33
32
  var label = g.node(v);
34
33
  if (visited.hasOwnProperty(v)) {
35
34
  return label.rank;
36
35
  }
37
36
  visited[v] = true;
38
-
39
37
  var rank = Math.min(...g.outEdges(v).map(e => {
40
38
  if (e == null) {
41
39
  return Number.POSITIVE_INFINITY;
42
40
  }
43
-
44
41
  return dfs(e.w) - g.edge(e).minlen;
45
42
  }));
46
-
47
43
  if (rank === Number.POSITIVE_INFINITY) {
48
44
  rank = 0;
49
45
  }
50
-
51
- return (label.rank = rank);
46
+ return label.rank = rank;
52
47
  }
53
-
54
48
  g.sources().forEach(dfs);
55
49
  }
56
50
 
package/lib/util.js CHANGED
@@ -2,39 +2,37 @@
2
2
 
3
3
  "use strict";
4
4
 
5
- var 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
-
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.addBorderNode = addBorderNode;
9
+ exports.addDummyNode = addDummyNode;
10
+ exports.asNonCompoundGraph = asNonCompoundGraph;
11
+ exports.buildLayerMatrix = buildLayerMatrix;
12
+ exports.intersectRect = intersectRect;
13
+ exports.mapValues = mapValues;
14
+ exports.maxRank = maxRank;
15
+ exports.normalizeRanks = normalizeRanks;
16
+ exports.notime = notime;
17
+ exports.partition = partition;
18
+ exports.pick = pick;
19
+ exports.predecessorWeights = predecessorWeights;
20
+ exports.range = range;
21
+ exports.removeEmptyRanks = removeEmptyRanks;
22
+ exports.simplify = simplify;
23
+ exports.successorWeights = successorWeights;
24
+ exports.time = time;
25
+ exports.uniqueId = uniqueId;
26
+ exports.zipObject = zipObject;
27
+ var _graphlib = require("@dagrejs/graphlib");
29
28
  /*
30
29
  * Adds a dummy node to the graph and return v.
31
30
  */
32
31
  function addDummyNode(g, type, attrs, name) {
33
- var v;
32
+ let v;
34
33
  do {
35
34
  v = uniqueId(name);
36
35
  } while (g.hasNode(v));
37
-
38
36
  attrs.dummy = type;
39
37
  g.setNode(v, attrs);
40
38
  return v;
@@ -45,11 +43,14 @@ function addDummyNode(g, type, attrs, name) {
45
43
  * associated with multi-edges.
46
44
  */
47
45
  function simplify(g) {
48
- var simplified = new Graph().setGraph(g.graph());
46
+ let simplified = new _graphlib.Graph().setGraph(g.graph());
49
47
  g.nodes().forEach(v => simplified.setNode(v, g.node(v)));
50
48
  g.edges().forEach(e => {
51
- var simpleLabel = simplified.edge(e.v, e.w) || { weight: 0, minlen: 1 };
52
- var label = g.edge(e);
49
+ let simpleLabel = simplified.edge(e.v, e.w) || {
50
+ weight: 0,
51
+ minlen: 1
52
+ };
53
+ let label = g.edge(e);
53
54
  simplified.setEdge(e.v, e.w, {
54
55
  weight: simpleLabel.weight + label.weight,
55
56
  minlen: Math.max(simpleLabel.minlen, label.minlen)
@@ -57,9 +58,10 @@ function simplify(g) {
57
58
  });
58
59
  return simplified;
59
60
  }
60
-
61
61
  function asNonCompoundGraph(g) {
62
- var simplified = new Graph({ multigraph: g.isMultigraph() }).setGraph(g.graph());
62
+ let simplified = new _graphlib.Graph({
63
+ multigraph: g.isMultigraph()
64
+ }).setGraph(g.graph());
63
65
  g.nodes().forEach(v => {
64
66
  if (!g.children(v).length) {
65
67
  simplified.setNode(v, g.node(v));
@@ -70,10 +72,9 @@ function asNonCompoundGraph(g) {
70
72
  });
71
73
  return simplified;
72
74
  }
73
-
74
75
  function successorWeights(g) {
75
- var weightMap = g.nodes().map(v => {
76
- var sucs = {};
76
+ let weightMap = g.nodes().map(v => {
77
+ let sucs = {};
77
78
  g.outEdges(v).forEach(e => {
78
79
  sucs[e.w] = (sucs[e.w] || 0) + g.edge(e).weight;
79
80
  });
@@ -81,10 +82,9 @@ function successorWeights(g) {
81
82
  });
82
83
  return zipObject(g.nodes(), weightMap);
83
84
  }
84
-
85
85
  function predecessorWeights(g) {
86
- var weightMap = g.nodes().map(v => {
87
- var preds = {};
86
+ let weightMap = g.nodes().map(v => {
87
+ let preds = {};
88
88
  g.inEdges(v).forEach(e => {
89
89
  preds[e.v] = (preds[e.v] || 0) + g.edge(e).weight;
90
90
  });
@@ -98,21 +98,19 @@ function predecessorWeights(g) {
98
98
  * ({x, y, width, height}) if it were pointing at the rectangle's center.
99
99
  */
100
100
  function intersectRect(rect, point) {
101
- var x = rect.x;
102
- var y = rect.y;
101
+ let x = rect.x;
102
+ let y = rect.y;
103
103
 
104
104
  // Rectangle intersection algorithm from:
105
105
  // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes
106
- var dx = point.x - x;
107
- var dy = point.y - y;
108
- var w = rect.width / 2;
109
- var h = rect.height / 2;
110
-
106
+ let dx = point.x - x;
107
+ let dy = point.y - y;
108
+ let w = rect.width / 2;
109
+ let h = rect.height / 2;
111
110
  if (!dx && !dy) {
112
111
  throw new Error("Not possible to find intersection inside of the rectangle");
113
112
  }
114
-
115
- var sx, sy;
113
+ let sx, sy;
116
114
  if (Math.abs(dy) * w > Math.abs(dx) * h) {
117
115
  // Intersection is top or bottom of rect.
118
116
  if (dy < 0) {
@@ -128,8 +126,10 @@ function intersectRect(rect, point) {
128
126
  sx = w;
129
127
  sy = w * dy / dx;
130
128
  }
131
-
132
- return { x: x + sx, y: y + sy };
129
+ return {
130
+ x: x + sx,
131
+ y: y + sy
132
+ };
133
133
  }
134
134
 
135
135
  /*
@@ -137,10 +137,10 @@ function intersectRect(rect, point) {
137
137
  * function will produce a matrix with the ids of each node.
138
138
  */
139
139
  function buildLayerMatrix(g) {
140
- var layering = range(maxRank(g) + 1).map(() => []);
140
+ let layering = range(maxRank(g) + 1).map(() => []);
141
141
  g.nodes().forEach(v => {
142
- var node = g.node(v);
143
- var rank = node.rank;
142
+ let node = g.node(v);
143
+ let rank = node.rank;
144
144
  if (rank !== undefined) {
145
145
  layering[rank][node.order] = v;
146
146
  }
@@ -153,37 +153,33 @@ function buildLayerMatrix(g) {
153
153
  * rank(v) >= 0 and at least one node w has rank(w) = 0.
154
154
  */
155
155
  function normalizeRanks(g) {
156
- var min = Math.min(...g.nodes().map(v => {
157
- var rank = g.node(v).rank;
156
+ let min = Math.min(...g.nodes().map(v => {
157
+ let rank = g.node(v).rank;
158
158
  if (rank === undefined) {
159
159
  return Number.MAX_VALUE;
160
160
  }
161
-
162
161
  return rank;
163
162
  }));
164
163
  g.nodes().forEach(v => {
165
- var node = g.node(v);
164
+ let node = g.node(v);
166
165
  if (node.hasOwnProperty("rank")) {
167
166
  node.rank -= min;
168
167
  }
169
168
  });
170
169
  }
171
-
172
170
  function removeEmptyRanks(g) {
173
171
  // Ranks may not start at 0, so we need to offset them
174
- var offset = Math.min(...g.nodes().map(v => g.node(v).rank));
175
-
176
- var layers = [];
172
+ let offset = Math.min(...g.nodes().map(v => g.node(v).rank));
173
+ let layers = [];
177
174
  g.nodes().forEach(v => {
178
- var rank = g.node(v).rank - offset;
175
+ let rank = g.node(v).rank - offset;
179
176
  if (!layers[rank]) {
180
177
  layers[rank] = [];
181
178
  }
182
179
  layers[rank].push(v);
183
180
  });
184
-
185
- var delta = 0;
186
- var nodeRankFactor = g.graph().nodeRankFactor;
181
+ let delta = 0;
182
+ let nodeRankFactor = g.graph().nodeRankFactor;
187
183
  Array.from(layers).forEach((vs, i) => {
188
184
  if (vs === undefined && i % nodeRankFactor !== 0) {
189
185
  --delta;
@@ -192,9 +188,8 @@ function removeEmptyRanks(g) {
192
188
  }
193
189
  });
194
190
  }
195
-
196
191
  function addBorderNode(g, prefix, rank, order) {
197
- var node = {
192
+ let node = {
198
193
  width: 0,
199
194
  height: 0
200
195
  };
@@ -204,14 +199,12 @@ function addBorderNode(g, prefix, rank, order) {
204
199
  }
205
200
  return addDummyNode(g, "border", node, prefix);
206
201
  }
207
-
208
202
  function maxRank(g) {
209
203
  return Math.max(...g.nodes().map(v => {
210
- var rank = g.node(v).rank;
204
+ let rank = g.node(v).rank;
211
205
  if (rank === undefined) {
212
206
  return Number.MIN_VALUE;
213
207
  }
214
-
215
208
  return rank;
216
209
  }));
217
210
  }
@@ -222,7 +215,10 @@ function maxRank(g) {
222
215
  * into `rhs.
223
216
  */
224
217
  function partition(collection, fn) {
225
- var result = { lhs: [], rhs: [] };
218
+ let result = {
219
+ lhs: [],
220
+ rhs: []
221
+ };
226
222
  collection.forEach(value => {
227
223
  if (fn(value)) {
228
224
  result.lhs.push(value);
@@ -238,43 +234,36 @@ function partition(collection, fn) {
238
234
  * time it takes to execute the function.
239
235
  */
240
236
  function time(name, fn) {
241
- var start = Date.now();
237
+ let start = Date.now();
242
238
  try {
243
239
  return fn();
244
240
  } finally {
245
241
  console.log(name + " time: " + (Date.now() - start) + "ms");
246
242
  }
247
243
  }
248
-
249
244
  function notime(name, fn) {
250
245
  return fn();
251
246
  }
252
-
253
247
  let idCounter = 0;
254
248
  function uniqueId(prefix) {
255
249
  var id = ++idCounter;
256
250
  return toString(prefix) + id;
257
251
  }
258
-
259
252
  function range(start, limit, step = 1) {
260
253
  if (limit == null) {
261
254
  limit = start;
262
255
  start = 0;
263
256
  }
264
-
265
- let endCon = (i) => i < limit;
257
+ let endCon = i => i < limit;
266
258
  if (step < 0) {
267
- endCon = (i) => limit < i;
259
+ endCon = i => limit < i;
268
260
  }
269
-
270
261
  const range = [];
271
262
  for (let i = start; endCon(i); i += step) {
272
263
  range.push(i);
273
264
  }
274
-
275
265
  return range;
276
266
  }
277
-
278
267
  function pick(source, keys) {
279
268
  const dest = {};
280
269
  for (const key of keys) {
@@ -282,22 +271,18 @@ function pick(source, keys) {
282
271
  dest[key] = source[key];
283
272
  }
284
273
  }
285
-
286
274
  return dest;
287
275
  }
288
-
289
276
  function mapValues(obj, funcOrProp) {
290
277
  let func = funcOrProp;
291
278
  if (typeof funcOrProp === 'string') {
292
- func = (val) => val[funcOrProp];
279
+ func = val => val[funcOrProp];
293
280
  }
294
-
295
281
  return Object.entries(obj).reduce((acc, [k, v]) => {
296
282
  acc[k] = func(v, k);
297
283
  return acc;
298
284
  }, {});
299
285
  }
300
-
301
286
  function zipObject(props, values) {
302
287
  return props.reduce((acc, key, i) => {
303
288
  acc[key] = values[i];
package/lib/version.js CHANGED
@@ -1 +1,8 @@
1
- module.exports = "1.0.2";
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _default = exports.default = "1.1.0";
8
+ module.exports = exports.default;
@@ -0,0 +1,62 @@
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
+ }
@@ -0,0 +1,35 @@
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
+ }