diff --git a/GraphNode.js b/GraphNode.js index 3959f2e..ff65273 100644 --- a/GraphNode.js +++ b/GraphNode.js @@ -41,6 +41,7 @@ class GraphNode { } } + // TODO: move this to LayoutNode, item by item setAffinity(nodes) { const INF = 999999; diff --git a/Layout.js b/Layout.js index 9e774d0..bf99e8d 100644 --- a/Layout.js +++ b/Layout.js @@ -9,9 +9,9 @@ class Layout { this.links_ = []; this.setInitialPositions(); + this.resolveGroups(); this.resolveLinks(); this.resolveAffinity(); - this.resolveGroups(); while (this.iterate()); this.addGroupPos(); this.drawLinks(); diff --git a/LayoutGroup.js b/LayoutGroup.js index 8bd0b97..3999fb3 100644 --- a/LayoutGroup.js +++ b/LayoutGroup.js @@ -4,6 +4,10 @@ class LayoutGroup { this.nodesByPos_ = nodesByPos; this.nodes = new Set(nodes); this.tension = 0; + + for (let node of nodes) { + node.groups.push(this); + } } setTension() { @@ -68,6 +72,12 @@ class LayoutGroup { return [min, max]; } + isContained(pos) { + let [min, max] = this.getMinMax(); + return (pos[0] >= min[0] && pos[0] <= max[0] && + pos[1] >= min[1] && pos[1] <= max[1]); + } + getStep() { if (!this.graphGroup_) { return null; diff --git a/LayoutNode.js b/LayoutNode.js index bdc349b..d22d9ec 100644 --- a/LayoutNode.js +++ b/LayoutNode.js @@ -3,6 +3,7 @@ class LayoutNode { this.graphNode_ = graphNode; this.nodesByPos_ = nodesByPos; this.pos = pos; + this.groups = []; this.nodesByPos_.set(this.pos, this); } @@ -15,6 +16,9 @@ class LayoutNode { } resolveAffinity(nodesByGraphNode) { + const INF = 999999; + + // Transitional: copy GraphNode affinity this.affinity_ = []; for (let aff of this.graphNode_.affinity) { this.affinity_.push({ @@ -22,6 +26,19 @@ class LayoutNode { distanceToWeight: aff.distanceToWeight, }); } + + for (let node of nodesByGraphNode.values()) { + for (let group of this.groups) { + // Ensure groups do not overlap + if (group.nodes.has(node)) { + continue; + } + this.affinity_.push({ + node: node, + distanceToWeight: (d, v, p) => group.isContained(p) ? -INF : 0, + }); + } + } } setTension() { @@ -35,7 +52,7 @@ class LayoutNode { }; // Avoid calling sqrt(), since the results are used relatively let distanceSquared = vec[0] * vec[0] + vec[1] * vec[1]; - let weight = aff.distanceToWeight(distanceSquared, vec); + let weight = aff.distanceToWeight(distanceSquared, vec, aff.node.pos); if (weight instanceof Array) { for (let i of [0, 1]) { this.vec[i] += weight[i];