224 lines
9.7 KiB
JavaScript
224 lines
9.7 KiB
JavaScript
let atree_map;
|
|
let atree_head;
|
|
let atree_connectors_map;
|
|
function construct_AT(elem, tree) {
|
|
console.log("constructing ability tree UI");
|
|
document.getElementById("atree-active").innerHTML = ""; //reset all atree actives - should be done in a more general way later
|
|
elem.innerHTML = ""; //reset the atree in the DOM
|
|
|
|
if (tree === undefined) {return false;}
|
|
|
|
// add in the "Active" title to atree
|
|
let active_row = document.createElement("div");
|
|
active_row.classList.add("row", "item-title", "mx-auto", "justify-content-center");
|
|
active_row.textContent = "Active:";
|
|
document.getElementById("atree-active").appendChild(active_row);
|
|
|
|
atree_map = new Map();
|
|
atree_connectors_map = new Map()
|
|
for (let i of tree) {
|
|
atree_map.set(i.display_name, {display: i.display, parents: i.parents, connectors: []});
|
|
}
|
|
|
|
for (let i = 0; i < tree.length; i++) {
|
|
let node = tree[i];
|
|
|
|
// create rows if not exist
|
|
let missing_rows = [node.display.row];
|
|
|
|
if (node.parents.length == 0) {
|
|
// Assuming there is only one head.
|
|
atree_head = node;
|
|
}
|
|
|
|
for (let parent of node.parents) {
|
|
missing_rows.push(tree.find(object => {return object.display_name === parent;}).display.row);
|
|
}
|
|
for (let missing_row of missing_rows) {
|
|
if (document.getElementById("atree-row-" + missing_row) == null) {
|
|
for (let j = 0; j <= missing_row; j++) {
|
|
if (document.getElementById("atree-row-" + j) == null) {
|
|
let row = document.createElement('div');
|
|
row.classList.add("row");
|
|
row.id = "atree-row-" + j;
|
|
//was causing atree rows to be 0 height
|
|
row.style.minHeight = elem.scrollWidth / 9 + "px";
|
|
//row.style.minHeight = elem.getBoundingClientRect().width / 9 + "px";
|
|
|
|
for (let k = 0; k < 9; k++) {
|
|
col = document.createElement('div');
|
|
col.classList.add('col', 'px-0');
|
|
col.style.minHeight = elem.scrollWidth / 9 + "px";
|
|
row.appendChild(col);
|
|
|
|
atree_connectors_map.set(j + "," + k, [])
|
|
};
|
|
elem.appendChild(row);
|
|
};
|
|
};
|
|
};
|
|
}
|
|
|
|
|
|
let connector_list = [];
|
|
// create connectors based on parent location
|
|
for (let parent of node.parents) {
|
|
let parent_node = atree_map.get(parent);
|
|
|
|
let connect_elem = document.createElement("div");
|
|
connect_elem.style = "background-size: cover; width: 100%; height: 100%;";
|
|
// connect up
|
|
for (let i = node.display.row - 1; i > parent_node.display.row; i--) {
|
|
let connector = connect_elem.cloneNode();
|
|
connector.style.backgroundImage = "url('../media/atree/connect_line.png')";
|
|
atree_map.get(node.display_name).connectors.push(i + "," + node.display.col);
|
|
atree_connectors_map.get(i + "," + node.display.col).push({connector: connector, type: "line"});
|
|
resolve_connector(i + "," + node.display.col, node);
|
|
}
|
|
// connect horizontally
|
|
let min = Math.min(parent_node.display.col, node.display.col);
|
|
let max = Math.max(parent_node.display.col, node.display.col);
|
|
for (let i = min + 1; i < max; i++) {
|
|
let connector = connect_elem.cloneNode();
|
|
connector.style.backgroundImage = "url('../media/atree/connect_line.png')";
|
|
connector.classList.add("rotate-90");
|
|
atree_map.get(node.display_name).connectors.push(parent_node.display.row + "," + i);
|
|
atree_connectors_map.get(parent_node.display.row + "," + i).push({connector: connector, type: "line"});
|
|
resolve_connector(parent_node.display.row + "," + i, node);
|
|
}
|
|
|
|
// connect corners
|
|
|
|
if (parent_node.display.row != node.display.row && parent_node.display.col != node.display.col) {
|
|
let connector = connect_elem.cloneNode();
|
|
connector.style.backgroundImage = "url('../media/atree/connect_angle.png')";
|
|
atree_map.get(node.display_name).connectors.push(parent_node.display.row + "," + node.display.col);
|
|
atree_connectors_map.get(parent_node.display.row + "," + node.display.col).push({connector: connector, type: "angle"});
|
|
if (parent_node.display.col > node.display.col) {
|
|
connector.classList.add("rotate-180");
|
|
}
|
|
else {// if (parent_node.display.col < node.display.col && (parent_node.display.row != node.display.row)) {
|
|
connector.classList.add("rotate-270");
|
|
}
|
|
resolve_connector(parent_node.display.row + "," + node.display.col, node);
|
|
}
|
|
}
|
|
|
|
// create node
|
|
let node_elem = document.createElement('div')
|
|
node_elem.style = "background-image: url('../media/atree/node.png'); background-size: cover; width: 100%; height: 100%;";
|
|
|
|
// add tooltip
|
|
node_elem.addEventListener('mouseover', function(e) {
|
|
if (e.target !== this) {return;}
|
|
let tooltip = this.children[0];
|
|
tooltip.style.top = this.getBoundingClientRect().bottom + window.scrollY * 1.02 + "px";
|
|
tooltip.style.left = this.parentElement.parentElement.getBoundingClientRect().left + (elem.getBoundingClientRect().width * .2 / 2) + "px";
|
|
tooltip.style.display = "block";
|
|
});
|
|
|
|
node_elem.addEventListener('mouseout', function(e) {
|
|
if (e.target !== this) {return;}
|
|
let tooltip = this.children[0];
|
|
tooltip.style.display = "none";
|
|
});
|
|
|
|
node_elem.classList.add("fake-button");
|
|
|
|
let active_tooltip = document.createElement('div');
|
|
active_tooltip.classList.add("rounded-bottom", "dark-7", "border", "mb-2", "mx-auto");
|
|
//was causing active element boxes to be 0 width
|
|
// active_tooltip.style.width = elem.getBoundingClientRect().width * .80 + "px";
|
|
active_tooltip.style.display = "none";
|
|
|
|
// tooltip text formatting
|
|
|
|
let active_tooltip_title = document.createElement('b');
|
|
active_tooltip_title.classList.add("scaled-font");
|
|
active_tooltip_title.innerHTML = node.display_name;
|
|
|
|
let active_tooltip_text = document.createElement('p');
|
|
active_tooltip_text.classList.add("scaled-font-sm");
|
|
active_tooltip_text.textContent = node.desc;
|
|
|
|
active_tooltip.appendChild(active_tooltip_title);
|
|
active_tooltip.appendChild(active_tooltip_text);
|
|
|
|
node_tooltip = active_tooltip.cloneNode(true);
|
|
|
|
active_tooltip.id = "atree-ab-" + node.display_name.replaceAll(" ", "");
|
|
|
|
node_tooltip.style.position = "absolute";
|
|
node_tooltip.style.zIndex = "100";
|
|
|
|
node_elem.appendChild(node_tooltip);
|
|
document.getElementById("atree-active").appendChild(active_tooltip);
|
|
|
|
node_elem.addEventListener('click', function(e) {
|
|
if (e.target !== this) {return;}
|
|
let tooltip = document.getElementById("atree-ab-" + node.display_name.replaceAll(" ", ""));
|
|
if (tooltip.style.display == "block") {
|
|
tooltip.style.display = "none";
|
|
this.classList.remove("atree-selected");
|
|
this.style.backgroundImage = 'url("../media/atree/node.png")';
|
|
}
|
|
else {
|
|
tooltip.style.display = "block";
|
|
this.classList.add("atree-selected");
|
|
this.style.backgroundImage = 'url("../media/atree/node-selected.png")';
|
|
}
|
|
});
|
|
document.getElementById("atree-row-" + node.display.row).children[node.display.col].appendChild(node_elem);
|
|
};
|
|
|
|
atree_render_connection();
|
|
};
|
|
|
|
// resolve connector conflict
|
|
function resolve_connector(pos, node) {
|
|
if (atree_connectors_map.get(pos).length < 2) {return false;}
|
|
|
|
let line = false;
|
|
let angle = false;
|
|
let t = false;
|
|
for (let i of atree_connectors_map.get(pos)) {
|
|
if (i.type == "line") {
|
|
line += true;
|
|
} else if (i.type == "angle") {
|
|
angle += true;
|
|
} else if (i.type == "t") {
|
|
t += true;
|
|
}
|
|
}
|
|
|
|
let connect_elem = document.createElement("div");
|
|
|
|
if ((line && angle)) {
|
|
connect_elem.style = "background-image: url('../media/atree/connect_t.png'); background-size: cover; width: 100%; height: 100%;"
|
|
connect_elem.classList.add("rotate-180")
|
|
atree_connectors_map.set(pos, [{connector: connect_elem, type: "t"}])
|
|
}
|
|
if (node.parents.length == 3 && t && atree_same_row(node)) {
|
|
connect_elem.style = "background-image: url('../media/atree/connect_c.png'); background-size: cover; width: 100%; height: 100%;"
|
|
atree_connectors_map.set(pos, [{connector: connect_elem, type: "c"}])
|
|
}
|
|
// override the conflict with the first children
|
|
atree_connectors_map.set(pos, [atree_connectors_map.get(pos)[0]])
|
|
}
|
|
|
|
// check if a node doesn't have same row w/ its parents (used to solve conflict)
|
|
function atree_same_row(node) {
|
|
for (let i of node.parents) {
|
|
if (node.display.row == atree_map.get(i).display.row) { return false; }
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// draw the connector onto the screen
|
|
function atree_render_connection() {
|
|
for (let i of atree_connectors_map.keys()) {
|
|
if (atree_connectors_map.get(i).length != 0) {
|
|
document.getElementById("atree-row-" + i.split(",")[0]).children[i.split(",")[1]].appendChild(atree_connectors_map.get(i)[0].connector)
|
|
}
|
|
}
|
|
}
|