iVis-at-Bilkent / cytoscape.js-fcose

fCoSE: a fast Compound Spring Embedder
MIT License
141 stars 25 forks source link

Cannot read property 'getEdgesBetween' #13

Closed hrvoj3e closed 4 years ago

hrvoj3e commented 4 years ago

I get when running layout(...).run() on a subset of newly added nodes.

cytoscape-fcose.js:865 Uncaught TypeError: Cannot read property 'getEdgesBetween' of undefined
    at processEdges (cytoscape-fcose.js:865)
    at coseLayout (cytoscape-fcose.js:902)
    at a.run (cytoscape-fcose.js:551)

Line 115 https://github.com/iVis-at-Bilkent/cytoscape.js-fcose/blob/8e02e9b493d16f7446052e2188a29198d85e0234/src/fcose/cose.js#L109-L120

My code

// node = current node for which we load connected nodes from api
let node = evt.target;
let added = cy.add(<nodes from api>);
cy.collection()
  .union(node.outgoers())
  .layout(Object.assign(m.Graph.layout, {fit: false})).run();
hasanbalci commented 4 years ago

@hrvoj3e The reason behind the error is that you give dangling edges to the layout which doesn't deal with that case. (node.outgoers() only returns outgoing edges and target nodes, not the source node.)

What I can suggest you is to use cytoscape-layout-utilities extension that does exactly what you want. It positions the newly added nodes with respect to their already laid out neighbors. Then, optionally you can apply fCoSE on the whole graph or only on the desired part (without dangling edges) incrementally (with randomize: false) for polishing.

ugurdogrusoz commented 4 years ago

@hrvoj3e In other words, a layout algorithm will not properly work if you want to layout edges whose both ends aren't provided (as nodes to be laid out).