UNPKG

@gravity-ui/graph

Version:

Modern graph editor component

103 lines (102 loc) 2.97 kB
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); } } } }