@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.
Files changed (59) hide show
  1. package/dist/dagre.js +16 -5
  2. package/dist/dagre.min.js +4 -4
  3. package/lib/acyclic.js +18 -10
  4. package/lib/add-border-segments.js +11 -19
  5. package/lib/coordinate-system.js +15 -5
  6. package/lib/data/list.js +7 -8
  7. package/lib/debug.js +14 -25
  8. package/lib/greedy-fas.js +30 -35
  9. package/lib/layout.js +102 -105
  10. package/lib/nesting-graph.js +21 -18
  11. package/lib/normalize.js +18 -22
  12. package/lib/order/add-subgraph-constraints.js +2 -6
  13. package/lib/order/barycenter.js +6 -14
  14. package/lib/order/build-layer-graph.js +13 -19
  15. package/lib/order/cross-count.js +10 -13
  16. package/lib/order/index.js +23 -23
  17. package/lib/order/init-order.js +7 -8
  18. package/lib/order/resolve-conflicts.js +19 -9
  19. package/lib/order/sort-subgraph.js +22 -16
  20. package/lib/order/sort.js +12 -13
  21. package/lib/parent-dummy-chains.js +19 -17
  22. package/lib/position/bk.js +84 -40
  23. package/lib/position/index.js +9 -10
  24. package/lib/rank/feasible-tree.js +17 -14
  25. package/lib/rank/index.js +15 -25
  26. package/lib/rank/network-simplex.js +39 -18
  27. package/lib/rank/util.js +12 -6
  28. package/lib/util.js +57 -42
  29. package/lib/version.js +1 -8
  30. package/package.json +3 -15
  31. package/lib/index.js +0 -38
  32. package/mjs-lib/acyclic.js +0 -62
  33. package/mjs-lib/add-border-segments.js +0 -35
  34. package/mjs-lib/coordinate-system.js +0 -65
  35. package/mjs-lib/data/list.js +0 -56
  36. package/mjs-lib/debug.js +0 -30
  37. package/mjs-lib/greedy-fas.js +0 -125
  38. package/mjs-lib/index.js +0 -9
  39. package/mjs-lib/layout.js +0 -405
  40. package/mjs-lib/nesting-graph.js +0 -120
  41. package/mjs-lib/normalize.js +0 -84
  42. package/mjs-lib/order/add-subgraph-constraints.js +0 -49
  43. package/mjs-lib/order/barycenter.js +0 -24
  44. package/mjs-lib/order/build-layer-graph.js +0 -71
  45. package/mjs-lib/order/cross-count.js +0 -64
  46. package/mjs-lib/order/index.js +0 -70
  47. package/mjs-lib/order/init-order.js +0 -34
  48. package/mjs-lib/order/resolve-conflicts.js +0 -116
  49. package/mjs-lib/order/sort-subgraph.js +0 -71
  50. package/mjs-lib/order/sort.js +0 -54
  51. package/mjs-lib/parent-dummy-chains.js +0 -82
  52. package/mjs-lib/position/bk.js +0 -409
  53. package/mjs-lib/position/index.js +0 -30
  54. package/mjs-lib/rank/feasible-tree.js +0 -93
  55. package/mjs-lib/rank/index.js +0 -46
  56. package/mjs-lib/rank/network-simplex.js +0 -233
  57. package/mjs-lib/rank/util.js +0 -58
  58. package/mjs-lib/util.js +0 -305
  59. package/mjs-lib/version.js +0 -1
package/dist/dagre.js CHANGED
@@ -1309,7 +1309,12 @@ module.exports = order;
1309
1309
  * 1. Graph nodes will have an "order" attribute based on the results of the
1310
1310
  * algorithm.
1311
1311
  */
