From 3f015a35407983911336bfbec03743541260af80 Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Tue, 9 Jul 2019 05:55:04 +0000 Subject: [PATCH] Encourage link merging --- GraphNode.js | 2 +- LayoutLink.js | 40 +++++++++++++++++++++++----------------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/GraphNode.js b/GraphNode.js index 85caaf8..fb3e4d8 100644 --- a/GraphNode.js +++ b/GraphNode.js @@ -68,7 +68,7 @@ class GraphNode { // Try to preserve pagerank left-to-right flow from initial positions let rankSign = Math.sign(node.pageRank - this.pageRank); this.addAffinity(node, (d, v) => - [Math.sign(v[0]) == rankSign ? 0 : -500, 0]); + [Math.sign(v[0]) == rankSign ? 0 : -1000, 0]); } for (let to of this.links) { diff --git a/LayoutLink.js b/LayoutLink.js index 920fa57..c4d3361 100644 --- a/LayoutLink.js +++ b/LayoutLink.js @@ -121,24 +121,30 @@ class LayoutLink { // Traversing nodes has higher cost cost += 5; }; + } - // Overlapping links have cost, but not if they are from or to the same - // node we are (which render as merging or splitting lines). Allowing - // that saves space. We XOR because we want to force apart lines between - // the same pair, e.g. for redundant or cyclical links. - for (let point of [this.getInPoint(from, to), - this.getOutPoint(from, to)]) { - // inPoint/outPoint is part of the key because we only count the lines - // as "overlapping" if they travel together, not if they just cross. - let links = this.linksByPos_.get([pos, point]); - if (!links) { - continue; - } - let hasFrom = links.has('f' + this.from_.pos.toString()); - let hasTo = links.has('t' + this.to_.pos.toString()); - if (!(hasFrom || hasTo) || (hasFrom && hasTo)) { - cost += 2; - } + // Overlapping links have cost, but not if they are from or to the same + // node we are (which render as merging or splitting lines). Allowing + // that saves space. We XOR because we want to force apart lines between + // the same pair, e.g. for redundant or cyclical links. + for (let key of [[from, this.getOutPoint(from, to)], + [to, this.getInPoint(from, to)]]) { + // inPoint/outPoint is part of the key because we only count the lines + // as "overlapping" if they travel together, not if they just cross. + let links = this.linksByPos_.get(key); + if (!links) { + continue; + } + let hasFrom = links.has('f' + this.from_.pos.toString()); + let hasTo = links.has('t' + this.to_.pos.toString()); + if (hasFrom && hasTo) { + // Push apart lines between the same pair + cost += 2; + } else if (hasFrom || hasTo) { + // Encourage merging + cost -= 0.25; + } else { + cost += 2; } }