How to highlight neighbouring nodes in Cytoscape.js
Asked Answered
N

4

9

I am using cytoscape.js and would like to add the feature on mouseover or tap of a node to apply a style to:

  1. change the style of the neighbouring nodes - 1st degree
  2. fade out the nodes that are not connected

I seem to be able to get the neighbours, any ideas how I apply a style to non neighbours?

cy.on('tap', 'node', function(e) {
                var node = e.cyTarget;
                var directlyConnected = node.neighborhood();
                directlyConnected.nodes().addClass('connectednodes');

            });
Nudd answered 20/7, 2015 at 7:33 Comment(0)
M
20

If ever you haven't found the solution to highlight children of a node when mouse hover one, here is my attempt and it works nice:

Event handler:

cy.on('mouseover', 'node', function(e){
    var sel = e.target;
    cy.elements().difference(sel.outgoers()).not(sel).addClass('semitransp');
    sel.addClass('highlight').outgoers().addClass('highlight');
});
cy.on('mouseout', 'node', function(e){
    var sel = e.target;
    cy.elements().removeClass('semitransp');
    sel.removeClass('highlight').outgoers().removeClass('highlight');
});

Basically, all elements are filtered if they're not the hovered node or its direct children ("outgoers") and the class 'semitransp' is added to them.
Then, the class 'highlight' is added to the hovered node and all its children.

Example of style for 'highlight' and 'semitransp' class:

var cy = cytoscape({
    elements: [ {...} ]
    style: [
        {...},
        {
            selector: 'node.highlight',
            style: {
                'border-color': '#FFF',
                'border-width': '2px'
            }
        },
        {
            selector: 'node.semitransp',
            style:{ 'opacity': '0.5' }
        },
        {
            selector: 'edge.highlight',
            style: { 'mid-target-arrow-color': '#FFF' }
        },
        {
            selector: 'edge.semitransp',
            style:{ 'opacity': '0.2' }
        }
    ]
});
Mei answered 19/7, 2016 at 21:33 Comment(4)
It should be remembered to add style sheet of the class to the cy object, otherwise addClass doesn't work.Navelwort
Which version of cytoscape was this? I don't see the cyTarget property anymore and difference doesn't seem to be doing what is expected.Pistoia
@Pistoia Try just e.targetUlyssesumayyad
cy.elements() is not a functionNecessary
M
10

Addition to Polosson's answer since I am not aloud to comment:

The api seems to have changed, it's target instead of cyTarget now (Verison 3.2.17).

Also, you might have to add the incomers to highlight all neighbours:

cy.on('mouseover', 'node', function(e) {
    var sel = e.target;
    cy.elements()
        .difference(sel.outgoers()
            .union(sel.incomers()))
        .not(sel)
        .addClass('semitransp');
    sel.addClass('highlight')
        .outgoers()
        .union(sel.incomers())
        .addClass('highlight');
});
cy.on('mouseout', 'node', function(e) {
    var sel = e.target;
    cy.elements()
        .removeClass('semitransp');
    sel.removeClass('highlight')
        .outgoers()
        .union(sel.incomers())
        .removeClass('highlight');
});
Meli answered 22/10, 2018 at 20:12 Comment(0)
B
2

Use the set difference: http://js.cytoscape.org/#collection/building--filtering/eles.difference

cy.elements().difference( dontIncludeTheseEles )

Billon answered 20/7, 2015 at 13:6 Comment(2)
Hi Max, thanks for the reply. How would this be used with a mouseover to show only the connected nodes to an individual node?Nudd
I have also tried eles.neighborhood() and still no success. I have looked through all of the examples on js.cytoscape.com, gists, codepens, etc. Has anyone successfully implemented onhover capabilities to highlight nodes? Perhaps this is a bug ?Nudd
R
0

This code implements the click functionality instead of hover to highlight the node. It´s an extension of Polosson answer.

var previous_node;
var previous_sel;
cy.on("click","node",(e)=>
{
    var sel = e.target;
    var id = e.target.id();

    if ((id != previous_node) && (previous_node != undefined ) && (previous_sel != undefined))
        
    {

        cy.elements().removeClass("semitransp");
        previous_sel.removeClass("highlight").outgoers().union(previous_sel.incomers()).removeClass("highlight");

        cy.elements().difference(sel.outgoers().union(sel.incomers())).not(sel).addClass("semitransp");
        sel.addClass("highlight").outgoers().union(sel.incomers()).addClass("highlight");

        previous_sel = sel;
        previous_node = id;

    }

    else
    
    {
        
        cy.elements().difference(sel.outgoers().union(sel.incomers())).not(sel).addClass("semitransp");
        sel.addClass("highlight").outgoers().union(sel.incomers()).addClass("highlight");
        previous_sel = sel;
        previous_node = id;

    }



    

})
Ruppert answered 21/12, 2022 at 10:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.