2019-07-03 18:13:11 +00:00
|
|
|
class LayoutGroup {
|
2019-07-05 06:10:41 +00:00
|
|
|
constructor(graphGroup, nodesByPos, nodes) {
|
2019-07-04 06:42:05 +00:00
|
|
|
this.graphGroup_ = graphGroup;
|
2019-07-05 06:10:41 +00:00
|
|
|
this.nodesByPos_ = nodesByPos;
|
2019-07-03 03:36:48 +00:00
|
|
|
this.nodes = new Set(nodes);
|
2019-07-03 18:13:11 +00:00
|
|
|
this.tension = 0;
|
2019-07-03 01:42:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setTension() {
|
2019-07-03 18:13:11 +00:00
|
|
|
// Groups don't track tension, since we always want to sort last for total
|
|
|
|
|
// tension
|
2019-07-03 01:42:17 +00:00
|
|
|
this.vec = [0, 0];
|
2019-07-05 06:10:41 +00:00
|
|
|
for (let node of this.nodes) {
|
2019-07-03 01:42:17 +00:00
|
|
|
for (let i of [0, 1]) {
|
|
|
|
|
this.vec[i] += node.vec[i];
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-03 18:13:11 +00:00
|
|
|
offsetCollides(offset) {
|
2019-07-05 06:10:41 +00:00
|
|
|
for (let node of this.nodes) {
|
2019-07-03 18:13:11 +00:00
|
|
|
let other = node.offsetCollides(offset);
|
2019-07-03 03:36:48 +00:00
|
|
|
if (other && !this.nodes.has(other)) {
|
2019-07-03 01:42:17 +00:00
|
|
|
return other;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
savePos() {
|
2019-07-05 06:10:41 +00:00
|
|
|
for (let node of this.nodes) {
|
2019-07-03 01:42:17 +00:00
|
|
|
node.savePos();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-03 18:13:11 +00:00
|
|
|
restorePos() {
|
2019-07-05 06:10:41 +00:00
|
|
|
for (let node of this.nodes) {
|
2019-07-03 18:13:11 +00:00
|
|
|
node.restorePos();
|
2019-07-03 01:42:17 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-03 18:13:11 +00:00
|
|
|
moveBy(offset) {
|
2019-07-05 06:10:41 +00:00
|
|
|
for (let node of this.nodes) {
|
|
|
|
|
node.moveBy(offset);
|
|
|
|
|
}
|
|
|
|
|
// Fix up nodesByPos, as intra-group collisions may have corrupted it
|
|
|
|
|
for (let node of this.nodes) {
|
|
|
|
|
this.nodesByPos_.set(node.pos.toString(), node);
|
2019-07-03 01:42:17 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-07-04 06:42:05 +00:00
|
|
|
|
|
|
|
|
getMinMax() {
|
|
|
|
|
let min = [Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER];
|
|
|
|
|
let max = [Number.MIN_SAFE_INTEGER, Number.MIN_SAFE_INTEGER];
|
|
|
|
|
for (let node of this.nodes) {
|
|
|
|
|
for (let i of [0, 1]) {
|
|
|
|
|
min[i] = Math.min(min[i], node.pos[i]);
|
|
|
|
|
max[i] = Math.max(max[i], node.pos[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (this.graphGroup_ && this.graphGroup_.label) {
|
|
|
|
|
// Room for the label
|
|
|
|
|
--min[1];
|
|
|
|
|
}
|
|
|
|
|
return [min, max];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getStep() {
|
|
|
|
|
if (!this.graphGroup_) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let [min, max] = this.getMinMax();
|
|
|
|
|
return {
|
|
|
|
|
type: 'group',
|
|
|
|
|
min: min,
|
|
|
|
|
max: max,
|
|
|
|
|
label: this.graphGroup_.label,
|
|
|
|
|
};
|
|
|
|
|
}
|
2019-07-03 01:42:17 +00:00
|
|
|
}
|