Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cytoscape.js dynamically add nodes without moving the others

Tags:

cytoscape.js

I am working on an application that fetches data from a database and I would like to show them as graph.

I managed the "tap" event on a node by showing their neighbors (nodes and connection links).

The problem is that, every time I want to show the neighbors, all the graph is re-rendered and if some nodes were moved before, they lose their previous position.

Is there a way to add only the neighbors without affecting the position of the node already present in the layout?

Important: the constraint is that all the nodes should be "movable": the number of nodes in the graph can, easily, increase and I would like to have the availability to move/organize them without losing the result when I add new ones (by clicking on a node)

I am using cola-layout in my project.

Here the way I managed to add neighbors:

function addNeighbour(node, link) {
    cy.startBatch();
    addNode(link.otherNode.type, link.otherNode.name, link.otherNode.properties);
    cy.add([
      {
        group: 'edges',
        data:
        {
          id: node + ":" + link.type + ":" + link.otherNode.type + ":" + link.otherNode.name,
          source: source,
          target: target,
          type: link.type,
          properties: linkproperties
        }
      }
    ]);
    refreshLayout()
    cy.endBatch();
  }
}

var layoutOpts = {
    name: 'cola',
    refresh: 2,
    edgeLength: 200,
    fit: false
}

function refreshLayout() {
    layout.stop();
    layout = cy.elements().makeLayout(layoutOpts);
    layout.run();
}

Thanks in advance

like image 737
Cristiano Avatar asked Oct 20 '25 05:10

Cristiano


1 Answers

(1) You can lock a node to make its position immutable, via nodes.lock().

(2) You can run a layout on a subset of the graph to exclude certain elements, via eles.layout().

Either of these strategies can be used in general, or they can be used in tandem.

For your case, it sounds like you should use (1).

  • Lock the existing nodes.
  • Add the new nodes.
  • Run Cola on the entire graph.
  • When Cola is done, free the locked nodes.

Note, however, that this won't always give a good result. You could over-constrain the system. If you want a good layout result, it's probably best to just run the layout on everything without locking, as Stephan T. suggested.

like image 176
maxkfranz Avatar answered Oct 22 '25 04:10

maxkfranz