From cdd91d04ce7b20369ba3f11426ad4e5f54b3bce9 Mon Sep 17 00:00:00 2001 From: Anya Date: Thu, 27 Jun 2019 18:00:22 +0200 Subject: [PATCH 1/3] Allow manual ranking --- lib/layout.js | 2 +- lib/rank/index.js | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/layout.js b/lib/layout.js index 26b07304..9309b995 100644 --- a/lib/layout.js +++ b/lib/layout.js @@ -97,7 +97,7 @@ function updateInputGraph(inputGraph, layoutGraph) { var graphNumAttrs = ["nodesep", "edgesep", "ranksep", "marginx", "marginy"]; var graphDefaults = { ranksep: 50, edgesep: 20, nodesep: 50, rankdir: "tb" }; var graphAttrs = ["acyclicer", "ranker", "rankdir", "align"]; -var nodeNumAttrs = ["width", "height"]; +var nodeNumAttrs = ["width", "height", "rank"], var nodeDefaults = { width: 0, height: 0 }; var edgeNumAttrs = ["minlen", "weight", "width", "height", "labeloffset"]; var edgeDefaults = { diff --git a/lib/rank/index.js b/lib/rank/index.js index 5ec26c8d..58c38b9a 100644 --- a/lib/rank/index.js +++ b/lib/rank/index.js @@ -27,14 +27,21 @@ module.exports = rank; * fix them up later. */ function rank(g) { + var ranker = g.graph().ranker; + if (ranker instanceof Function) { + return ranker(g) + } + switch(g.graph().ranker) { - case "network-simplex": networkSimplexRanker(g); break; - case "tight-tree": tightTreeRanker(g); break; - case "longest-path": longestPathRanker(g); break; - default: networkSimplexRanker(g); + case "network-simplex": networkSimplexRanker(g); break; + case "tight-tree": tightTreeRanker(g); break; + case "longest-path": longestPathRanker(g); break; + case "none": break; + default: networkSimplexRanker(g); } } + // A fast and simple ranker, but results are far from optimal. var longestPathRanker = longestPath; From ae243c73b02d655a3ddeada13712eff0127db735 Mon Sep 17 00:00:00 2001 From: Anya Date: Thu, 27 Jun 2019 18:55:20 +0200 Subject: [PATCH 2/3] Calculate same-layer crossings --- lib/order/cross-count.js | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/lib/order/cross-count.js b/lib/order/cross-count.js index 2f8b6b0f..b5c93601 100644 --- a/lib/order/cross-count.js +++ b/lib/order/cross-count.js @@ -22,12 +22,40 @@ module.exports = crossCount; */ function crossCount(g, layering) { var cc = 0; - for (var i = 1; i < layering.length; ++i) { - cc += twoLayerCrossCount(g, layering[i-1], layering[i]); + for (var i = 0; i < layering.length; ++i) { + cc += singleLayerCrossCount(g, layering[i]); + if (i > 0) { + cc += twoLayerCrossCount(g, layering[i-1], layering[i]); + } } return cc; } + +// Count crossings between a single layer, in cases where manual ranking +// enables edges between nodes with the same rank. +function singleLayerCrossCount(g, layer) { + var layerRank = g.node(layer[0]).rank; + var layerIndex = _.zipObject( + layer, + _.map(layer, function (v, i) { return i; }) + ); + + var cc = 0; + _.forEach(layer, function(n, i) { + _.forEach(g.inEdges(n), function(e) { + if (g.node(e.v).rank == layerRank) { + var otherPos = layerIndex[e.v]; + if (Math.abs(otherPos - i) > 1) { + cc++; + } + } + }); + }); + return cc; +} + + function twoLayerCrossCount(g, northLayer, southLayer) { // Sort all of the edges between the north and south layers by their position // in the north layer and then the south. Map these edges to the position of From 049b4263370efc8994c24c13c857d5ec5e88e425 Mon Sep 17 00:00:00 2001 From: Richard Westenra Date: Tue, 24 Mar 2020 12:27:45 +0000 Subject: [PATCH 3/3] Fix syntax error Hopefully fix broken CI build/test --- lib/layout.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/layout.js b/lib/layout.js index 9309b995..e68d8e79 100644 --- a/lib/layout.js +++ b/lib/layout.js @@ -97,7 +97,7 @@ function updateInputGraph(inputGraph, layoutGraph) { var graphNumAttrs = ["nodesep", "edgesep", "ranksep", "marginx", "marginy"]; var graphDefaults = { ranksep: 50, edgesep: 20, nodesep: 50, rankdir: "tb" }; var graphAttrs = ["acyclicer", "ranker", "rankdir", "align"]; -var nodeNumAttrs = ["width", "height", "rank"], +var nodeNumAttrs = ["width", "height", "rank"]; var nodeDefaults = { width: 0, height: 0 }; var edgeNumAttrs = ["minlen", "weight", "width", "height", "labeloffset"]; var edgeDefaults = {