UNPKG

sparnatural

Version:

Visual client-side SPARQL query builder and knowledge graph exploration tool

184 lines 6.39 kB
export class Dag { constructor() { this.roots = new Array(); } toDebugString() { let result = ""; this.roots.forEach(root => { result += root.toDebugString(0); }); return result; } /** * Creates a DAG from a map giving the relationship between a node and its parent, and a data map containing the payload * for each ID. * @param hierarchy The map containing the hierarchy information * @param data The map containing the payload information */ initFromFlatList(hierarchy, data, disabled) { this.roots = new Array(); // Create all nodes const nodes = new Map(); for (const [id, parentIds] of hierarchy.entries()) { if (!nodes.has(id)) { nodes.set(id, new DagNode(id, data.get(id))); } if (parentIds !== null) { parentIds.forEach(parentId => { if (!nodes.has(parentId)) { nodes.set(parentId, new DagNode(parentId, data.get(parentId))); } }); } } // set disabled nodes for (const id of disabled) { nodes.get(id).disabled = true; } // Establish parent-child relationships for (const [id, parentIds] of hierarchy.entries()) { const currentNode = nodes.get(id); // no parents, it's a root if (parentIds === null || parentIds.length == 0) this.roots.push(currentNode); else { parentIds.forEach(parentId => { const parentNode = nodes.get(parentId); // addUnder and not moveUnder, otherwise the existing parent would be reset currentNode.addUnder(parentNode); }); } } } /** * A simple method to create a Dag from a map containing the hierarchy, and an array of items that are the payload * and that have a getId() method to retrieve their ID * @param hierarchy the map containing the hierarchy (id <-> list of parent ids) * @param data the array containing the payload objects, each with a getId() function */ initFromIdableEntity(hierarchy, data) { let dataMap = new Map(); data.forEach((item) => { dataMap.set(item.getId(), item); }); this.initFromFlatList(hierarchy, dataMap, new Array()); } /** * A simple method to create a Dag from only an array of items that are the payload * and that have a getId() method to retrieve their ID, and a getParents() methods to retrieve their parents * @param data the array containing the payload objects, each with a getId() function and a getParents() function */ initFromParentableAndIdAbleEntity(data, disabled) { let dataMap = new Map(); data.forEach((item) => { dataMap.set(item.getId(), item); }); let hierarchyMap = new Map(); data.forEach((item) => { hierarchyMap.set(item.getId(), item.getParents()); }); this.initFromFlatList(hierarchyMap, dataMap, disabled); } initFlatTreeFromFlatList(data) { let dataMap = new Map(); data.forEach((item) => { dataMap.set(item.getId(), item); }); // empty hierarchy map let hierarchyMap = new Map(); data.forEach((item) => { hierarchyMap.set(item.getId(), []); }); this.initFromFlatList(hierarchyMap, dataMap, new Array()); } traverseBreadthFirst(processor) { this.roots.forEach(root => { processor(root); }); this.roots.forEach(root => { root.traverseBreadthFirst(processor); }); } traverseDepthFirst(processor) { this.roots.forEach(root => { processor(root); root.traverseBreadthFirst(processor); }); } sort(compareFn) { // when sorting the children array, sort their payload this.roots.sort((a, b) => { return compareFn(a.payload, b.payload); }); // then sort recursively this.roots.forEach(c => c.sort(compareFn)); } } export class DagNode { constructor(id, payload) { this.id = id; this.payload = payload; this.parents = new Array(); this.children = new Array(); } /** * Adds this node under a new parent. Existing parents are kept * @param parent the new parent or null to set a root node */ addUnder(parent) { // link with parent if a parent was given if (parent) { this.parents.push(parent); parent.children.push(this); } } /** * Moves this node under a new parent. This will unlink the node from its existing parents * @param parent the new parent or null to set a root node */ moveUnder(parent) { // unlink from current parents let theId = this.id; this.parents.forEach(p => { p.children = p.children.filter(n => n.id != theId); }); // reset parents this.parents = new Array(); // then add it under new parent this.addUnder(parent); } sort(compareFn) { // when sorting the children array, sort their payload this.children.sort((a, b) => { return compareFn(a.payload, b.payload); }); // then sort recursively this.children.forEach(c => c.sort(compareFn)); } toDebugString(depth) { let indent = ""; for (let i = 0; i < depth; i++) { indent += " "; } let result = indent + "id:" + this.id + (this.disabled ? " !disabled" : "") + "\n"; this.children.forEach(child => { result += child.toDebugString(depth + 2); }); return result; } traverseBreadthFirst(processor) { this.children.forEach(c => { processor(c); }); this.children.forEach(c => { c.traverseBreadthFirst(processor); }); } traverseDepthFirst(processor) { this.children.forEach(c => { processor(c); c.traverseBreadthFirst(processor); }); } } //# sourceMappingURL=Dag.js.map