@gravity-ui/graph
Version:
Modern graph editor component
103 lines (102 loc) • 2.97 kB
JavaScript
import { cache } from "./utils";
export class Tree {
constructor(data, parent) {
this.children = new Set();
this.childrenArray = [];
this.childrenDirty = false;
this.zIndexGroups = new Map();
this.zIndexChildrenCache = cache(() => {
return Array.from(this.zIndexGroups.keys())
.sort((a, b) => a - b)
.map((index) => Array.from(this.zIndexGroups.get(index) || []))
.flat(2);
});
this.renderOrder = 0;
this.zIndex = 1;
this.data = data;
this.parent = parent;
}
append(node) {
node.parent = this;
this.children.add(node);
this.childrenDirty = true;
this.addInZIndex(node);
}
addInZIndex(node) {
if (!this.zIndexGroups.has(node.zIndex)) {
this.zIndexGroups.set(node.zIndex, new Set());
}
this.zIndexGroups.get(node.zIndex).add(node);
this.zIndexChildrenCache.reset();
}
removeZIndex(node) {
const zIndex = node.zIndex;
const set = this.zIndexGroups.get(node.zIndex);
if (!set)
return;
set.delete(node);
if (!set.size) {
this.zIndexGroups.delete(zIndex);
this.zIndexChildrenCache.reset();
}
}
remove(node = this) {
if (node.parent === null)
return;
this.children.delete(node);
this.childrenDirty = true;
this.removeZIndex(node);
}
setChildren(nodes) {
this.children = new Set(nodes);
this.childrenDirty = true;
nodes.forEach((item) => {
this.addInZIndex(item);
});
}
updateZIndex(index) {
if (this.zIndex === index) {
return;
}
this.zIndex = index;
this.parent?.updateChildZIndex(this);
}
updateChildZIndex(child) {
if (!this.children.has(child)) {
return;
}
this.removeZIndex(child);
this.addInZIndex(child);
}
clearChildren() {
this.children.clear();
this.childrenDirty = true;
this.zIndexGroups.clear();
this.zIndexChildrenCache.clear();
}
traverseDown(iterator) {
this._traverse(iterator, "_walkDown");
}
_traverse(iterator, strategyName) {
this[strategyName](iterator);
}
getChildrenArray() {
if (this.childrenDirty) {
this.childrenArray = Array.from(this.children);
this.childrenDirty = false;
}
return this.childrenArray;
}
_walkDown(iterator, order) {
this.renderOrder = order;
if (iterator(this)) {
if (!this.children.size) {
return;
}
const children = this.zIndexChildrenCache.get();
for (let i = 0; i < children.length; i++) {
children[i]._walkDown(iterator, i);
}
}
}
}