diff --git a/config.js b/config.js index 42eee97a7f5390092fdd61e147edd9259bba4693..9a3a271b3e050119baa7e782f8ecb26ab8fd0315 100644 --- a/config.js +++ b/config.js @@ -10,6 +10,9 @@ export const COLOR_PALETTE = [ "rgb(255, 255, 255)", ]; +export const LINK_WIDTH = 3; +export const HOVER_LINK_WIDTH = 6; + // Just renaming a variable which is given by the PHP script. This avoids errors in all other files. export const PLUGIN_PATH = ks_global.plugin_path; export var SPACE = ks_global.space_id; diff --git a/display/graph.js b/display/graph.js index 97648bb164c6b856f6d39a8942c40c3d2ece4921..b4938c82b1ec9c2c4d26d8c38c29de35bdc93bb4 100644 --- a/display/graph.js +++ b/display/graph.js @@ -52,15 +52,16 @@ export default class Graph { */ async loadGraph(spaceId) { this.gData = await loadGraphJson(spaceId); + this.graph = ForceGraph3D({ extraRenderers: [new CSS3DRenderer()], rendererConfig: { antialias: true }, })(document.getElementById("3d-graph")) .graphData(this.gData) .nodeLabel("hidden") // Just a value that is not present as node attribute. - .nodeAutoColorBy("group") - .nodeColor((node) => this.getNodeColor(node)) - .linkWidth((link) => this.getLinkWidth(link)) + //.nodeAutoColorBy("group") + //.nodeColor((node) => this.getNodeColor(node)) + //.linkWidth((link) => this.getLinkWidth(link)) .onNodeClick((node) => { this.focusOnNode(node); if (MODE === "default") { @@ -71,14 +72,17 @@ export default class Graph { this.onNodeHover(node); this.updateHighlight(); }) - .onLinkHover((link) => this.onLinkHover(link)) + .onLinkHover((link, previousLink) => + this.onLinkHover(link, previousLink) + ) //.linkColor((link) => this.getLinkColor(link)) .linkPositionUpdate((line, { start, end }) => this.updateLinkPosition(line, start, end) ) - .linkOpacity(0.8) + //.linkOpacity(0.8) .nodeThreeObjectExtend(false) .nodeThreeObject((node) => this.drawNode(node)) + //.linkThreeObject((link) => this.drawLink(link)) .onEngineTick(() => this.initializeModel()) .width(Helpers.getWidth()) .height(Helpers.getHeight()); @@ -183,11 +187,17 @@ export default class Graph { this.hoverNode = node || null; } - onLinkHover(link) { + onLinkHover(link, previousLink) { this.highlightNodes.clear(); this.highlightLinks.clear(); + if (previousLink) { + // A bit hacky, but the alternative would require additional data structures + previousLink.__lineObj.material.linewidth = Config.LINK_WIDTH; + } if (link) { + link.__lineObj.material.linewidth = Config.HOVER_LINK_WIDTH; + this.highlightLinks.add(link); this.highlightNodes.add(link.source); this.highlightNodes.add(link.target); @@ -329,10 +339,10 @@ export default class Graph { updateHighlight() { // trigger update of highlighted objects in scene - this.graph - .nodeColor(this.graph.nodeColor()) - .linkWidth(this.graph.linkWidth()) - .linkDirectionalParticles(this.graph.linkDirectionalParticles()); + // this.graph + // .nodeColor(this.graph.nodeColor()) + // .linkWidth(this.graph.linkWidth()) + // .linkDirectionalParticles(this.graph.linkDirectionalParticles()); } updateNodeMap() { @@ -403,26 +413,19 @@ export default class Graph { geometry.setPositions([0, 0, 0, 1, 1, 1]); geometry.setColors(colors); - // const material = new THREE.LineBasicMaterial({ - // vertexColors: THREE.VertexColors, - // }); - const material = new LineMaterial({ color: 0xffffff, - linewidth: 3, // in world units with size attenuation, pixels otherwise + linewidth: Config.LINK_WIDTH, // in world units with size attenuation, pixels otherwise vertexColors: true, - resolution: new THREE.Vector2(1920, 1080), // to be set by renderer, eventually + resolution: new THREE.Vector2( + window.screen.width, + window.screen.height + ), // Set the resolution to the maximum width and height of the screen. dashed: false, alphaToCoverage: true, }); - // const geometry = new THREE.BufferGeometry(); - // geometry.setAttribute( - // "position", - // new THREE.BufferAttribute(new Float32Array(2 * 3), 3) - // ); - // geometry.setAttribute("color", new THREE.BufferAttribute(colors, 3)); const line = new Line2(geometry, material); line.computeLineDistances(); line.scale.set(1, 1, 1); @@ -436,17 +439,13 @@ export default class Graph { const startR = 4; const endR = 4; - // const startR = Graph.nodeRelSize(); - // const endR = Graph.nodeRelSize(); const lineLen = Math.sqrt( ["x", "y", "z"] .map((dim) => Math.pow((end[dim] || 0) - (start[dim] || 0), 2)) .reduce((acc, v) => acc + v, 0) ); - //const linePos = line.geometry.getAttribute("position"); - - const test = [startR / lineLen, 1 - endR / lineLen] + const positions = [startR / lineLen, 1 - endR / lineLen] .map((t) => ["x", "y", "z"].map( (dim) => start[dim] + (end[dim] - start[dim]) * t @@ -454,32 +453,10 @@ export default class Graph { ) .flat(); - // start = line.geometry.getAttribute("instanceStart"); - // end = line.geometry.getAttribute("instanceEnd"); - // - // start.setXYZ(0, ...test[0]); - // start.needsUpdate = true; - // end.setXYZ(1, ...test[1]); - // end.needsUpdate = true; - // line.geometry.attributes.position.needsUpdate = true; - // line.geometry.computeBoundingBox(); - // line.geometry.computeBoundingSphere(); - - line.geometry.setPositions(test); // This seems to cause memory leaks :( - line.geometry.getAttribute("position").needsUpdate = true; - line.computeLineDistances(); + line.geometry.setPositions(positions); + //line.geometry.getAttribute("position").needsUpdate = true; + //line.computeLineDistances(); - // calculate coordinate on the node's surface instead of center - // linePos.set( - // [startR / lineLen, 1 - endR / lineLen] - // .map((t) => - // ["x", "y", "z"].map( - // (dim) => start[dim] + (end[dim] - start[dim]) * t - // ) - // ) - // .flat() - // ); - // linePos.needsUpdate = true; return true; }