import * as Helpers from "../helpers"; import jQuery from "jquery"; import * as Config from "../../config"; export { NodeNeighborOverlay }; /** * Displays an overlay showing the neighbors of a node divided by the link type * that connects them. */ class NodeNeighborOverlay { constructor(graph, parentNode, infoOverlay, type = "link") { this.graph = graph; this.parentNode = parentNode; this.infoOverlay = infoOverlay; this.type = type; this.activeTabNav = null; // The currently selected tab handle this.activeTabContent = null; // The currently selected tab content this.tabContentPages = {}; this.tabNavHandles = {}; } /** * Creates the visible elements of the overlay. * Must be called after the graph has been initialized. */ create() { const bottomContainerDiv = Helpers.createDiv( "bottom-container", this.parentNode ); const coll = Helpers.createDiv( "button", bottomContainerDiv ); coll.className = "collapsible"; coll.innerText = "Nachbarn"; // TODO: Scrolling wheel for content var contentTabs = Helpers.createDiv( "neighbor-content-tabs", bottomContainerDiv ); this.contentTab = contentTabs; coll.addEventListener("click", function() { if(contentTabs.style.display === "flex") { contentTabs.style.display = "none"; } else { contentTabs.style.display = "flex"; } }); const colors = this.type === "link" ? this.graph.edgeColors : this.graph.nodeColors; // TODO: Colors only fill little part of div for (const [cls, color] of Object.entries(colors)) { const collTab = Helpers.createDiv( "button", contentTabs ); collTab.className = "collapsible"; collTab.innerText = cls; collTab.style.backgroundColor = color; collTab.type = cls; this.tabNavHandles[cls] = collTab; const collTabContent = Helpers.createDiv( "neighbor-content-links", contentTabs ); this.tabContentPages[cls] = collTabContent; collTab.addEventListener("click", function() { if(collTabContent.style.display === "flex") { collTabContent.style.display = "none"; } else { collTabContent.style.display = "flex"; } }); } } /** * Clears the images from all tab content pages. */ clearTabContentPages() { for (const page of Object.values(this.tabContentPages)) { jQuery(page).empty(); if(page.style.display === "flex") { page.style.display = "none"; } } } /** * Creates a new image (with link) for the given target node. * @param target * @returns {HTMLDivElement} */ createReference(target) { const linkDiv = document.createElement("div"); linkDiv.className = "link-img"; if ("image" in target) { const linkImage = document.createElement("img"); linkImage.src = Config.PLUGIN_PATH + "datasets/images/" + target.image; linkDiv.appendChild(linkImage); } if ("name" in target) { Helpers.createHTMLElement("p", linkDiv, { className: "bottom-container-link-text", innerText: target.name, }); } jQuery(linkDiv).on("click", () => { this.graph.focusOnNode(target); this.infoOverlay.updateInfoOverlay(target); }); return linkDiv; } /** * Updates all tabs to have content matching the given node. * @param node */ updateTabs(node) { //TODO: Hide all categories that do not have any links this.clearTabContentPages(); if(this.contentTab.style.display === "flex") { this.contentTab.style.display = "none"; } for (const link of node.links) { const target = link.source == node ? link.target : link.source; const reference = this.createReference(target); if (this.type === "link") { this.tabContentPages[link.type].appendChild(reference); } else { this.tabContentPages[target.type].appendChild(reference); } } } }