javascript D3.js:使用元素位置而不是鼠标位置定位工具提示?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16256454/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 03:56:16  来源:igfitidea点击:

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

javascriptd3.jstooltip

提问by Richard

I'm using D3 to draw a scatter graph. I would like to show tooltips when the user mouses over each circle.

我正在使用 D3 绘制散点图。当用户将鼠标悬停在每个圆圈上时,我想显示工具提示。

My problem is that I can append tooltips, but they're positioned using the mouse event d3.event.pageXand d3.event.pageY, so they are not positioned consistently over each circle.

我的问题是我可以附加工具提示,但它们是使用鼠标事件d3.event.pageX和定位的d3.event.pageY,因此它们在每个圆圈上的位置不一致。

Instead, some are slightly to the left of the circle, some to the right - it depends on how the user's mouse enters the circle.

相反,有些在圆圈的左侧,有些在右侧 - 这取决于用户的鼠标如何进入圆圈。

This is my code:

这是我的代码:

circles
  .on("mouseover", function(d) {         
    tooltip.html(d)  
      .style("left", (d3.event.pageX) + "px")     
      .style("top", (d3.event.pageY - 28) + "px");    
  })                  
  .on("mouseout", function(d) {       
    tooltip.transition().duration(500).style("opacity", 0);   
  });

And is a JSFiddle showing the problem: http://jsfiddle.net/WLYUY/5/

并且是一个显示问题的 JSFiddle:http: //jsfiddle.net/WLYUY/5/

Is there some way I can use the centre of the circle itself as the position to orient the tooltip, not the mouse position?

有什么方法可以使用圆心本身作为定位工具提示的位置,而不是鼠标位置?

采纳答案by Lars Kotthoff

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

在您的特定情况下,您可以简单地使用d来定位工具提示,即

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");

回答by Boxuan

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

找到了这里,可能解决你的问题,即使<body><svg>有不同的定位。这是假设您absolute为工具提示设置了位置。

.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");
})

回答by Jared Wilber

In my experience, the easist solution is as follows:

根据我的经验,简单的解决方案如下:

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

首先,getBoundingClientRect()获取元素的位置。

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

然后,使用window.pageYOffset调整高度,相对于您所在的位置。

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).

在上面的例子中,我没有使用 X 的偏移量,因为我们很少需要(除非你水平滚动)。

Adding window.pageYOffsetand 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.

添加window.pageYOffsetpos['y']为我们提供当前鼠标位置(无论我们在页面上的哪个位置)。我减去 100 将工具提示放在它的上方一点。

回答by timemirror

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.

我是 D3 的新手,所以这可能不适用于散点图......但发现它似乎适用于条形图......其中 v1 和 v2 是绘制的值......它似乎从数据中查找值大批。

.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");})