From 9ef90cb862988c12961b740c8eaceed93cdb4830 Mon Sep 17 00:00:00 2001 From: Matthias Konitzny <konitzny@ibr.cs.tu-bs.de> Date: Thu, 10 Jun 2021 17:25:30 +0200 Subject: [PATCH] Added node highlights and focus on node functions. --- graph.js | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) diff --git a/graph.js b/graph.js index 393aeb1..0d4ffac 100644 --- a/graph.js +++ b/graph.js @@ -1,5 +1,94 @@ +const highlightNodes = new Set(); +const highlightLinks = new Set(); +let firstHover = true; +let hoverNode = null; + const Graph = ForceGraph3D() (document.getElementById('3d-graph')) .jsonUrl(dataset) .nodeLabel('id') - .nodeAutoColorBy('group'); \ No newline at end of file + .nodeAutoColorBy('group') + .nodeColor(node => highlightNodes.has(node) ? node === hoverNode ? 'rgb(255,0,0,1)' : 'rgba(255,160,0,0.8)' : 'rgba(0,255,255,0.6)') + .linkWidth(link => highlightLinks.has(link) ? 4 : 1) + .onNodeClick(focusOnNode) + .onNodeHover(nodeHover) + .onLinkHover(linkHover); + + +function updateLinks() { + gData = Graph.graphData(); + // cross-link node objects + gData.links.forEach(link => { + const a = link.source; + const b = link.target; + if (!a.neighbors) a.neighbors = []; + if (!b.neighbors) b.neighbors = []; + a.neighbors.push(b); + b.neighbors.push(a); + + if (!a.links) a.links = []; + if (!b.links) b.links = []; + a.links.push(link); + b.links.push(link); + }); + Graph.graphData(gData) +} + + +function focusOnNode(node) { + // Aim at node from outside it + const distance = 250; + const distRatio = 1 + distance/Math.hypot(node.x, node.y, node.z); + + Graph.cameraPosition( + { x: node.x * distRatio, y: node.y * distRatio, z: node.z * distRatio }, // new position + node, // lookAt ({ x, y, z }) + 1000 // ms transition duration + ); +} + +function nodeHover(node) { + + // no state change + if ((!node && !highlightNodes.size) || (node && hoverNode === node)) return; + if (firstHover) { + updateLinks(); + firstHover = false; + } + + highlightNodes.clear(); + highlightLinks.clear(); + if (node) { + highlightNodes.add(node); + node.neighbors.forEach(neighbor => highlightNodes.add(neighbor)); + node.links.forEach(link => highlightLinks.add(link)); + } + + hoverNode = node || null; + updateHighlight(); +} + +function linkHover(link) { + highlightNodes.clear(); + highlightLinks.clear(); + + if (link) { + highlightLinks.add(link); + highlightNodes.add(link.source); + highlightNodes.add(link.target); + } + + updateHighlight(); +} + +function updateHighlight() { + // trigger update of highlighted objects in scene + Graph + .nodeColor(Graph.nodeColor()) + .linkWidth(Graph.linkWidth()) + .linkDirectionalParticles(Graph.linkDirectionalParticles()); +} + + + + -- GitLab