简体   繁体   中英

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.

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 .

The parameter "d" of the returned function is not the same like the id of the node. Furthermore, the source and target objects can not be compared against other objects that were used as keys. IMO objects should not be used as keys.

The following code worked for me (see complete code) :

function fadeAll(opacity,color) { 
            return function(ds) { 
                var selected = Number(d3.select(this).attr('id')); 
                link
                    .style("stroke-opacity", function(o) { 
                        return o.source.id === selected || o.target.id === selected ? 1 : 0.1;
                    })   
                    .style("stroke", function(o) {
                        return o.source.id === selected || o.target.id === selected ? "#000" : "#ddd" ;
                    })
                    ;
            }
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM