How to have only some edges react to `mouseover` in a D3 v4 force graph

700 views
Skip to first unread message

Federicopvs

unread,
Sep 12, 2016, 4:42:16 AM9/12/16
to d3-js
I am working on this force graph in D3 v4.

When a user click on a nodes, only the nodes connected to it become visible. Moreover, the edges connecting those nodes become thicker and users can hover on the so see more information (the tooltip that appears on the right).

This is how I highlight the connected nodes after a click

    //Highlight on click
   
function highlighting () {
   
//Toggle stores whether the highlighting is on
   
var node = d3.selectAll('circle');
   
var link = d3.selectAll('line');
   
var toggle = 0;
   
//Create an array logging what is connected to what
   
var linkedByIndex = {};
   
for (i = 0; i < dataset.nodes.length; i++) {
        linkedByIndex
[i + "," + i] = 1;
   
};
    d3
.selectAll('line').each(function (d) {
        linkedByIndex
[d.source.index + "," + d.target.index] = 1;
   
});
   
//This function looks up whether a pair are neighbours
   
function neighboring(a, b) {
       
return linkedByIndex[a.index + "," + b.index];
   
}
   
function connectedNodes() {
       
if (toggle == 0) {
           
//Reduce the opacity of all but the neighbouring nodes
            d
= d3.select(this).node().__data__;
            node
.style("opacity", function (o) {
               
return neighboring(d, o) | neighboring(o, d) ? 1 : 0.0;
           
});
            link
.style("opacity", function (o) {
               
return d.index==o.source.index | d.index==o.target.index ? 1 : 0.0;
           
});
            link
.attr('stroke-width' , 4);
            toggle
= 1;
            interactivityHighlight
();

           
//Change navigation div
            d3
.select('#click01').classed('hidden', true);
            d3
.select('#click02').classed('hidden', false);

       
} else {
           
//Put them back to starting opacity
            node
.style("opacity", 1);
            link
.style("opacity", function (d) {return edgeOpacityScale(d.collaborations);});
            link
.attr('stroke-width', 1);
            link
.attr('class', null);
            toggle
= 0;
           
//Change navigation
            d3
.select('#click01').classed('hidden', false);
            d3
.select('#click02').classed('hidden', true);
       
}
   
}
    node
.on('click', connectedNodes);
   
}



And this is the function I call after the click

    function interactivityHighlight () {
    graph
.selectAll('line').on('mouseover', function (d) {
       
if (d3.select(this).style('opacity') == 1) {
            d3
.select(this)
           
.attr('stroke', 'red')
           
.attr('stroke-width', 6);

            d3
.select('#tooltip')
           
.classed('hidden', false);

            d3
.select('#tooltip')
           
.append('p')
           
.attr('id', 'org_names')
           
.text('Collaborations between ' + d.source.name + ' and ' + d.target.name);

            d3
.select('#tooltip')
           
.append('p')
           
.attr('id', 'collaborations')
           
.text('Worked together on ' + d.collaborations + ' projects');

            d3
.select('#tooltip')
           
.append('p')
           
.attr('id', 'collBudget')
           
.text('Total budget: '+ commafy(d.collBudget));
   
}})

    graph
.selectAll('line').on('mouseout', function (d) {
       
if (d3.select(this).style('opacity') == 1) {
            d3
.select(this)
           
.attr('stroke', 'black')
           
.attr('stroke-width', 4);

            d3
.select('#tooltip')
           
.selectAll('p')
           
.remove();

            d3
.select('#tooltip')
           
.classed('hidden', true);
   
}})
   
}



Basically all non-connected nodes get `opacity=0` and thus become invisible. However, they are still present on the graph: hovering over a line may not trigger `interactivityHighlight()` because the mouse is actually hovering over an invisible edge.

Is there a way I can make the invisible edges really disappear, or make the visible ones "get on top" of all the others?
Reply all
Reply to author
Forward
0 new messages