You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

115 lines
3.7 KiB

class Node {
constructor(data, tree) {
this.name = data.name;
this.id = data.id;
if (data.parent === null) {
this.parent = "root";
data.parent = {id:"root"};
this.name = ""
}
if (data.parent.id && data.parent.id !== 'root') {
let el = tree._getElementById(data.parent.id);
this.parent = el.node || new Node(el, tree);
}
data.node = this;
this.children = data.children.map(function (el_obj) {
let el = tree._getElementById(el_obj.id);
if(!el) console.log("el not found with id", el_obj.id);
// console.log("el = ", el, "el.id = ", el_obj.id);
if (el.node) return el.node;
el.node = new Node(el, tree);
return el.node
});
this.children = this.children || [];
}
}
class SpecTree {
constructor(data) {
this.baseData = data;
this._root = new Node(data[0], this);
}
/**
* получить element в базовой структуре
*/
_getElementById(id) {
for (let i = 0; i < this.baseData.length; i++) {
// console.log(this.baseData[i].id, " / ", id);
if (this.baseData[i].id == id) return this.baseData[i]
}
}
/**
* получить element в дереве
*/
getElementById(id) {
function searchInChildren(children) {
for (let i = 0; i < children.length; i++) {
if (children[i].id == id) return children[i];
let res = searchInChildren(children[i].children);
if (res) return res
}
}
return searchInChildren(this._root.children)
}
/**
* Является ли узел c el_id дочерним для parent_id
* @param el_id
* @param parent_id
*/
hasChildren(el_id, parent_id){
function checkParent(el, parent) {
if (el.parent == parent) return true;
if (el.parent && el.parent != 'root') return checkParent(el.parent, parent);
return false;
}
return checkParent(this.getElementById(el_id), this.getElementById(parent_id))
}
/**
* @param start_parent_id(number) - начиная с
* @param attached(bool) - включая вложенные/дочерние
* @param exclude_id - исключая узел c exclude_id и всеми его вложенными узлами
* @returns [{name, id}, ...]
*/
dataToList(start_parent_id, attached, exclude_id) {
let data_list = [];
function goInChildren(children) {
for (let i = 0; i < children.length; i++) {
if (children[i].id == exclude_id) continue;
data_list.push({name: children[i].name, id: children[i].id});
if (attached) goInChildren(children[i].children);
}
}
let start = start_parent_id ? this.getElementById(start_parent_id) : this._root;
goInChildren(start.children);
return data_list
}
/**
*
* @param id
* @param incl(bool) - исключая сам элемент
* @returns {Array} всех узлов/элементов от элемента с id до корня
*/
getSpecChain(id, incl){
let chain = [];
let el = this.getElementById(id);
// console.log("el = ", el);
function getParent(el) {
if (el.parent && el.parent != "root"){
chain.push(el.parent);
getParent(el.parent)
}
}
getParent(el);
// console.log("chain = ", chain);
if (incl) chain.unshift(el);
return chain
}
}