D3.js: Position tooltips using element position, not mouse position?

I'm new to D3 so this may not work for scatterplots... but found it seems to work for Bar charts... where v1 and v2 are the values being plotted.. and it seems to look up the value from the data array.

.on("mouseover", function(d) {
                  divt .transition()
                      .duration(200)
                      .style("opacity", .9);
                  divt .html(d.v1)
                      .style("left", x(d.v2)+50 + "px")
                      .style("top",y(d.v1)+ "px");})

Found something here that might address your problem even if <body> and <svg> have different positioning. This is assuming you have absolute position set for your tooltip.

.on("mouseover", function(d) {
    var matrix = this.getScreenCTM()
        .translate(+ this.getAttribute("cx"), + this.getAttribute("cy"));
    tooltip.html(d)
        .style("left", (window.pageXOffset + matrix.e + 15) + "px")
        .style("top", (window.pageYOffset + matrix.f - 30) + "px");
})

In my experience, the easist solution is as follows:

First, getBoundingClientRect() to get the position of your element.

Then, use window.pageYOffset to adjust the height, relative to where you are.

E.g.

.on('mouseover', function(d) {
    let pos = d3.select(this).node().getBoundingClientRect();
    d3.select('#tooltip')
        .style('left', `${pos['x']}px`)
        .style('top', `${(window.pageYOffset  + pos['y'] - 100)}px`);
})

In the example above, I don't use X's offset because we rarely need to (unless you're scrolling horizontally).

Adding window.pageYOffset and pos['y'] gives us the current mouse position (wherever we are on the page). I subtract 100 to place the tooltip a little above it.


In your particular case you can simply use d to position the tooltip, i.e.

tooltip.html(d)  
  .style("left", d + "px")     
  .style("top", d + "px");

To make this a bit more general, you can select the element that is being moused over and get its coordinates to position the tooltip, i.e.

tooltip.html(d)  
  .style("left", d3.select(this).attr("cx") + "px")     
  .style("top", d3.select(this).attr("cy") + "px");