如何向 svg 图形添加工具提示?

2022-08-30 05:24:25

我有一系列svg矩形(使用D3.js),我想在鼠标悬停时显示一条消息,消息应该被一个充当背景的框包围。它们应该彼此完全对齐,并与矩形完全对齐(在顶部和居中)。最好的方法是什么?

我尝试使用“x”,“y”,“宽度”和“高度”属性添加svg文本,然后在svg正方形之前添加一个svg文本。问题是文本的参考点在中间(因为我希望它居中对齐,所以我使用了),但对于矩形,它是左上角的坐标,加上我想要在文本周围留一点边距,这使得它有点痛苦。text-anchor: middle

另一个选项是使用html div,这很好,因为我可以直接添加文本和填充,但我不知道如何获取每个矩形的绝对坐标。有没有办法做到这一点?


答案 1

你能简单地使用SVG<title>元素和它传达的默认浏览器渲染吗?(注意:这与html中可以在div / img / spans上使用的属性不同,它需要是一个名为titletitle)

rect {
  width: 100%;
  height: 100%;
  fill: #69c;
  stroke: #069;
  stroke-width: 5px;
  opacity: 0.5
}
<p>Mouseover the rect to see the tooltip on supporting browsers.</p>

<svg xmlns="http://www.w3.org/2000/svg">
  <rect>
    <title>Hello, World!</title>
  </rect>
</svg>

或者,如果您真的想在SVG中显示HTML,则可以直接嵌入HTML:

rect {
  width: 100%;
  height: 100%;
  fill: #69c;
  stroke: #069;
  stroke-width: 5px;
  opacity: 0.5
}

foreignObject {
  width: 100%;
}

svg div {
  text-align: center;
  line-height: 150px;
}
<svg xmlns="http://www.w3.org/2000/svg">
  <rect/>
  <foreignObject>
    <body xmlns="http://www.w3.org/1999/xhtml">
      <div>
        Hello, <b>World</b>!
      </div>
    </body>      
  </foreignObject>
</svg>

...但是你需要JS来打开和关闭显示器。如上所示,使标签显示在正确位置的一种方法是将矩形和 HTML 包装在相同的位置,将它们放在一起。<g>

要使用JS查找SVG元素在屏幕上的位置,您可以使用,例如 http://phrogz.net/svg/html_location_in_svg_in_html.xhtmlgetBoundingClientRect()


答案 2

我发现的唯一好方法是使用Javascript来移动工具提示。显然,这只有在HTML文档中有SVG时才有效 - 而不是独立的。它需要Javascript。<div>

function showTooltip(evt, text) {
  let tooltip = document.getElementById("tooltip");
  tooltip.innerHTML = text;
  tooltip.style.display = "block";
  tooltip.style.left = evt.pageX + 10 + 'px';
  tooltip.style.top = evt.pageY + 10 + 'px';
}

function hideTooltip() {
  var tooltip = document.getElementById("tooltip");
  tooltip.style.display = "none";
}
#tooltip {
  background: cornsilk;
  border: 1px solid black;
  border-radius: 5px;
  padding: 5px;
}
<div id="tooltip" display="none" style="position: absolute; display: none;"></div>

<svg>
  <rect width="100" height="50" style="fill: blue;" onmousemove="showTooltip(evt, 'This is blue');" onmouseout="hideTooltip();" >
  </rect>
</svg>