diff --git a/config.js b/config.js index 42eee97a7f5390092fdd61e147edd9259bba4693..9ca8fa0c72a86654dcabf68e822b1220555ac147 100644 --- a/config.js +++ b/config.js @@ -18,3 +18,6 @@ export const MODE = ks_global.mode; export function setSpace(space) { SPACE = space; } + +export const DRAG_THRESHOLD_3D = 10; +export const DRAG_THRESHOLD_2D = 5; diff --git a/display/graph.js b/display/graph.js index c1c9b79743fc44da203ac73a825fddf0cf788199..c2a1eaffbc1a7882d23e093cb1356e5596e24eac 100644 --- a/display/graph.js +++ b/display/graph.js @@ -9,7 +9,7 @@ import { CSS3DRenderer, CSS3DSprite, } from "three/examples/jsm/renderers/CSS3DRenderer.js"; -import { MODE } from "../config"; +import { MODE, DRAG_THRESHOLD_3D } from "../config"; /** * The main ForceGraph. Displays the graph and handles all connected events. @@ -59,16 +59,12 @@ export default class Graph { .nodeAutoColorBy("group") .nodeColor((node) => this.getNodeColor(node)) .linkWidth((link) => this.getLinkWidth(link)) - .onNodeClick((node) => { - this.focusOnNode(node); - if (MODE === "default") { - this.infoOverlay.updateInfoOverlay(node); - } - }) + .onNodeClick((node) => this.onNodeClick(node)) .onNodeHover((node) => { this.onNodeHover(node); this.updateHighlight(); }) + .onNodeDragEnd((node, translate) => this.onNodeDragEnd(node, translate)) .onLinkHover((link) => this.onLinkHover(link)) //.linkColor((link) => this.getLinkColor(link)) .linkPositionUpdate((line, { start, end }) => @@ -80,6 +76,7 @@ export default class Graph { .onEngineTick(() => this.initializeModel()) .width(Helpers.getWidth()) .height(Helpers.getHeight()); + } /** @@ -194,6 +191,20 @@ export default class Graph { this.updateHighlight(); } + onNodeClick(node) { + this.focusOnNode(node); + if (MODE === "default") { + this.infoOverlay.updateInfoOverlay(node); + } + } + + onNodeDragEnd(node, translate) { + // NodeDrag is handled like NodeClick if distance is very short + if(Math.sqrt(Math.pow(translate.x, 2)+ Math.pow(translate.y, 2)+ Math.pow(translate.z, 2)) < DRAG_THRESHOLD_3D) { + this.onNodeClick(node); + } + } + focusOnNode(node) { if (typeof node == "string") { node = this.idToNode[node]; @@ -500,4 +511,6 @@ export default class Graph { return group; } + + } diff --git a/editor/js/editor.js b/editor/js/editor.js index c111023b51817e6eb0f92685c3d800118a1a7d0f..eebae44df5d7a4a3539aff160f406e2b0712fc05 100644 --- a/editor/js/editor.js +++ b/editor/js/editor.js @@ -3,8 +3,7 @@ import * as Graph from "./graph"; import { loadGraphJson } from "../../datasets/datasets"; import ForceGraph from "force-graph"; import * as Interactions from "./interactions"; -import { setSpace, SPACE } from "../../config"; - +import { DRAG_THRESHOLD_2D, setSpace, SPACE } from "../../config"; export var state = undefined; export var graph = undefined; @@ -24,21 +23,19 @@ window.onload = function () { loadSpace(SPACE); }; - export function loadSpace(spaceId) { if (state !== undefined && spaceId === SPACE) { return; } setSpace(spaceId); - return loadGraphJson(SPACE) - .then((graphConfig) => { - state = new State(); - graph = new Graph.Graph(graphConfig); - load(); + return loadGraphJson(SPACE).then((graphConfig) => { + state = new State(); + graph = new Graph.Graph(graphConfig); + load(); - graph.restartSimulation(); - }); + graph.restartSimulation(); + }); } function extractPositions(event) { @@ -60,6 +57,7 @@ function load() { .linkColor((link) => state.linkColor(link)) .nodeColor((node) => state.nodeColor(node)) .onNodeClick((node) => state.onNodeClick(node)) + .onNodeDragEnd((node, translate) => onNodeDragEnd(node, translate)) .autoPauseRedraw(false) // keep redrawing after engine has stopped .linkWidth((link) => state.linkWidth(link)) .linkDirectionalParticles(state.linkDirectionalParticles()) @@ -70,12 +68,25 @@ function load() { state.onBackgroundClick(event, extractPositions(event)) ) .nodeCanvasObjectMode((node) => state.nodeCanvasObjectMode(node)) - .nodeCanvasObject((node, ctx, globalScale) => state.nodeCanvasObject(node, ctx, globalScale)) + .nodeCanvasObject((node, ctx, globalScale) => + state.nodeCanvasObject(node, ctx, globalScale) + ) .linkCanvasObjectMode((link) => state.linkCanvasObjectMode(link)) - .linkCanvasObject((link, ctx, globalScale) => state.linkCanvasObject(link, ctx, globalScale)) + .linkCanvasObject((link, ctx, globalScale) => + state.linkCanvasObject(link, ctx, globalScale) + ) .onLinkClick((link) => state.onLinkClick(link)); graph.onChangeCallbacks.push((data) => { graphObj.graphData(data); }); } + +function onNodeDragEnd(node, translate) { + if ( + Math.sqrt(Math.pow(translate.x, 2) + Math.pow(translate.y, 2)) < + DRAG_THRESHOLD_2D + ) { + state.onNodeClick(node); + } +}