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
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
|
|
}
|
|
} |