Skip to content
Snippets Groups Projects
Commit 9ace95e6 authored by Matthias Konitzny's avatar Matthias Konitzny :fire:
Browse files

More refactoring on the overlays.

Beginning to write code comments.
parent 84a7c71b
No related branches found
No related tags found
No related merge requests found
import * as Config from "../config"; import * as Config from "../config";
import * as Helpers from "./helpers"; import * as Helpers from "./helpers";
import { InfoOverlay } from "./infooverlay"; import { NodeInfoOverlay } from "./overlays/nodeinfo";
import { LinkOverlay } from "./linkoverlay"; import { LinkSelectionOverlay } from "./overlays/linkselection";
import * as THREE from "three"; import * as THREE from "three";
import ForceGraph3D from "3d-force-graph"; import ForceGraph3D from "3d-force-graph";
...@@ -357,6 +357,6 @@ function createFullScreenButton() { ...@@ -357,6 +357,6 @@ function createFullScreenButton() {
const dataUrl = Config.PLUGIN_PATH + "datasets/aud1.json"; const dataUrl = Config.PLUGIN_PATH + "datasets/aud1.json";
const G = new Graph(dataUrl); const G = new Graph(dataUrl);
const linkoverlay = new LinkOverlay(G); const linkoverlay = new LinkSelectionOverlay(G);
const infooverlay = new InfoOverlay(G); const infooverlay = new NodeInfoOverlay(G);
G.infooverlay = infooverlay; G.infooverlay = infooverlay;
export { getWidth, getHeight, getCanvasDivNode }; export { getWidth, getHeight, getCanvasDivNode, createDiv };
function getWidth() { function getWidth() {
return document.getElementById("3d-graph").offsetWidth; return document.getElementById("3d-graph").offsetWidth;
...@@ -12,3 +12,12 @@ function getCanvasDivNode() { ...@@ -12,3 +12,12 @@ function getCanvasDivNode() {
const domNode = document.getElementById("3d-graph"); const domNode = document.getElementById("3d-graph");
return domNode.firstChild.firstChild.firstChild; return domNode.firstChild.firstChild.firstChild;
} }
function createDiv(className, parent) {
const node = document.createElement("div");
node.className = className;
if (typeof parent !== "undefined") {
parent.appendChild(node);
}
return node;
}
import * as Helpers from "./helpers"; import * as Helpers from "../helpers";
import jQuery from "jquery"; import jQuery from "jquery";
export { LinkOverlay }; export { LinkSelectionOverlay };
class LinkOverlay { /**
* Represents an overlay showing the meaning of different edge colors.
* Offers the ability to toggle certain edge types.
*/
class LinkSelectionOverlay {
/**
* Creates the link overlay for a given graph object.
* @param {Graph} graph The graph object.
*/
constructor(graph) { constructor(graph) {
this.graph = graph; this.graph = graph;
} }
/**
* Creates the overlay based on the edges and nodes of the graph object.
* Must be called after the graph has been initialized.
*/
create() { create() {
const sceneNode = Helpers.getCanvasDivNode(); const sceneNode = Helpers.getCanvasDivNode();
const overlayNode = document.createElement("div"); const overlayNode = document.createElement("div");
...@@ -39,6 +51,11 @@ class LinkOverlay { ...@@ -39,6 +51,11 @@ class LinkOverlay {
} }
} }
/**
* Event handler for the click event of the link type divs.
* Toggles the visibility of certain edge types.
* @param {MouseEvent} event
*/
toggleLinkVisibility(event) { toggleLinkVisibility(event) {
const target = event.currentTarget; const target = event.currentTarget;
this.graph.toggleLinkVisibility(target.edgeType); this.graph.toggleLinkVisibility(target.edgeType);
......
import * as Helpers from "../helpers";
import jQuery from "jquery";
import * as Config from "../../config";
export { NodeNeighborOverlay };
class NodeNeighborOverlay {
constructor(graph, parentNode, infoOverlay) {
this.graph = graph;
this.parentNode = parentNode;
this.infoOverlay = infoOverlay;
this.activeTabNav = null;
this.activeTabContent = null;
this.tabContentPages = {};
}
create() {
const bottomContainerDiv = Helpers.createDiv(
"bottom-container",
this.parentNode
);
const bottomContainerNavDiv = Helpers.createDiv(
"bottom-container-nav",
bottomContainerDiv
);
const bottomContainerLinkDiv = Helpers.createDiv(
"bottom-container-links",
bottomContainerDiv
);
for (const [cls, color] of Object.entries(this.graph.edgeColors)) {
const navTab = Helpers.createDiv(
"bottom-container-nav-tab",
bottomContainerNavDiv
);
navTab.innerText = cls.slice(0, 3);
navTab.style.backgroundColor = color;
navTab.edgeType = cls; // Attach the edge type to the DOM object to retrieve it during click events
jQuery(navTab).click((event) => this.openTab(event));
const tabContent = Helpers.createDiv(
"bottom-container-tab-content",
bottomContainerLinkDiv
);
tabContent.style.backgroundColor = color;
this.tabContentPages[cls] = tabContent;
}
this.initializeActive(bottomContainerNavDiv, bottomContainerLinkDiv);
}
/**
* Initializes the activeTabNav and activeTabContent variables to a random edge type.
* @param {Element} bottomContainerNavDiv
* @param {Element} bottomContainerLinkDiv
*/
initializeActive(bottomContainerNavDiv, bottomContainerLinkDiv) {
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;
}
/**
* Click event handler for the tab headers of the bottom menu.
* @param event
*/
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];
}
clearTabContentPages() {
for (const page of Object.values(this.tabContentPages)) {
jQuery(page).empty();
}
}
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);
}
jQuery(linkDiv).on("click", () => {
this.graph.focusOnNode(target);
this.infoOverlay.updateInfoOverlay(target);
});
return linkDiv;
}
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);
}
}
}
import * as Helpers from "./helpers";
import jQuery from "jquery"; import jQuery from "jquery";
import * as Config from "../config";
export { InfoOverlay }; import { NodeNeighborOverlay } from "./neighbors";
import * as Helpers from "../helpers";
import * as Config from "../../config";
class InfoOverlay { export { NodeInfoOverlay };
/**
* An overlay displaying the information which is connected with each node.
*/
class NodeInfoOverlay {
/**
* Constructs a new info overlay for the given graph object.
* @param {Graph} graph
*/
constructor(graph) { constructor(graph) {
this.graph = graph; this.graph = graph;
this.bottomMenu = null;
this.activeTabNav = null;
this.activeTabContent = null;
this.tabContentPages = {};
} }
/**
* Creates the visible elements of the overlay.
* Must be called after the graph has been initialized.
*/
create() { create() {
const overlayDiv = this.createOverlayMainDiv(); const overlayDiv = this.createOverlayMainDiv();
this.createOverlayElements(overlayDiv); this.createOverlayElements(overlayDiv);
this.createBottomMenu(overlayDiv); this.bottomMenu = new NodeNeighborOverlay(this.graph, overlayDiv, this);
this.bottomMenu.create();
jQuery("#infoOverlayCloseButton").click(function () { jQuery("#infoOverlayCloseButton").click(function () {
jQuery("#infoOverlay").slideUp("fast"); 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);
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;
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() { createOverlayMainDiv() {
const sceneNode = Helpers.getCanvasDivNode(); const sceneNode = Helpers.getCanvasDivNode();
const overlayNode = document.createElement("div"); const overlayNode = document.createElement("div");
overlayNode.id = "infoOverlay"; overlayNode.id = "infoOverlay";
overlayNode.className = "detail-view"; overlayNode.className = "detail-view";
//overlayNode.innerText = 'Hello there!';
sceneNode.insertBefore(overlayNode, sceneNode.childNodes[2]); sceneNode.insertBefore(overlayNode, sceneNode.childNodes[2]);
return overlayNode; return overlayNode;
} }
...@@ -146,42 +101,7 @@ class InfoOverlay { ...@@ -146,42 +101,7 @@ class InfoOverlay {
jQuery("#infoOverlayDescription").text("Default Text"); jQuery("#infoOverlayDescription").text("Default Text");
} }
this.updateTabs(node); this.bottomMenu.updateTabs(node);
jQuery("#infoOverlay").slideDown("fast"); jQuery("#infoOverlay").slideDown("fast");
} }
clearTabContentPages() {
for (const page of Object.values(this.tabContentPages)) {
jQuery(page).empty();
}
}
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);
}
jQuery(linkDiv).on("click", () => {
this.graph.focusOnNode(target);
this.updateInfoOverlay(target);
});
return linkDiv;
}
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);
}
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment