简体   繁体   中英

Interactive Legend onclick or mouseover - D3js

I've been looking for a way to have my legend control my chart animation (similar to NVD3 examples ). I've run into a problem though - nested selections.

var legend = svg.append("g")
    .attr("class", "legend")
    .attr("transform", "translate(70,10)")
    ;

var legendRect = legend.selectAll('rect').data(colors);

legendRect.enter()
   .append("rect")
   .attr("x", w - 65)
   .attr("width", 10)
   .attr("height", 10)
   .attr("y", function(d, i) {
       return i * 20;
   })
   .style("stroke", function(d) {
       return d[1];
   })
   .style("fill", function(d) {
       return d[1];
   });

I'm using a bit of a hack to do my animation. Basically setting style to display: none .
I want to be able to click on the rectangles and call the function. But putting a mouseover or onclick within legendRect doesn't work. The bars to animate are not children of the legend. How can I call the function, or chain my function to my legend?

function updateBars(opts) {
var gbars = svg.selectAll("rect.global");
var lbars = svg.selectAll("rect.local");
if (opts === "global") {
    gbars.style("display", "block") ;
    lbars.style("display", "none");
    gbars.transition()
        .duration(500)
        .attr("width", xScale.rangeBand());
};
if (opts === "local") {
    lbars.style("display", "block")
    ;
    gbars.style("display", "none");
    lbars.transition()
        .duration(500)
        .attr("x", 1 / -xScale.rangeBand())
        .attr("width", xScale.rangeBand());
};
}

My other obstacle is changing the fill color on click . I want it to almost imitate a checkbox, so clicking (to deselect) would turn the fill white. I tried something similar as .on("click",(".style" ("fill", "white"))) . But that is incorrect.

Here is my fiddle . For some reason, the function isn't updating things on Fiddle. It works on my localhost though. Not sure the problem with that.

I'm not completely sure I understand you correctly, but if your first question is how to change element X when clicking on element Y, you need something along the lines of:

legendRect.on("click", function() {
  gbars.transition()
    .duration(500)
    .style("display", "block")
    // etc...
}

As for changing the fill on click, try:

gbars.on("click", function() {
  d3.select(this)
    .attr("fill", "white");
}

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