RedGiant
RedGiant

Reputation: 4748

How to get a tooltip show up near the pie slice using d3.js?

Fiddle Example

How can I get the tooltip to show up closer to the hovered slice? I can't get d3.pageXOffset and d3.pageYOffset (like this example) to work. What is the way to get the hovered pie slice position for the tooltip?

Not working:

path.on('mouseover', function(d) { 
    tooltip.style("top", d3.pageYOffset + "px").style("left", d3.pageXOffset + "px")
});

Full code:

    var dataset = 
        [
            {item:"Boy",result:12},
            {item:"Girl",result:24},
            {item:"Woman",result:60},
            {item:"Man",result:10}                     
        ]
    var width = 280;
    var height = 280;
    var radius = Math.min(width, height) / 2;
    var color = d3.scale.category10();

    var svg = d3.select('#area')
      .append('svg')
      .attr('width', width)
      .attr('height', height)
      .append('g')
      .attr('transform', 'translate(' + (width / 2) + 
        ',' + (height / 2) + ')');
    var arc = d3.svg.arc()
      .outerRadius(radius);
    var pie = d3.layout.pie()
      .value(function(d) { return d.result; })
      .sort(null);
    var path = svg.selectAll('path')
      .data(pie(dataset))
      .enter()
      .append('path')
      .attr('d', arc)
      .attr('fill', function(d, i) { 
        return color(d.data.item);
      });
    var tooltip = d3.select('#area').append('div').attr('class', 'tooltip');                           
    path.on('mouseover', function(d) { 
               var matrix = this.getScreenCTM()
        .translate(+this.getAttribute("cx"),
                 +this.getAttribute("cy"));

        var total = d3.sum(dataset.map(function(d) {               
          return d.result;                                           
        }));     
        var percent = Math.round(1000 * d.data.result / total) / 10; 
        tooltip.style("top", d3.pageYOffset + "px")
        .style("left",d3.pageXOffset + "px")
        .style('display', 'block') 
        .style("opacity", 1)
        .append('div')                                         
        .attr('class', 'label')                                   
        .append('div')                                        
        .attr('class', 'count')                                      
        .append('div')                                           
        .attr('class', 'percent'); 

        tooltip.select('.label').html(d.data.item);               
        tooltip.select('.count').html(d.data.result);               
        tooltip.select('.percent').html(percent + '%'); 

      });                                                           

      path.on('mouseout', function() {                             
        tooltip.style('display', 'none');                          
      });                       

Upvotes: 1

Views: 247

Answers (1)

Mark
Mark

Reputation: 108537

Use d3.event:

tooltip.style("top", d3.event.y + "px").style("left", d3.event.x + "px");

I would also put it into a mousemove handler for better results.

Updated fiddle.

Upvotes: 1

Related Questions