Fix overlapping groups

This commit is contained in:
Ian Gulliver
2019-07-09 20:34:36 +00:00
parent b7d51417d6
commit b0bc1e5f3b
4 changed files with 30 additions and 2 deletions

View File

@@ -41,6 +41,7 @@ class GraphNode {
}
}
// TODO: move this to LayoutNode, item by item
setAffinity(nodes) {
const INF = 999999;

View File

@@ -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();

View File

@@ -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;

View File

@@ -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];