Ad

How To Show Labels On A Barchart On Mouseover With D3.js?

- 1 answer

I have drawn a horizontal barchart with D3.js. Each bar has a label and the bar changes color on mousover. Label visibility is set to hidden initially.

var bars = gw2.selectAll(".bar")
        .data(data)
        .enter()
        .append("g")
    //append rects
    bars.append("rect")
        .attr("class", "bar")
        .attr("id", function(d) { return d.country+"_bar"; })
        .attr("y", function(d) { return y2(d.country); })               
        .attr("height", y2.bandwidth())
        .style("filter", "url(#drop-shadow-h)")
        .attr("width", function(d) { return x2(d.value); });        
    //add a value label to the right of each bar
    bars.append("text")
        .attr("class", "textlbl")
        .attr("id", function(d) { return d.country+"_lbl"; })
        .attr("fill", "#404040")
        .attr("x", function(d) { return x2(d.value) - 5 })
        .attr("y", function(d){ return y2(d.country) + (y2.bandwidth()/2); })
        .attr("dy", ".35em") //vertical align middle
        .style("text-anchor", "end")
        .text(function(d){ return (d.value); });    

.textlbl {       
   font-size: 0.7rem;
   font-weight: bold;
   visibility: hidden;
}

I would like that, in addition to the color change of the single bar on mousover, also the corresponding label changes visibility to 'visible'. The single bar is as following:

<g>
    <rect class="bar" id="Greece_bar" y="149" height="14" width="230" style="filter: url(&quot;#drop-shadow-h&quot;);"></rect>
    <text class="textlbl" id="Greece_lbl" fill="#404040" x="225" y="156" dy=".35em" style="text-anchor: end; visibility: hidden;">56.6</text>
</g>

I've tried different solutions, but they don't work. First, with 'selectAll', but it selects all bars and all labels and not only the one with mouseover:

gw2.selectAll(".bar")
    .on("mouseover", function(d){               
        d3.selectAll(".textlbl").style("visibility", "visible");
    });

Then I've tried with 'this', but I can't get the selector 'textlbl' and the code returns the error "'[object SVGRectElement]+.textlbl' is not a valid selector".

gw2.select(".bar")
    .on("mouseover", function(d){               
        d3.select(this+"+.textlbl").style("visibility", "visible");
    });

Any suggestion?

Ad

Answer

Maybe this will do.

In d3 you can't select siblings, go to the parent first

gw2.select(".bar")
    .on("mouseover", function(d){               
        d3.select(this.parentNode).select('.textlbl').style("visibility", "visible");
    });
Ad
source: stackoverflow.com
Ad