1312
- function order(g) {
1312
+ function order(g, opts) {
1313
+ if (opts && typeof opts.customOrder === 'function') {
1314
+ opts.customOrder(g, order);
1315
+ return;
1316
+ }
1317
+
1313
1318
  let maxRank = util.maxRank(g),
1314
1319
  downLayerGraphs = buildLayerGraphs(g, util.range(1, maxRank + 1), "inEdges"),
1315
1320
  upLayerGraphs = buildLayerGraphs(g, util.range(maxRank - 1, -1, -1), "outEdges");
@@ -1317,6 +1322,10 @@ function order(g) {
1317
1322
  let layering = initOrder(g);
1318
1323
  assignOrder(g, layering);
1319
1324
 
1325
+ if (opts && opts.disableOptimalOrderHeuristic) {
1326
+ return;
1327
+ }
1328
+
1320
1329
  let bestCC = Number.POSITIVE_INFINITY,
1321
1330
  best;
1322
1331
 
@@ -1810,7 +1819,8 @@ function findType1Conflicts(g, layering) {
1810
1819
  return layer;
1811
1820
  }
1812
1821
 
1813
- layering.reduce(visitLayer);
1822
+ layering.length && layering.reduce(visitLayer);
1823
+
1814
1824
  return conflicts;
1815
1825
  }
1816
1826
 
@@ -1855,7 +1865,8 @@ function findType2Conflicts(g, layering) {
1855
1865
  return south;
1856
1866
  }
1857
1867
 
1858
- layering.reduce(visitLayer);
1868
+ layering.length && layering.reduce(visitLayer);
1869
+
1859
1870
  return conflicts;
1860
1871
  }
1861
1872
 
@@ -2948,7 +2959,7 @@ function zipObject(props, values) {
2948
2959
  }
2949
2960
 
2950
2961
  },{"@dagrejs/graphlib":29}],28:[function(require,module,exports){
2951
- module.exports = "1.0.4";
2962
+ module.exports = "1.1.1";
2952
2963
 
2953
2964
  },{}],29:[function(require,module,exports){
2954
2965
  /**
@@ -4342,7 +4353,7 @@ function read(json) {
4342
4353
  }
4343
4354
 
4344
4355
  },{"./graph":44}],47:[function(require,module,exports){
4345
- module.exports = '2.1.13';
4356
+ module.exports = '2.2.1';
4346
4357
 
4347
4358
  },{}]},{},[1])(1)
4348
4359
  });
package/dist/dagre.min.js CHANGED
@@ -207,7 +207,7 @@ let cc=0;southEntries.forEach(entry=>{let index=entry.pos+firstIndex;tree[index]
207
207
  *
208
208
  * 1. Graph nodes will have an "order" attribute based on the results of the
209
209
  * algorithm.
210
- */function order(g){let maxRank=util.maxRank(g),downLayerGraphs=buildLayerGraphs(g,util.range(1,maxRank+1),"inEdges"),upLayerGraphs=buildLayerGraphs(g,util.range(maxRank-1,-1,-1),"outEdges");let layering=initOrder(g);assignOrder(g,layering);let bestCC=Number.POSITIVE_INFINITY,best;for(let i=0,lastBest=0;lastBest<4;++i,++lastBest){sweepLayerGraphs(i%2?downLayerGraphs:upLayerGraphs,i%4>=2);layering=util.buildLayerMatrix(g);let cc=crossCount(g,layering);if(cc<bestCC){lastBest=0;best=Object.assign({},layering);bestCC=cc}}assignOrder(g,best)}function buildLayerGraphs(g,ranks,relationship){return ranks.map(function(rank){return buildLayerGraph(g,rank,relationship)})}function sweepLayerGraphs(layerGraphs,biasRight){let cg=new Graph;layerGraphs.forEach(function(lg){let root=lg.graph().root;let sorted=sortSubgraph(lg,root,cg,biasRight);sorted.vs.forEach((v,i)=>lg.node(v).order=i);addSubgraphConstraints(lg,cg,sorted.vs)})}function assignOrder(g,layering){Object.values(layering).forEach(layer=>layer.forEach((v,i)=>g.node(v).order=i))}},{"../util":27,"./add-subgraph-constraints":11,"./build-layer-graph":13,"./cross-count":14,"./init-order":16,"./sort-subgraph":18,"@dagrejs/graphlib":29}],16:[function(require,module,exports){"use strict";let util=require("../util");module.exports=initOrder;
210
+ */function order(g,opts){if(opts&&typeof opts.customOrder==="function"){opts.customOrder(g,order);return}let maxRank=util.maxRank(g),downLayerGraphs=buildLayerGraphs(g,util.range(1,maxRank+1),"inEdges"),upLayerGraphs=buildLayerGraphs(g,util.range(maxRank-1,-1,-1),"outEdges");let layering=initOrder(g);assignOrder(g,layering);if(opts&&opts.disableOptimalOrderHeuristic){return}let bestCC=Number.POSITIVE_INFINITY,best;for(let i=0,lastBest=0;lastBest<4;++i,++lastBest){sweepLayerGraphs(i%2?downLayerGraphs:upLayerGraphs,i%4>=2);layering=util.buildLayerMatrix(g);let cc=crossCount(g,layering);if(cc<bestCC){lastBest=0;best=Object.assign({},layering);bestCC=cc}}assignOrder(g,best)}function buildLayerGraphs(g,ranks,relationship){return ranks.map(function(rank){return buildLayerGraph(g,rank,relationship)})}function sweepLayerGraphs(layerGraphs,biasRight){let cg=new Graph;layerGraphs.forEach(function(lg){let root=lg.graph().root;let sorted=sortSubgraph(lg,root,cg,biasRight);sorted.vs.forEach((v,i)=>lg.node(v).order=i);addSubgraphConstraints(lg,cg,sorted.vs)})}function assignOrder(g,layering){Object.values(layering).forEach(layer=>layer.forEach((v,i)=>g.node(v).order=i))}},{"../util":27,"./add-subgraph-constraints":11,"./build-layer-graph":13,"./cross-count":14,"./init-order":16,"./sort-subgraph":18,"@dagrejs/graphlib":29}],16:[function(require,module,exports){"use strict";let util=require("../util");module.exports=initOrder;
211
211
  /*
212
212
  * Assigns an initial order value for each node by performing a DFS search
213
213
  * starting from nodes in the first rank. Nodes are assigned an order in their
@@ -277,7 +277,7 @@ parent=w;while((parent=g.parent(parent))!==lca){wPath.push(parent)}return{path:v
277
277
  k0=0,
278
278
  // Tracks the last node in this layer scanned for crossings with a type-1
279
279
  // segment.
280
- scanPos=0,prevLayerLength=prevLayer.length,lastNode=layer[layer.length-1];layer.forEach((v,i)=>{let w=findOtherInnerSegmentNode(g,v),k1=w?g.node(w).order:prevLayerLength;if(w||v===lastNode){layer.slice(scanPos,i+1).forEach(scanNode=>{g.predecessors(scanNode).forEach(u=>{let uLabel=g.node(u),uPos=uLabel.order;if((uPos<k0||k1<uPos)&&!(uLabel.dummy&&g.node(scanNode).dummy)){addConflict(conflicts,u,scanNode)}})});scanPos=i+1;k0=k1}});return layer}layering.reduce(visitLayer);return conflicts}function findType2Conflicts(g,layering){let conflicts={};function scan(south,southPos,southEnd,prevNorthBorder,nextNorthBorder){let v;util.range(southPos,southEnd).forEach(i=>{v=south[i];if(g.node(v).dummy){g.predecessors(v).forEach(u=>{let uNode=g.node(u);if(uNode.dummy&&(uNode.order<prevNorthBorder||uNode.order>nextNorthBorder)){addConflict(conflicts,u,v)}})}})}function visitLayer(north,south){let prevNorthPos=-1,nextNorthPos,southPos=0;south.forEach((v,southLookahead)=>{if(g.node(v).dummy==="border"){let predecessors=g.predecessors(v);if(predecessors.length){nextNorthPos=g.node(predecessors[0]).order;scan(south,southPos,southLookahead,prevNorthPos,nextNorthPos);southPos=southLookahead;prevNorthPos=nextNorthPos}}scan(south,southPos,south.length,nextNorthPos,north.length)});return south}layering.reduce(visitLayer);return conflicts}function findOtherInnerSegmentNode(g,v){if(g.node(v).dummy){return g.predecessors(v).find(u=>g.node(u).dummy)}}function addConflict(conflicts,v,w){if(v>w){let tmp=v;v=w;w=tmp}let conflictsV=conflicts[v];if(!conflictsV){conflicts[v]=conflictsV={}}conflictsV[w]=true}function hasConflict(conflicts,v,w){if(v>w){let tmp=v;v=w;w=tmp}return!!conflicts[v]&&conflicts[v].hasOwnProperty(w)}
280
+ scanPos=0,prevLayerLength=prevLayer.length,lastNode=layer[layer.length-1];layer.forEach((v,i)=>{let w=findOtherInnerSegmentNode(g,v),k1=w?g.node(w).order:prevLayerLength;if(w||v===lastNode){layer.slice(scanPos,i+1).forEach(scanNode=>{g.predecessors(scanNode).forEach(u=>{let uLabel=g.node(u),uPos=uLabel.order;if((uPos<k0||k1<uPos)&&!(uLabel.dummy&&g.node(scanNode).dummy)){addConflict(conflicts,u,scanNode)}})});scanPos=i+1;k0=k1}});return layer}layering.length&&layering.reduce(visitLayer);return conflicts}function findType2Conflicts(g,layering){let conflicts={};function scan(south,southPos,southEnd,prevNorthBorder,nextNorthBorder){let v;util.range(southPos,southEnd).forEach(i=>{v=south[i];if(g.node(v).dummy){g.predecessors(v).forEach(u=>{let uNode=g.node(u);if(uNode.dummy&&(uNode.order<prevNorthBorder||uNode.order>nextNorthBorder)){addConflict(conflicts,u,v)}})}})}function visitLayer(north,south){let prevNorthPos=-1,nextNorthPos,southPos=0;south.forEach((v,southLookahead)=>{if(g.node(v).dummy==="border"){let predecessors=g.predecessors(v);if(predecessors.length){nextNorthPos=g.node(predecessors[0]).order;scan(south,southPos,southLookahead,prevNorthPos,nextNorthPos);southPos=southLookahead;prevNorthPos=nextNorthPos}}scan(south,southPos,south.length,nextNorthPos,north.length)});return south}layering.length&&layering.reduce(visitLayer);return conflicts}function findOtherInnerSegmentNode(g,v){if(g.node(v).dummy){return g.predecessors(v).find(u=>g.node(u).dummy)}}function addConflict(conflicts,v,w){if(v>w){let tmp=v;v=w;w=tmp}let conflictsV=conflicts[v];if(!conflictsV){conflicts[v]=conflictsV={}}conflictsV[w]=true}function hasConflict(conflicts,v,w){if(v>w){let tmp=v;v=w;w=tmp}return!!conflicts[v]&&conflicts[v].hasOwnProperty(w)}
281
281
  /*
282
282
  * Try to align nodes into vertical "blocks" where possible. This algorithm
283
283
  * attempts to align a node with one of its median neighbors. If the edge
@@ -495,7 +495,7 @@ let offset=Math.min(...g.nodes().map(v=>g.node(v).rank));let layers=[];g.nodes()
495
495
  /*
496
496
  * Returns a new function that wraps `fn` with a timer. The wrapper logs the
497
497
  * time it takes to execute the function.
498
- */function time(name,fn){let start=Date.now();try{return fn()}finally{console.log(name+" time: "+(Date.now()-start)+"ms")}}function notime(name,fn){return fn()}let idCounter=0;function uniqueId(prefix){var id=++idCounter;return toString(prefix)+id}function range(start,limit,step=1){if(limit==null){limit=start;start=0}let endCon=i=>i<limit;if(step<0){endCon=i=>limit<i}const range=[];for(let i=start;endCon(i);i+=step){range.push(i)}return range}function pick(source,keys){const dest={};for(const key of keys){if(source[key]!==undefined){dest[key]=source[key]}}return dest}function mapValues(obj,funcOrProp){let func=funcOrProp;if(typeof funcOrProp==="string"){func=val=>val[funcOrProp]}return Object.entries(obj).reduce((acc,[k,v])=>{acc[k]=func(v,k);return acc},{})}function zipObject(props,values){return props.reduce((acc,key,i)=>{acc[key]=values[i];return acc},{})}},{"@dagrejs/graphlib":29}],28:[function(require,module,exports){module.exports="1.0.4"},{}],29:[function(require,module,exports){
498
+ */function time(name,fn){let start=Date.now();try{return fn()}finally{console.log(name+" time: "+(Date.now()-start)+"ms")}}function notime(name,fn){return fn()}let idCounter=0;function uniqueId(prefix){var id=++idCounter;return toString(prefix)+id}function range(start,limit,step=1){if(limit==null){limit=start;start=0}let endCon=i=>i<limit;if(step<0){endCon=i=>limit<i}const range=[];for(let i=start;endCon(i);i+=step){range.push(i)}return range}function pick(source,keys){const dest={};for(const key of keys){if(source[key]!==undefined){dest[key]=source[key]}}return dest}function mapValues(obj,funcOrProp){let func=funcOrProp;if(typeof funcOrProp==="string"){func=val=>val[funcOrProp]}return Object.entries(obj).reduce((acc,[k,v])=>{acc[k]=func(v,k);return acc},{})}function zipObject(props,values){return props.reduce((acc,key,i)=>{acc[key]=values[i];return acc},{})}},{"@dagrejs/graphlib":29}],28:[function(require,module,exports){module.exports="1.1.1"},{}],29:[function(require,module,exports){
499
499
  /**
500
500
  * Copyright (c) 2014, Chris Pettitt
501
501
  * All rights reserved.
@@ -798,4 +798,4 @@ module.exports={Graph:require("./graph"),version:require("./version")}},{"./grap
798
798
  * // ['a', 'b']
799
799
  * g2.edges()
800
800
  * // [ { v: 'a', w: 'b' } ]
801
- */function read(json){var g=new Graph(json.options).setGraph(json.value);json.nodes.forEach(function(entry){g.setNode(entry.v,entry.value);if(entry.parent){g.setParent(entry.v,entry.parent)}});json.edges.forEach(function(entry){g.setEdge({v:entry.v,w:entry.w,name:entry.name},entry.value)});return g}},{"./graph":44}],47:[function(require,module,exports){module.exports="2.1.13"},{}]},{},[1])(1)});
801
+ */function read(json){var g=new Graph(json.options).setGraph(json.value);json.nodes.forEach(function(entry){g.setNode(entry.v,entry.value);if(entry.parent){g.setParent(entry.v,entry.parent)}});json.edges.forEach(function(entry){g.setEdge({v:entry.v,w:entry.w,name:entry.name},entry.value)});return g}},{"./graph":44}],47:[function(require,module,exports){module.exports="2.2.1"},{}]},{},[1])(1)});
package/lib/acyclic.js CHANGED
@@ -1,32 +1,37 @@
1
1
  "use strict";
