Search code examples
javascriptcssd3.jssvgtooltip

Tooltip doesn't disappear on mouseout


I'm trying to add a tooltip to a rect. It does pop up on mouse pointer hover over a bar but it doesn't want to disappear on mouseout event. I've also tried to use div.style("display", "none"), but it doesn't work either. For some reason it doesn't want to trigger mouseover event again after mouseout. It just keep displaying a tooltip.

http://bl.ocks.org/edkiljak/dc85bf51a27122380c68909cdd09d388

div.tooltip {
            position: absolute;
            text-align: left;
            padding: 4px;
            font-family: Lato, arial, sans-serif;
            font-size: 14px;
            background: #eee;
            border-radius: 2px;
            border: 1px solid gray;
            pointer-events: none;
        }



var div = d3.select("body")
                .append("div")
                .attr("class", "tooltip")
                .style("opacity", 0);

var bars = barGroup.selectAll("rect")
            .data(data)
            .enter()
            .append("rect")
            .attr("x", 0)
            .attr("y", function (d) {
                return heightScale(d.Vendor);
            })
            .attr("width", function (d) {
                return widthScale(+d.Share2016)
            })
            .attr("height", heightScale.bandwidth() / 1.1)
            .style("fill", function (d, i) {
                return color(i);
            })
            .on("mouseover",function (d){

                div.transition()
                    .duration(200)
                div
                    .style("opacity", .9)
                    .html("Vendor: " + "<strong>" + d.Vendor + "</strong>" + "<br>" + "Market share in 2016: " + d.Share2016 + "%")
                    .style("left", (d3.event.pageX) + "px")
                    .style("top", (d3.event.pageY - 28) + "px");


                d3.select(this)
                    .style("fill", "#93ceff")



            })
            .on("mouseout", function(){
                d3.select(this)
                    .transition()
                    .duration(50)
                    .style("fill", function(d,i){
                        return color(i);
                    })

                d3.select(div).remove()

            })

What am I doing wrong here?


Solution

  • The problem lies here:

    d3.select(div).remove()
    

    As div is itself a selection, you're selecting a selection, and that makes little sense.

    Instead of that, just use div in the mouseout:

    div.remove()
    

    Or, even better, just set its opacity to zero:

    div.style("opacity", 0)
    

    Here is the updated bl.ocks with just that change: http://bl.ocks.org/anonymous/raw/13ce2445b248fb9e44dcd33cfc3dff36/dff0c60423927960cab8aaf9e613c2c3ae205808/