cytoscape.js

How to remove specific edges without redrawing the graph using cytoscape.js?


Given a node in cytoscape.js, I'm trying to remove the node and all directed (in and out) edges of that node. I've wrote some quick and dirty filters to do so, but calling cy.remove(edges); prints a 'no such method exists' error message to the console. Removing a node through the same approach works fine, but removes all nodes connected to the removed node, which in my case, is the whole graph (most of the times). So I've tried removing the edges and the node from my data source and then re-drawing the graph, but this is not the correct approach since it re-draws the graph, and changes the layout( i.e. refreshes the canvas).

How can I solve this?

                //data is the id of the node I want to remove
                var filteredEdges = this.elements.edges.filter((x, idx, arr) => 
                {
                    return x.source != data && x.target != data ;
                });

                var removedEdges = this.elements.edges.filter((x, idx, arr) => 
                {
                    return x.source == data || x.target == data ;
                });
                //this.cy.remove(removedEdges); this fails

                this.elements.edges = filteredEdges;

                var filteredNodes = this.elements.nodes.filter((x, idx, arr) =>
                {
                    return x.id != data;
                });
                this.cy.remove(data);
                this.elements.nodes = filteredNodes;
                this.render(); // this re-draws the whole graph, not a useable approach

Solution

  • Solved it using selectors. The documentation for cytoscape.js is very lacking. For anyone encountering this issue sometime in the future, here's how I did it:

    this.cy.remove('edge[source=\'' + nodeId + '\']');
    this.cy.remove('edge[target=\'' + nodeId + '\']');
    this.cy.remove('#' + nodeId);