2
2
 
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.run = run;
7
- exports.undo = undo;
8
- var _greedyFas = _interopRequireDefault(require("./greedy-fas.js"));
9
- var _util = require("./util.js");
10
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
3
+ let greedyFAS = require("./greedy-fas");
4
+ let uniqueId = require("./util").uniqueId;
5
+
6
+ module.exports = {
7
+ run: run,
8
+ undo: undo
9
+ };
10
+
11
11
  function run(g) {
12
- let fas = g.graph().acyclicer === "greedy" ? (0, _greedyFas.default)(g, weightFn(g)) : dfsFAS(g);
12
+ let fas = (g.graph().acyclicer === "greedy"
13
+ ? greedyFAS(g, weightFn(g))
14
+ : dfsFAS(g));
13
15
  fas.forEach(e => {
14
16
  let label = g.edge(e);
15
17
  g.removeEdge(e);
16
18
  label.forwardName = e.name;
17
19
  label.reversed = true;
18
- g.setEdge(e.w, e.v, label, (0, _util.uniqueId)("rev"));
20
+ g.setEdge(e.w, e.v, label, uniqueId("rev"));
19
21
  });
22
+
20
23
  function weightFn(g) {
21
24
  return e => {
22
25
  return g.edge(e).weight;
23
26
  };
24
27
  }
25
28
  }
