简体   繁体   中英

D3 force layout - legend interactivity on/off

I have a force layout with a legend, and I've appended checkboxes to each role in the legend. I'm trying to follow this example( https://jsfiddle.net/zhanghuancs/cuYu8/ ) and add interactivity to the legend, but when I uncheck any of the checkboxes, all the links disappear instead of the links and nodes related to the role. I'm creating the legend using this loop,

var col = color(d.group);
                   // adding code to display legend
                  // as nodes are filled
                  if(!(d.role in roles)){
                      legend.append("li")
                            .html(d.role)
                            .style("color", col)
                            //add checkbox
                            .append("input")
                            .attr("type", "checkbox")
                            .attr("id", function (d){
                                return "chk_" + d;
                            })
                            //check box
                            .property("checked", true)
                            .on("click", function (d){
                                //click event
                                var visibility = this.checked? "visible" : "hidden";
                                filterLegend(d,visibility);
                            })

                        roles[d.role] = true;
                    }

                  return col; })

Here's a fiddle of my graph ( https://jsfiddle.net/gbhrea/077mb7o1/1/ ), using a lot of data so just used a small sample for the fiddle. (graph won't show on fiddle but will keep the link anyways so that full code can be seen)

Here is the code for changing visibility

function filterLegend(aType, aVisibility){
                    //change vis of link
                    link.style("visibility", function (o) {
            var lOriginalVisibility = $(this).css("visibility");
            return o.type === aType ? aVisibility : lOriginalVisibility;
        });
                //change vis of node
                //if links of node invisible, node should be too
                node.style("visibility", function (o, i) {
                    var lHideNode = true;
                    link.each(function (d, i) {
                        if (d.source === o || d.target === o) {
                            if ($(this).css("visibility") === "visible") {
                        lHideNode = false;

                            }
                        }
                    })
                });

              } //end filter

To be clear, what I want to achieve is - When I uncheck a role, eg Actor, all nodes and links disappear. Any pointers would be greatly appreciated :)

There are a few mistakes in your code. First, you're not binding any data to the legend elements so .on("click", function (d) { }) won't work because d isn't defined there. You do have d.role there though, so that's what you should use to pass on to functions.

Similarly, your filterLegend() function references undefined things ( .type ) -- this is why everything disappears at the moment. You're passing in something undefined and comparing it to something undefined, which gives true . Furthermore, links don't have the node information directly, but under .source and .target , so you need to compare to .source.role and .target.role .

For the nodes on the other hand, it's much easier than what your current code is trying to do -- there's no need to iterate over the links. You can use the code you have for the links here, except for comparing to the existing .role attribute instead of the non-existing .type .

Complete demo here .

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