Search code examples
d3.jstooltip

tooltip X position in d3 grouped bar chart


I can't quite figure out why the X position is always as if the bar that I am hovering over was located in the first group.

http://jsbin.com/xiboxupema/edit?js,console,output

Not sure why this is getting downvoted. I am trying to use the x property of rectangle to determine tooltip position but it seems to always be set relative to "group". How can I fix that?

  state.selectAll("rect")
      .data(function(d) { return d.ages; })
      .enter().append("rect")
      .attr("width", x1.rangeBand())
      .attr("x", function(d) { return x1(d.name); })
      .attr("y", function(d) { return y(d.value); })
      .attr("height", function(d) { return height - y(d.value); })
      .style("fill", function(d) { return color(d.name); });

  state.selectAll("rect")
    .on("mouseover", function(d){

       var yPos = parseFloat(d3.select(this).attr("y"));
       var xPos = parseFloat(d3.select(this).attr("x"));
       var height = parseFloat(d3.select(this).attr("height"))
       var width = parseFloat(d3.select(this).attr("width"))

       console.log(xPos);

       d3.select(this).attr("stroke","red").attr("stroke-width",0.8);

       svg.append("text")
       .attr("x",xPos)
       .attr("y",yPos + height/2)
       .attr("font-family", "sans-serif")
       .attr("font-size", "10px")
       .attr("font-weight", "bold")
       .attr("fill", "black")
       .attr("text-anchor", "middle")
       .attr("id", "tooltip")
       .attr("transform", "translate(" + width/2 + ")")
       .text(d.name +": "+ d.value);

    })
    .on("mouseout", function(){
        svg.select("#tooltip").remove();
       d3.select(this).attr("stroke","pink").attr("stroke-width",0.2);

     });

EDIT:

Clearly its not the same issue as the one described in my previous question. Using transform property wasn't solving it like it did with the stacked bar chart since in a stacked bar chart all rectangles are in the same X coordinate while in grouped they are not. Each group is treated as object so getting a transform returns a point that is aligned with a left most bar but not with the rest of them. Now, I was able to solve this by getting a transform and adding a value of each bar's x position within the group to get its correct x coordinate. Please remove the down-vote.


Solution

  • Ah got it!

    state.selectAll("rect")
        .data(function (d) { return d.ages; })
        .enter().append("rect")
        .attr("width", x1.rangeBand())
        .attr("x", function (d) { return x1(d.name); })
        .attr("y", function (d) { return y(d.value); })
        .attr("height", function (d) { return height - y(d.value); })
        .style("fill", function (d) { return color(d.name); });
    
    state.selectAll("rect")
      .on("mouseover", function(d){
    
         var group = d3.select(d3.select(this).node().parentNode);
         var xPos = d3.transform(group.attr("transform")).translate[0] + x1(d.name);
         var yPos = parseFloat(d3.select(this).attr("y"));
         var height = parseFloat(d3.select(this).attr("height"))
         var width = parseFloat(d3.select(this).attr("width"))
    
         d3.select(this).attr("stroke","red").attr("stroke-width",0.8);
    
         svg.append("text")
         .attr("x",xPos)
         .attr("y",yPos + height/2)
         .attr("font-family", "sans-serif")
         .attr("font-size", "10px")
         .attr("font-weight", "bold")
         .attr("fill", "black")
         .attr("text-anchor", "middle")
         .attr("id", "tooltip")
         .attr("transform", "translate(" + width/2 + ")")
         .text(d.name +": "+ d.value);
    
      })
      .on("mouseout", function(){
          svg.select("#tooltip").remove();
         d3.select(this).attr("stroke","pink").attr("stroke-width",0.2);
    
       });