dzordz dzordz - 3 months ago 45
CSS Question

D3 force directed layout - changing node color and its links color on button click

I'm little bit lost again and I need your help with my "fungraph" in D3. I wanna to color all nodes with same given class "person" and also their links with a click of the button.

I've managed to get nodes colored up in red color but I have issues with links.

I've tried to use simplified version of fade function which I'm using for mouseover on my nodes. I've first created on click function for button:

$(".btn_person").on("click",function(){

d3.selectAll(".person").select('circle')
.transition()
.duration(500)
.attr("style", "fill:red; stroke:red; stroke-width: 2px;" )
.call(fadeAll(.4,"red"));


});


and created fadeAll function which I'm calling as you see:

function fadeAll(opacity,color) {

return function(d) {


link.style("stroke-opacity", function(o) {
return o.source === d || o.target === d ? 1 : opacity;
})
.style("stroke", function(o) {
return o.source === d || o.target === d ? color : "#000" ;
});
};

}


But it does not work as I expected. I get no errors but links from the colored nodes does not get colored to red and all links does get opacity of 0.4 and I do not why? Am I calling the function in the wrong way?

You can see my situation, and test the issue when you click on button "person" on following link: http://jsfiddle.net/9rSM6/

The problematic code is at end of JavaScript code.

Any help or advice is welcome.

Answer

You're almost there -- d is a D3 selection, so you cannot compare elements to it directly. Rather, you need to extract the elements in the selection and then check whether .source or .target is in this array:

var e = [];
d.each(function(a, i) { e[i] = a; });

link.style("stroke-opacity", function(o) {
    return e.indexOf(o.source) != -1 || e.indexOf(o.target) != -1 ? 1 : opacity;
  })   
  .style("stroke", function(o) {
    return e.indexOf(o.source) != -1 || e.indexOf(o.target) != -1 ? color : "#000" ;
  });

Complete example here.