diff --git a/display/infooverlay.js b/display/infooverlay.js index edb8c9a15d95b92bb08f2498b253d3cc933eb2f9..2fa4f2083c563a5ae05cf85c1701bb70f219cd3c 100644 --- a/display/infooverlay.js +++ b/display/infooverlay.js @@ -3,16 +3,95 @@ class InfoOverlay { constructor(graph) { this.graph = graph; + + this.activeTabNav = null; + this.activeTabContent = null; + + this.tabContentPages = {}; } create() { + const overlayDiv = this.createOverlayMainDiv(); + this.createOverlayElements(overlayDiv); + this.createBottomMenu(overlayDiv) + + jQuery('#infoOverlayCloseButton').click(function () { + jQuery('#infoOverlay').slideUp('fast'); + }); + + } + + createBottomMenu(overlayNode) { + + const bottomContainerDiv = document.createElement('div'); + bottomContainerDiv.className = 'bottom-container'; + overlayNode.appendChild(bottomContainerDiv); + + const bottomContainerNavDiv = document.createElement('div'); + bottomContainerNavDiv.className = 'bottom-container-nav'; + bottomContainerDiv.appendChild(bottomContainerNavDiv); + + const bottomContainerLinkDiv = document.createElement('div'); + bottomContainerLinkDiv.className = 'bottom-container-links'; + bottomContainerDiv.appendChild(bottomContainerLinkDiv); + + //const linkClasses = this.graph.getLinkClasses(); + + for(const [cls, color] of Object.entries(this.graph.edgeColors)) { + + const navTab = document.createElement('div'); + navTab.className = 'bottom-container-nav-tab'; + navTab.innerText = cls.slice(0, 3); + navTab.style = "background-color: " + color; + navTab.edgeType = cls; + //tablink.setAttribute("onclick", "openTab(event, " + linkType + "_id)"); //unusual function call + bottomContainerNavDiv.appendChild(navTab); + jQuery(navTab).click(event => this.openTab(event)) + + const tabContent = document.createElement('div'); + tabContent.className = "bottom-container-tab-content"; + tabContent.id = cls + "_id_content"; + tabContent.style = "background-color: " + color; + bottomContainerLinkDiv.appendChild(tabContent); + this.tabContentPages[cls] = tabContent; + } + + this.activeTabNav = bottomContainerNavDiv.firstChild; + this.activeTabContent = bottomContainerLinkDiv.firstChild; + + this.activeTabContent.classList.add("active-tab-content"); + this.activeTabNav.classList.add("active-tab-nav"); + this.activeTabNav.innerText = this.activeTabNav.edgeType; + + } + + openTab(event) { + const navTab = event.target; + const cls = navTab.edgeType; + + this.activeTabNav.classList.remove("active-tab-nav"); + this.activeTabNav.innerText = this.activeTabNav.innerText.slice(0, 3); + navTab.classList.add("active-tab-nav"); + navTab.innerText = cls; + + this.activeTabContent.classList.remove("active-tab-content"); + this.tabContentPages[cls].classList.add("active-tab-content"); + + this.activeTabNav = navTab; + this.activeTabContent = this.tabContentPages[cls]; + } + + createOverlayMainDiv() { const sceneNode = getCanvasDivNode(); const overlayNode = document.createElement('div'); overlayNode.id = 'infoOverlay' overlayNode.className = 'detail-view'; //overlayNode.innerText = 'Hello there!'; sceneNode.insertBefore(overlayNode, sceneNode.childNodes[2]); + return overlayNode; + } + createOverlayElements(overlayNode) { const close = document.createElement('div'); close.innerHTML = '<p>✖</p>'; close.id = 'infoOverlayCloseButton'; @@ -44,50 +123,6 @@ class InfoOverlay { description.innerText = 'Default Text' description.setAttribute("overflow-y", "scroll"); textArea.appendChild(description); - - const link_container = document.createElement('div'); - const links = document.createElement('div'); - const linkClasses = G.getLinkClasses(); - - link_container.id = 'link_container'; - link_container.className = 'bottom container'; - links.className = 'tab'; - links.id = 'links'; - - for(let i = 0; i < linkClasses.length; i++){ - - const linkType = linkClasses[i]; - const tablink = document.createElement('button'); - tablink.className = 'tablinks'; - tablink.id = linkType + "_id"; - tablink.innerHTML = linkType[0] + linkType[1] + linkType[2]; - tablink.style = "background-color: " + this.graph.edgeColors[linkClasses[i]]; - tablink.setAttribute("onclick", "openTab(event, " + linkType + "_id)"); //unusual function call - links.appendChild(tablink); - - } - - link_container.appendChild(links); - - for(let i = 0; i < linkClasses.length; i++){ - - const linkType = linkClasses[i]; - const tabcontent = document.createElement('div'); - tabcontent.className = "tabcontent"; - tabcontent.id = linkType + "_id_content"; - tabcontent.style = "background-color: " + this.graph.edgeColors[linkClasses[i]]; - link_container.appendChild(tabcontent); - - } - - overlayNode.appendChild(link_container); - - jQuery('#infoOverlayCloseButton').click(function () { - jQuery('#infoOverlay').slideUp('fast'); - }); - - //sceneNode.appendChild(overlayNode); - } updateInfoOverlay(node) { @@ -109,74 +144,37 @@ class InfoOverlay { jQuery('#infoOverlay').slideDown('fast'); } - updateTabs(node){ - //tabs of the links to other nodes: - //delete old nodes from tabcontent - const tabcontent = document.getElementsByClassName("tabcontent"); - for (let i = 0; i < tabcontent.length; i++) { - while (tabcontent[i].firstChild){ - tabcontent[i].removeChild(tabcontent[i].lastChild); - } - } - //add new nodes to tabcontent - for (let i = 0; i < tabcontent.length; i++) { //for every type of link - node.links.forEach(link => { //and for every link - if(link.type + '_id_content' == tabcontent[i].id){ //is checked if the type is equal - const linkButton = document.createElement('div'); //and if so a new element is created - linkButton.className = "link img"; - var node2; - if(link.source == node){ - node2 = link.target; - } - else if(link.target == node){ - node2 = link.source; - } - linkButton.id = "linkButton_" + node2.id; - const nodeID = node2.id; - - const linkImage = document.createElement('img'); - const linkTitle = document.createElement('div'); - - if ('image' in node2) { - linkImage.src = plugin_path + 'datasets/images/' + node2.image; - } else if(!('image' in node2) && ('id' in node2)) { - linkImage.src = plugin_path + 'datasets/images/default.jpg'; - } - - linkTitle.className = "link title"; - linkTitle.innerHTML = node2.name; - - //linkButton.appendChild(linkTitle); - linkButton.appendChild(linkImage); - - jQuery(linkButton).on('click', () => this.graph.focusOnNode(nodeID)); - tabcontent[i].appendChild(linkButton); - } - }); + clearTabContentPages() { + for (const page of Object.values(this.tabContentPages)) { + jQuery(page).empty(); } } + createReference(target) { + const linkDiv = document.createElement('div'); //and if so a new element is created + linkDiv.className = "link-img"; + if ('image' in target) { + const linkImage = document.createElement('img'); + linkImage.src = plugin_path + 'datasets/images/' + target.image; + linkDiv.appendChild(linkImage); + } -} - -//is used in createInfoOverlay, as an unusual function call to open link-tabs -function openTab (event, tab) { - var i, tabcontent, tablinks; - - // Get all elements with class="tabcontent" and hide them - tabcontent = document.getElementsByClassName("tabcontent"); - for (i = 0; i < tabcontent.length; i++) { - tabcontent[i].style.display = "none"; + jQuery(linkDiv).on('click', () => { + this.graph.focusOnNode(target); + this.updateInfoOverlay(target); + }); + return linkDiv; } - // Get all elements with class="tablinks" and remove the class "active" - tablinks = document.getElementsByClassName("tablinks"); - for (i = 0; i < tablinks.length; i++) { - tablinks[i].className = tablinks[i].className.replace(" active", ""); + updateTabs(node){ + this.clearTabContentPages(); + + for (const link of node.links) { + const target = link.source == node ? link.target : link.source; + const reference = this.createReference(target); + this.tabContentPages[link.type].appendChild(reference); + } } - // Show the current tab, and add an "active" class to the button that opened the tab - document.getElementById(tab.id + "_content").style.display = "flex"; - event.currentTarget.className += " active"; } \ No newline at end of file diff --git a/kg-style.css b/kg-style.css index 80b1f3901522741e392b3dc6acf72ef57d16c597..1a04640c6445ad9004c931a2bd70f3f182b00c81 100644 --- a/kg-style.css +++ b/kg-style.css @@ -24,7 +24,6 @@ font-size: 20px; } - .detail-view { position: absolute; top: 0; @@ -103,59 +102,68 @@ width: 78px; } -.tab { - overflow: hidden; - width: 200px; - background-color: #f1f1f1; -} -.tab button { - color: white; - float: left; - border: none; - outline: none; - cursor: pointer; - width: 50px; - padding: 10px 12px; - transition: 0.3s; -} -.tab button:hover { - background-color: #ddd; +.bottom-container-tab-content { + display: none; + /*padding: 6px 0px;*/ + /*border-top: none;*/ + overflow-x: auto; + /*height: 100px;*/ + height: 100%; + width: 100%; } -.tab button.active { - background-color: #ccc; + +.active-tab-nav { + color: black; + font-weight: bold; } -.tabcontent { - display: none; - padding: 6px 0px; - border-top: none; - overflow-x: scroll; - height: 100px; - width: 200px; + +.active-tab-content { + display: flex; + align-items: center; } -.bottom container { + +.bottom-container { position: absolute; bottom: 0; left: 0; - width: 200px; - padding: 0px; - margin: 0px; + width: 100%; } -.link img { - position: relative; - text-align: center; - min-width: 60px; - width: 60px; - height: 60px; - margin-left: 5px; +.bottom-container-nav { + height: 35px; + width: 100%; + top: 0; + display: flex; + flex-direction: row; + cursor: pointer; +} + +.bottom-container-links { + width: 100%; + height: 92px; + display: block; +} + + +.link-img { + min-width: 70px; + width: 70px; + height: 70px; + margin: 10px; pointer-events: all; cursor: pointer; border-radius: 50%; + overflow: hidden; + background-color: white; + display: flex; + align-items: center; +} + +.bottom-container-nav-tab { + height: 100%; + display: flex; + padding: 0 8px; + min-width: 10%; + text-align: center; + line-height: 35px; } -.link title { - font-size: 2px; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); -} \ No newline at end of file