D3 tooltip not following the mouse

Viewed 124

I have created a webpage with multiple charts using D3 and Object Oriented Programming.

Working code link--> https://codepen.io/mohan-ys/pen/LYLwqrK

The problem I am facing is that the tooltip is not at the mouse location, it is somewhere else. I tried using d3.event.pageX & d3.event.pageY instead of vis.mouse[0] & vis.mouse[1] which is in the code above but it does not work.

I am getting the tooltip as shown. When the mouse is at the right end of the graph, the tool tip moves further right, it gets closer somewhere in the middle & it goes to the other side by the time the cursor is on the left end of the chart!

The page is resized, then it is a totally different behaviour!

Can anyone help get the tooltip right a the mouse pointer (top-left corner at the mouse pointer) for all graphs & even when the page is resized (the graphs scale with page resize).

The vertical line follows the mouse perfectly!, so, if there is another way of creating the tooltip instead of a div, that is also ok for me.

enter image description here enter image description here enter image description here

1 Answers

The underlying problem is addressed here but the answer doesn't directly solve your problem. Basically, there's a second and optional argument to d3.pointer called target such that:

If target is not specified, it defaults to the source event’s currentTarget property, if available. If the target is an SVG element, the event’s coordinates are transformed using the inverse of the screen coordinate transformation matrix...

You can make use of this argument per below noting that it will break your vertical tracking line if you try and just update vis.mouse:

// mouse moving over canvas
vis.mouse = d3.pointer(event); // keep this for the vertical tracking line
vis.mouse2 = d3.pointer(event, d3.select(vis.chartLocation)); // <--- NEW VARIABLE!

Now vis.mouse2 has a relative x and y - so use them where you set the style of the div:

d3
  .select(vis.chartLocation)
  .selectAll("#tooltip")
  .html((d, i) => {
    vis.xDate = d.values[vis.idx - 1].date;
    return vis.xDate.toLocaleDateString("pt-PT");
  })
  .style("display", "block")
  .style("left", vis.mouse2[0] + "px") // use vis.mouse2
  .style("top", vis.mouse2[1] + "px") // use vis.mouse2

The clue is in that your first selection is vis.chartLocation.

Related