0

In my sigma.js webapp, I have mainly 2 types of events: one is to handle click event (to open the node's URL) and the other is to handle drag events (to be able to drag the nodes here and there in the space) This code is responsible for handling the click event. If we click on nodes, then this opens the node's page URL:

  const renderer = new Sigma(graph, container);

  renderer.on("clickNode", ({ node }) => {
    if (!graph.getNodeAttribute(node, "hidden")) {
      window.open(graph.getNodeAttribute(node, "pageURL"), "_blank");
    }
  });

And this code is responsible for handling drag event. We can drag nodes anywhere using the mouse:

  let draggedNode: string | null = null;
  let isDragging = false;

  /* On mouse down on a node
    - we enable the drag mode
    - save in the dragged node in the state
    - highlight the node
    - disable the camera so its state is not updated */

  renderer.on("downNode", (e) => {
    isDragging = true;
    draggedNode = e.node;
    graph.setNodeAttribute(draggedNode, "highlighted", true);
  });

  // On mouse move, if the drag mode is enabled, we change the position of the draggedNode
  renderer.getMouseCaptor().on("mousemovebody", (e) => {
    if (!isDragging || !draggedNode) return;

    // Get new position of node
    const pos = renderer.viewportToGraph(e);

    graph.setNodeAttribute(draggedNode, "x", pos.x);
    graph.setNodeAttribute(draggedNode, "y", pos.y);

    // Prevent sigma to move camera:
    e.preventSigmaDefault();
    e.original.preventDefault();
    e.original.stopPropagation();
  });

  // Disable the autoscale at the first down interaction
  renderer.getMouseCaptor().on("mousedown", () => {
    if (!renderer.getCustomBBox()) renderer.setCustomBBox(renderer.getBBox());
  });

  // On mouse up, we reset the autoscaling and the dragging mode
  renderer.getMouseCaptor().on("mouseup", () => {
    if (draggedNode) {
      graph.removeNodeAttribute(draggedNode, "highlighted");
    }
    isDragging = false;
    draggedNode = null;
  });
}

The problem I am getting is that whenever I am dragging the nodes & releasing the mouse button; the click event is automatically triggered and hence the pageURL is being opened (which was supposed to open only if I click the node; and not drag the node).

Is there any way to not trigger the click event when dragging? I have also followed some stack-overflow answers to distinguish between clicks and drags but none of them worked. Here is the CodeSandbox link for trying it hands on

wthrajat
  • 32
  • 6

1 Answers1

0

This issue was solved by my GSoC mentor Michael Hamann. I owe this answer to him :)

  const delta = 10;
  let startX;
  let startY;
  let allowClick = true;

  // Disable the autoscale at the first down interaction
  renderer.getMouseCaptor().on("mousedown", (event) => {
    startX = event.original.pageX;
    startY = event.original.pageY;
    if (!renderer.getCustomBBox()) renderer.setCustomBBox(renderer.getBBox());
  });

  // On mouse up, we reset the autoscaling and the dragging mode
  renderer.getMouseCaptor().on("mouseup", (event) => {
    if (draggedNode) {
      graph.removeNodeAttribute(draggedNode, "highlighted");
      const diffX = Math.abs(event.original.pageX - startX);
      const diffY = Math.abs(event.original.pageY - startY);
      allowClick = diffX < delta && diffY < delta;
      isDragging = false;
      draggedNode = null;
    }
  });

  renderer.on("clickNode", ({ node }) => {
    if (!graph.getNodeAttribute(node, "hidden") && allowClick) {
      window.open(graph.getNodeAttribute(node, "pageURL"), "_blank");
    }
  });
wthrajat
  • 32
  • 6
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 03 '23 at 21:35