Files
cs5890_data_visualization/hw2/js/Tree.js
2019-09-30 22:29:42 -06:00

108 lines
3.0 KiB
JavaScript

/** Class representing a Tree. */
class Tree {
/**
* Creates a Tree Object
* parentNode, children, parentName,level,position
* @param {json[]} json - array of json object with name and parent fields
*/
constructor(json) {
this.listOfNodes = [];
json.forEach(nodeInfo => {
let node = new Node(nodeInfo.name, nodeInfo.parent);
//console.log(node);
this.listOfNodes.push(node);
});
}
/**
* Function that builds a tree from a list of nodes with parent refs
*/
buildTree(){
let rootNode = this.listOfNodes.find(node => node.parentName === "root");
this.listOfNodes.forEach(currentNode => {
for(let i = 0; i < this.listOfNodes.length; i ++){
if(this.listOfNodes[i].parentName === currentNode.name){
currentNode.addChild(this.listOfNodes[i]);
}
}
});
//console.log(rootNode);
this.assignLevel(rootNode, 0);
this.assignPosition(rootNode, 0);
}
/**
* Recursive function that assign positions to each node
*/
assignPosition(node, position) {
node.position = position;
let currentlevel = node.level;
let q = [];
node.children.forEach(x=>{
q.push(x)
});
let count = 0;
while(q.length > 0){
let current = q.shift();
if(currentlevel === current.level){
current.position = count;
count +=1;
current.children.forEach(x=> q.push(x));
console.log(q);
}
else{
currentlevel = current.level;
current.children.forEach(x=> q.push(x));
count = current.position+1;
}
}
}
/**
* Recursive function that assign levels to each node
*/
assignLevel(node, level) {
node.level = level;
node.children.forEach(childNode => {
this.assignLevel(childNode, level+1);
})
}
/**
* Function that renders the tree
*/
renderTree() {
d3.select("body")
.append("svg")
.attr("width", 1200)
.attr("height", 1200);
this.listOfNodes.forEach(node => {
let svgElement = d3.select("svg");
for (var i = 0; i < node.children.length; i++) {
svgElement.append("line")
.attr("x1", (node.level + 3) * 100)
.attr("y1", (node.position + 3) * 100)
.attr("x2", (node.children[i].level +3) * 100)
.attr("y2", (node.children[i].position+3) * 100)
}
svgElement.append("circle")
.attr("r", 35)
.attr("cx", (node.level+3) * 100)
.attr("cy", (node.position+3) * 100);
svgElement.append("text")
.attr("class", "label")
.attr("dx", (node.level+3) * 100)
.attr("dy", (node.position+3) * 100)
.text(node.name)
})
}
}