29
+
26
30
  function dfsFAS(g) {
27
31
  let fas = [];
28
32
  let stack = {};
29
33
  let visited = {};
34
+
30
35
  function dfs(v) {
31
36
  if (visited.hasOwnProperty(v)) {
32
37
  return;
@@ -42,14 +47,17 @@ function dfsFAS(g) {
42
47
  });
43
48
  delete stack[v];
44
49
  }
50
+
45
51
  g.nodes().forEach(dfs);
46
52
  return fas;
47
53
  }
54
+
48
55
  function undo(g) {
49
56
  g.edges().forEach(e => {
50
57
  let label = g.edge(e);
51
58
  if (label.reversed) {
52
59
  g.removeEdge(e);
60
+
53
61
  let forwardName = label.forwardName;
54
62
  delete label.reversed;
55
63
  delete label.forwardName;
@@ -1,12 +1,7 @@
1
- "use strict";
1
+ let util = require("./util");
2
+
3
+ module.exports = addBorderSegments;
2
4
 
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = addBorderSegments;
7
- var util = _interopRequireWildcard(require("./util.js"));
8
- 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); }
9
- 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; }
10
5
  function addBorderSegments(g) {
11
6
  function dfs(v) {
12
7
  let children = g.children(v);
@@ -14,32 +9,29 @@ function addBorderSegments(g) {
14
9
  if (children.length) {
15
10
  children.forEach(dfs);
16
11
  }
12
+
17
13
  if (node.hasOwnProperty("minRank")) {
18
14
  node.borderLeft = [];
19
15
  node.borderRight = [];
20
- for (let rank = node.minRank, maxRank = node.maxRank + 1; rank < maxRank; ++rank) {
16
+ for (let rank = node.minRank, maxRank = node.maxRank + 1;
17
+ rank < maxRank;
18
+ ++rank) {
21
19
  addBorderNode(g, "borderLeft", "_bl", v, node, rank);
22
20
  addBorderNode(g, "borderRight", "_br", v, node, rank);
23
21
  }
24
22
  }
25
23
  }
24
+
26
25
  g.children().forEach(dfs);
27
26
  }
27
+
28
28
  function addBorderNode(g, prop, prefix, sg, sgNode, rank) {
29
- let label = {
30
- width: 0,
31
- height: 0,
32
- rank: rank,
33
- borderType: prop
34
- };
29
+ let label = { width: 0, height: 0, rank: rank, borderType: prop };
35
30
  let prev = sgNode[prop][rank - 1];
36
31
  let curr = util.addDummyNode(g, "border", label, prefix);
37
32
  sgNode[prop][rank] = curr;
38
33
  g.setParent(curr, sg);
39
34
  if (prev) {
40
- g.setEdge(prev, curr, {
41
- weight: 1
42
- });
35
+ g.setEdge(prev, curr, { weight: 1 });
43
36
  }
44
37
  }
45
- module.exports = exports.default;
@@ -1,37 +1,43 @@
1
1
  "use strict";
2
2
 
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.adjust = adjust;
7
- exports.undo = undo;
3
+ module.exports = {
4
+ adjust: adjust,
5
+ undo: undo
6
+ };
7
+
8
8
  function adjust(g) {
9
9
  let rankDir = g.graph().rankdir.toLowerCase();
10
10
  if (rankDir === "lr" || rankDir === "rl") {
11
11
  swapWidthHeight(g);
12
12
  }
13
13
  }
14
+
14
15
  function undo(g) {
15
16
  let rankDir = g.graph().rankdir.toLowerCase();
16
17
  if (rankDir === "bt" || rankDir === "rl") {
17
18
  reverseY(g);
18
19
  }
20
+
19
21
  if (rankDir === "lr" || rankDir === "rl") {
20
22
  swapXY(g);
21
23
  swapWidthHeight(g);
22
24
  }
23
25
  }
26
+
24
27
  function swapWidthHeight(g) {
25
28
  g.nodes().forEach(v => swapWidthHeightOne(g.node(v)));
26
29
  g.edges().forEach(e => swapWidthHeightOne(g.edge(e)));
27
30
  }
31
+
28
32
  function swapWidthHeightOne(attrs) {
29
33
  let w = attrs.width;
30
34
  attrs.width = attrs.height;
31
35
  attrs.height = w;
32
36
  }
37
+
33
38
  function reverseY(g) {
34
39
  g.nodes().forEach(v => reverseYOne(g.node(v)));
40
+
35
41
  g.edges().forEach(e => {
36
42
  let edge = g.edge(e);
37
43
  edge.points.forEach(reverseYOne);
@@ -40,11 +46,14 @@ function reverseY(g) {
40
46
  }
41
47
  });
42
48
  }
49
+
43
50
  function reverseYOne(attrs) {
44
51
  attrs.y = -attrs.y;
45
52
  }
53
+
46
54
  function swapXY(g) {
47
55
  g.nodes().forEach(v => swapXYOne(g.node(v)));
56
+
48
57
  g.edges().forEach(e => {
49
58
  let edge = g.edge(e);
50
59
  edge.points.forEach(swapXYOne);
@@ -53,6 +62,7 @@ function swapXY(g) {
53
62
  }
54
63
  });
55
64
  }
65
+
56
66
  function swapXYOne(attrs) {
57
67
  let x = attrs.x;
58
68
  attrs.x = attrs.y;
package/lib/data/list.js CHANGED
@@ -1,9 +1,3 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
1
  /*
8
2
  * Simple doubly linked list implementation derived from Cormen, et al.,
9
3
  * "Introduction to Algorithms".
@@ -15,6 +9,7 @@ class List {
15
9
  sentinel._next = sentinel._prev = sentinel;
16
10
  this._sentinel = sentinel;
17
11
  }
12
+
18
13
  dequeue() {
19
14
  let sentinel = this._sentinel;
20
15
  let entry = sentinel._prev;
@@ -23,6 +18,7 @@ class List {
23
18
  return entry;
24
19
  }
25
20
  }
21
+
26
22
  enqueue(entry) {
27
23
  let sentinel = this._sentinel;
28
24
  if (entry._prev && entry._next) {
@@ -33,6 +29,7 @@ class List {
33
29
  sentinel._next = entry;
34
30
  entry._prev = sentinel;
35
31
  }
32
+
36
33
  toString() {
37
34
  let strs = [];
38
35
  let sentinel = this._sentinel;
@@ -44,16 +41,18 @@ class List {
44
41
  return "[" + strs.join(", ") + "]";
45
42
  }
46
43
  }
47
- exports.default = List;
44
+
48
45
  function unlink(entry) {
49
46
  entry._prev._next = entry._next;
50
47
  entry._next._prev = entry._prev;
51
48
  delete entry._next;
52
49
  delete entry._prev;
53
50
  }
51
+
54
52
  function filterOutLinks(k, v) {
55
53
  if (k !== "_next" && k !== "_prev") {
56
54
  return v;
57
55
  }
58
56
  }
59
- module.exports = exports.default;
57
+
58
+ module.exports = List;
package/lib/debug.js CHANGED
@@ -1,42 +1,31 @@
1
- "use strict";
1
+ let util = require("./util");
2
+ let Graph = require("@dagrejs/graphlib").Graph;
2
3
 
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = debugOrdering;
7
- var util = _interopRequireWildcard(require("./util.js"));
8
- var _graphlib = require("@dagrejs/graphlib");
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; }
11
- // web-devs write a <script type="importmap"> to map
12
- // nodejs paths to actual http://paths
4
+ module.exports = {
5
+ debugOrdering: debugOrdering
6
+ };
13
7
 
14
8
  /* istanbul ignore next */
15
9
  function debugOrdering(g) {
16
10
  let layerMatrix = util.buildLayerMatrix(g);
17
- let h = new _graphlib.Graph({
18
- compound: true,
19
- multigraph: true
20
- }).setGraph({});
11
+
12
+ let h = new Graph({ compound: true, multigraph: true }).setGraph({});
13
+
21
14
  g.nodes().forEach(v => {
22
- h.setNode(v, {
23
- label: v
24
- });
15
+ h.setNode(v, { label: v });
25
16
  h.setParent(v, "layer" + g.node(v).rank);
26
17
  });
18
+
27
19
  g.edges().forEach(e => h.setEdge(e.v, e.w, {}, e.name));
20
+
28
21
  layerMatrix.forEach((layer, i) => {
29
22
  let layerV = "layer" + i;
30
- h.setNode(layerV, {
31
- rank: "same"
32
- });
23
+ h.setNode(layerV, { rank: "same" });
33
24
  layer.reduce((u, v) => {
34
- h.setEdge(u, v, {
35
- style: "invis"
36
- });
25
+ h.setEdge(u, v, { style: "invis" });
37
26
  return v;
38
27
  });
39
28
  });
29
+
40
30
  return h;
41
31
  }
42
- module.exports = exports.default;
package/lib/greedy-fas.js CHANGED
@@ -1,14 +1,5 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = greedyFAS;
7
- var _graphlib = require("@dagrejs/graphlib");
8
- var _list = _interopRequireDefault(require("./data/list.js"));
9
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10
- // web-devs write a <script type="importmap"> to map
11
- // nodejs paths to actual http://paths
1
+ let Graph = require("@dagrejs/graphlib").Graph;
2
+ let List = require("./data/list");
12
3
 
13
4
  /*
14
5
  * A greedy heuristic for finding a feedback arc set for a graph. A feedback
@@ -17,8 +8,10 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
17
8
  * effective heuristic for the feedback arc set problem." This implementation
18
9
  * adjusts that from the paper to allow for weighted edges.
19
10
  */
11
+ module.exports = greedyFAS;
20
12
 
21
13
  let DEFAULT_WEIGHT_FN = () => 1;
14
+
22
15
  function greedyFAS(g, weightFn) {
23
16
  if (g.nodeCount() <= 1) {
24
17
  return [];
@@ -29,18 +22,16 @@ function greedyFAS(g, weightFn) {
29
22
  // Expand multi-edges
30
23
  return results.flatMap(e => g.outEdges(e.v, e.w));
31
24
  }
25
+
32
26
  function doGreedyFAS(g, buckets, zeroIdx) {
33
27
  let results = [];
34
28
  let sources = buckets[buckets.length - 1];
35
29
  let sinks = buckets[0];
30
+
36
31
  let entry;
37
32
  while (g.nodeCount()) {
38
- while (entry = sinks.dequeue()) {
39
- removeNode(g, buckets, zeroIdx, entry);
40
- }
41
- while (entry = sources.dequeue()) {
42
- removeNode(g, buckets, zeroIdx, entry);
43
- }
33
+ while ((entry = sinks.dequeue())) { removeNode(g, buckets, zeroIdx, entry); }
34
+ while ((entry = sources.dequeue())) { removeNode(g, buckets, zeroIdx, entry); }
44
35
  if (g.nodeCount()) {
45
36
  for (let i = buckets.length - 2; i > 0; --i) {
46
37
  entry = buckets[i].dequeue();
@@ -51,22 +42,25 @@ function doGreedyFAS(g, buckets, zeroIdx) {
51
42
  }
52
43
  }
53
44
  }
45
+
54
46
  return results;
55
47
  }
48
+
56
49
  function removeNode(g, buckets, zeroIdx, entry, collectPredecessors) {
57
50
  let results = collectPredecessors ? [] : undefined;
51
+
58
52
  g.inEdges(entry.v).forEach(edge => {
59
53
  let weight = g.edge(edge);
60
54
  let uEntry = g.node(edge.v);
55
+
61
56
  if (collectPredecessors) {
62
- results.push({
63
- v: edge.v,
64
- w: edge.w
65
- });
57
+ results.push({ v: edge.v, w: edge.w });
66
58
  }
59
+
67
60
  uEntry.out -= weight;
68
61
  assignBucket(buckets, zeroIdx, uEntry);
69
62
  });
63
+
70
64
  g.outEdges(entry.v).forEach(edge => {
71
65
  let weight = g.edge(edge);
72
66
  let w = edge.w;
@@ -74,19 +68,19 @@ function removeNode(g, buckets, zeroIdx, entry, collectPredecessors) {
74
68
  wEntry["in"] -= weight;
75
69
  assignBucket(buckets, zeroIdx, wEntry);
76
70
  });
71
+
77
72
  g.removeNode(entry.v);
73
+
78
74
  return results;
79
75
  }
76
+
80
77
  function buildState(g, weightFn) {
81
- let fasGraph = new _graphlib.Graph();
78
+ let fasGraph = new Graph();
82
79
  let maxIn = 0;
83
80
  let maxOut = 0;
81
+
84
82
  g.nodes().forEach(v => {
85
- fasGraph.setNode(v, {
86
- v: v,
87
- "in": 0,
88
- out: 0
89
- });
83
+ fasGraph.setNode(v, { v: v, "in": 0, out: 0 });
90
84
  });
91
85
 
92
86
  // Aggregate weights on nodes, but also sum the weights across multi-edges
@@ -97,19 +91,19 @@ function buildState(g, weightFn) {
97
91
  let edgeWeight = prevWeight + weight;
98
92
  fasGraph.setEdge(e.v, e.w, edgeWeight);
99
93
  maxOut = Math.max(maxOut, fasGraph.node(e.v).out += weight);
100
- maxIn = Math.max(maxIn, fasGraph.node(e.w)["in"] += weight);
94
+ maxIn = Math.max(maxIn, fasGraph.node(e.w)["in"] += weight);
101
95
  });
102
- let buckets = range(maxOut + maxIn + 3).map(() => new _list.default());
96
+
97
+ let buckets = range(maxOut + maxIn + 3).map(() => new List());
103
98
  let zeroIdx = maxIn + 1;
99
+
104
100
  fasGraph.nodes().forEach(v => {
105
101
  assignBucket(buckets, zeroIdx, fasGraph.node(v));
106
102
  });
107
- return {
108
- graph: fasGraph,
109
- buckets: buckets,
110
- zeroIdx: zeroIdx
111
- };
103
+
104
+ return { graph: fasGraph, buckets: buckets, zeroIdx: zeroIdx };
112
105
  }
106
+
113
107
  function assignBucket(buckets, zeroIdx, entry) {
114
108
  if (!entry.out) {
115
109
  buckets[0].enqueue(entry);
@@ -119,11 +113,12 @@ function assignBucket(buckets, zeroIdx, entry) {
119
113
  buckets[entry.out - entry["in"] + zeroIdx].enqueue(entry);
120
114
  }
121
115
  }
116
+
122
117
  function range(limit) {
123
118
  const range = [];
124
119
  for (let i = 0; i < limit; i++) {
125
120
  range.push(i);
126
121
  }
122
+
127
123
  return range;
128
124
  }
129
- module.exports = exports.default;