cytoscape.js - How to dynamically shift a node's position with a preset layout? - Stack Overflow

admin2025-04-26  2

I'm working on a project where I'm using Cytoscape.js to visualize a graph. I have a preset layout defined where I set the initial positions of the nodes as follows:

const presetLayoutOptions = {
    name: "preset",
    positions: this.cy.nodes().reduce((acc, node: any) => {
      acc[node.data().id] = node.data()["position"];
      return acc;
    }, {} as { [key: string]: { x: number; y: number } }),
    pan: { x: 800, y: 400 },
    zoom: 1,
    fit: true,
    padding: 30,
  };

this.cy.layout(presetLayoutOptions).run();

I also have a method triggered on a button click where I attempt to shift the position of a node by passing its id. Here’s the code:

this.cy.$('#id').shift({ x: 100, y: 0 });  

Problem:

The node doesn't seem to update its position dynamically when the button is clicked. I'm expecting the node to shift by 100 units along the x-axis from its current position.

Expected Behavior:

When I click the button, the node with the given id should shift its position based on the values passed to the shift method.


I'm working on a project where I'm using Cytoscape.js to visualize a graph. I have a preset layout defined where I set the initial positions of the nodes as follows:

const presetLayoutOptions = {
    name: "preset",
    positions: this.cy.nodes().reduce((acc, node: any) => {
      acc[node.data().id] = node.data()["position"];
      return acc;
    }, {} as { [key: string]: { x: number; y: number } }),
    pan: { x: 800, y: 400 },
    zoom: 1,
    fit: true,
    padding: 30,
  };

this.cy.layout(presetLayoutOptions).run();

I also have a method triggered on a button click where I attempt to shift the position of a node by passing its id. Here’s the code:

this.cy.$('#id').shift({ x: 100, y: 0 });  

Problem:

The node doesn't seem to update its position dynamically when the button is clicked. I'm expecting the node to shift by 100 units along the x-axis from its current position.

Expected Behavior:

When I click the button, the node with the given id should shift its position based on the values passed to the shift method.


Share Improve this question edited Jan 15 at 6:00 DarkBee 15.5k8 gold badges72 silver badges118 bronze badges asked Jan 15 at 5:30 Nikhil RatnawatNikhil Ratnawat 1
Add a comment  | 

1 Answer 1

Reset to default 0

Could there be an issue with the binding an event to the button? Here is a full working example.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Example</title>
    <script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
    <style>
      #cy {
        width: 800px;
        height: 600px;
        border: 1px solid #ccc;
        display: inline-block;
        vertical-align: top;
      }
      #controls {
        display: inline-block;
        vertical-align: top;
        margin-left: 1rem;
      }
    </style>
  </head>
  <body>
    <div id="cy"></div>
    <div id="controls">
      <button id="shiftButton">Shift Node (id='one')</button>
    </div>

    <script>
      const cy = cytoscape({
        container: document.getElementById('cy'),
        elements: [
          {
            data: { id: 'one', position: { x: 100, y: 100 } },
          },
          {
            data: { id: 'two', position: { x: 300, y: 300 } },
          },
          {
            data: { id: 'edge1', source: 'one', target: 'two' },
          },
        ],
        style: [
          {
            selector: 'node',
            style: {
              label: 'data(id)',
              'text-valign': 'center',
              color: '#000',
              'background-color': '#ccc',
            },
          },
          {
            selector: 'edge',
            style: {
              width: 2,
              'line-color': '#999',
            },
          },
        ],
      });

      const presetLayoutOptions = {
        name: 'preset',
        positions: cy.nodes().reduce((acc, node) => {
          acc[node.data().id] = node.data().position;
          return acc;
        }, {}),
        pan: { x: 0, y: 0 },
        zoom: 1,
        fit: true,
        padding: 30,
      };

      cy.layout(presetLayoutOptions).run();

      document.getElementById('shiftButton').addEventListener('click', () => {
        cy.$('#one').shift({ x: 100, y: 0 });
      });
    </script>
  </body>
</html>
转载请注明原文地址:http://anycun.com/QandA/1745598232a90982.html