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

47

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

我的问题是,尽管我可以附加工具提示,但它们的位置是基于鼠标事件 d3.event.pageXd3.event.pageY 而定位的,因此它们没有一致地位于每个圆的正上方。

相反,有些工具提示略微靠左,有些靠右-这取决于用户的鼠标进入圆形的方式。

这是我的代码:

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

这里有一个展示问题的 JSFiddle: http://jsfiddle.net/WLYUY/5/

我能否以圆形本身的中心作为提示框定位的位置,而不是以鼠标位置为基准?


如果您对任何类型的工具提示都没有问题,那么这个答案应该会有所帮助。 - Lars Kotthoff
谢谢!如果可能的话,我更喜欢使用纯D3工具提示而不是tipsy。 - Richard
4个回答

32
在您的情况下,您可以简单地使用d来定位工具提示,即:
tooltip.html(d)  
  .style("left", d + "px")     
  .style("top", d + "px");
为了让这更加通用,您可以选择被鼠标悬停的元素并获取其坐标以定位工具提示,即:

为了让这更加通用,您可以选择被鼠标悬停的元素并获取其坐标以定位工具提示,即:

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

2
谢谢 - 恐怕只有在<body><svg>元素具有相同的定位时,使用d3.select(this).attr("cx")才有效。请参见http://jsfiddle.net/WLYUY/6/ - Richard
4
如果您有其他内容,您需要添加SVG的偏移量到位置上,参见 http://jsfiddle.net/WLYUY/7/。 - Lars Kotthoff
1
解决方案中的偏移量适用于我。谢谢Lars。现在我使用了Bootstrap列网格中的可视化,但偏移量并没有受到新位置的影响。我该如何解决这个问题? - Robin Wieruch
不确定,需要看到完整的例子。你可能想提出一个单独的问题来询问这个。 - Lars Kotthoff
2
我想到了这个代码:<code>var matrix = this.getScreenCTM().translate(+this.getAttribute("cx"),+this.getAttribute("cy"));tip.style("left", (window.pageXOffset + matrix.e) + "px").style("top", (window.pageYOffset + matrix.f + 30) + "px");</code> - Robin Wieruch

20

在这里找到一些东西,即使<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");
})

正是我所需要的。谢谢! - dorsh
接受的解决方案加上你的补充才算完整。 - Ashi

6
在我的经验中,最简单的解决方案如下:
首先使用getBoundingClientRect()获取您的元素位置。
然后使用window.pageYOffset相对于您的位置进行高度调整。
例如:
.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`);
})

在上面的例子中,我没有使用X的偏移量,因为我们很少需要它(除非您在水平滚动)。
添加window.pageYOffsetpos['y']可以给我们当前鼠标位置(不论我们在页面上的哪个位置)。我减去100是为了将工具提示放置在其上方一点。

1

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接