diff --git a/display/graph.js b/display/graph.js index f10a9bae1c1eaba3177f659b24970a28ca1d89bb..b36a0371446a1b89821c4267fd1e2a123a433075 100644 --- a/display/graph.js +++ b/display/graph.js @@ -12,7 +12,14 @@ import { CSS3DSprite, } from "three/examples/jsm/renderers/CSS3DRenderer.js"; +/** + * The main ForceGraph. Displays the graph and handles all connected events. + */ class Graph { + /** + * Constructs a new Graph object. + * @param {string} dataUrl URL to a JSON object defining the graph structure. + */ constructor(dataUrl) { this.graph = null; this.gData = null; @@ -31,6 +38,12 @@ class Graph { this.loadGraph(dataUrl); } + /** + * Loads the graph by constructing a new ForceGraph3D object. + * Also fetches the JSON data from the given URL. + * @param {string} dataUrl URL to a JSON object defining the graph structure. + * @returns {Promise<void>} + */ async loadGraph(dataUrl) { this.gData = await fetch(dataUrl).then((res) => res.json()); this.graph = ForceGraph3D({ @@ -59,6 +72,10 @@ class Graph { .height(Helpers.getHeight()); } + /** + * Initializes all component which are dependent on the graph data after the graph has finished loading + * (after it has computed its first tick.) + */ initializeModel() { if (this.firstTick) { this.mapEdgeColors(); @@ -79,6 +96,11 @@ class Graph { } } + /** + * Returns the color of the given node as a string in the HTML rgb() format. + * @param node + * @returns {string} HTML rgb() string. + */ getNodeColor(node) { return this.highlightNodes.has(node) ? node === this.hoverNode @@ -98,6 +120,10 @@ class Graph { return this.highlightLinks.has(link) ? 2 : 0.8; } + /** + * Returns an array containing the different edge types of the graph. + * @returns {*[]} + */ getLinkClasses() { const linkClasses = []; this.graph @@ -202,6 +228,10 @@ class Graph { this.graph.graphData(data); } + /** + * Resets additional node values. + * @see updateNodeData + */ resetNodeData() { const gData = this.graph.graphData(); for (const node of gData.nodes) { @@ -210,6 +240,10 @@ class Graph { } } + /** + * Updates the graph data structure to contain additional values. + * Creates a 'neighbors' and 'links' array for each node object. + */ updateNodeData() { const gData = this.graph.graphData(); // cross-link node objects @@ -269,6 +303,9 @@ class Graph { this.graph.scene().add(mesh); } + /** + * Maps the colors of the color palette to the different edge types + */ mapEdgeColors() { const linkClasses = this.getLinkClasses(); for (let i = 0; i < linkClasses.length; i++) { diff --git a/display/helpers.js b/display/helpers.js index 459ec16c1de10c34f033023ac204c55fcb830b22..68684d34a0e7ebb413afcce6e899f2ed41adf962 100644 --- a/display/helpers.js +++ b/display/helpers.js @@ -1,18 +1,36 @@ export { getWidth, getHeight, getCanvasDivNode, createDiv }; +/** + * Returns the maximum width that should be used if displaying elements inside of wordpress. + * @returns {number} + */ function getWidth() { return document.getElementById("3d-graph").offsetWidth; } +/** + * Returns the maximum height that should be used if displaying elements inside of wordpress. + * @returns {number} + */ function getHeight() { return window.innerHeight - 200; } +/** + * Returns the div node which encapsulates the canvas the 3d-force-graph is drawn on. + * @returns {ChildNode} + */ function getCanvasDivNode() { const domNode = document.getElementById("3d-graph"); return domNode.firstChild.firstChild.firstChild; } +/** + * Creates a new div element. + * @param {string} className Class name of the new div element. + * @param {HTMLDivElement} parent Optional parent element of the new div. + * @returns {HTMLDivElement} The new div element. + */ function createDiv(className, parent) { const node = document.createElement("div"); node.className = className; diff --git a/display/overlays/neighbors.js b/display/overlays/neighbors.js index 0499788da39242a48615b352164aa22e576c1fdd..d7b253f971ffd0e6c3aa48f2b1acc08f9b710d37 100644 --- a/display/overlays/neighbors.js +++ b/display/overlays/neighbors.js @@ -4,18 +4,26 @@ 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) { this.graph = graph; this.parentNode = parentNode; this.infoOverlay = infoOverlay; - this.activeTabNav = null; - this.activeTabContent = null; + this.activeTabNav = null; // The currently selected tab handle + this.activeTabContent = null; // The currently selected tab content this.tabContentPages = {}; } + /** + * Creates the visible elements of the overlay. + * Must be called after the graph has been initialized. + */ create() { const bottomContainerDiv = Helpers.createDiv( "bottom-container", @@ -84,12 +92,20 @@ class NodeNeighborOverlay { this.activeTabContent = this.tabContentPages[cls]; } + /** + * Clears the images from all tab content pages. + */ clearTabContentPages() { for (const page of Object.values(this.tabContentPages)) { jQuery(page).empty(); } } + /** + * 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"; @@ -108,6 +124,10 @@ class NodeNeighborOverlay { return linkDiv; } + /** + * Updates all tabs to have content matching the given node. + * @param node + */ updateTabs(node) { this.clearTabContentPages(); diff --git a/display/overlays/nodeinfo.js b/display/overlays/nodeinfo.js index 18bd6791844329c3f8e6a490bd1008ecd38b94fa..c6f1f21655053eec129b66d3e7d50524ff3250ea 100644 --- a/display/overlays/nodeinfo.js +++ b/display/overlays/nodeinfo.js @@ -81,6 +81,10 @@ class NodeInfoOverlay { textArea.appendChild(description); } + /** + * Updates the overlay (and its children) to display information on the given node. + * @param node + */ updateInfoOverlay(node) { jQuery("#infoOverlayHeadline").text(node.name); if ("image" in node) {