D3 - SVG 元素上的定位工具提示不起作用 [英] D3 - Positioning tooltip on SVG element not working

查看:26
本文介绍了D3 - SVG 元素上的定位工具提示不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有 SVG 的网页.在它的某些形状上,我需要显示工具提示.但是,我无法让工具提示出现在它应该出现的位置,只是与形状本身相距一些像素.

I have a webpage with an SVG. On some of its shapes I need to display a tooltip. However, I can't get the tooltip to appear where it should, just some pixels away from the shape itself.

它出现在屏幕的右侧,大约 300 像素远.我用来获取坐标的代码如下:

It appears way on the right hand side of the screen, maybe some 300px away. The code I am using to get the coordinates is as follows:

d3.select("body")
  .select("svg")
  .select("g")
  .selectAll("circle")
  .on("mouseover", function(){return tooltip.style("visibility", "visible");})
  .on("mousemove", function(){

var svgPos = $('svg').offset(),

/*** Tooltip ***/

//This should be the correct one, but is displaying at all working at all.
/*x = svgPos.left + d3.event.target.cx.animVal.value,
y = svgPos.top + d3.event.target.cy.animVal.value;*/


//This displays a tool tip but way much to the left of the screen.
x = svgPos.left + d3.event.target.cx.animVal.value,
y = svgPos.top + d3.event.target.cy.animVal.value;

Tooltip
window.alert("svgPos: "+svgPos+"        top: "+y+"px          left: "+x+"px     "+d3.event.target.cx.animVal.value);


return tooltip.style("top", x+"px").style("left",y+"px");
})
.on("mouseout", function(){return tooltip.style("visibility", "hidden");});

我按照 这个 SO 帖子.

我已经更改了 $(ev.target).attr(cx) 因为它没有在我的机器上返回值;d3.event.target.cx 是,尽管它似乎无论如何都不会影响最终结果.

I have changed $(ev.target).attr(cx) as it is not returning a value on my machine; d3.event.target.cx is, even though it seems it is not affecting the end result anyway.

我做错了什么?有人可以帮我吗?非常感谢您抽出宝贵时间.

What am I doing wrong? Could somebody help me please? Thank you very much in advance for your time.

推荐答案

如果你的工具提示是一个 HTML 元素,那么你希望它相对于页面整体定位,而不是内部 SVG 坐标,因此访问 cx/cy 值只是使事情复杂化.如果不查看您的代码,我不能肯定地说,但是如果您对 <svg><g> 元素进行了任何转换,那么这可能是是什么让你失望.

If your tooltip is an HTML element, then you want to position it relative to the page as a whole, not the internal SVG coordinates, so accessing the cx/cy value is just complicating things. I can't say for sure without looking at your code, but if you have any transforms on your <svg> or <g> elements, then that could be what's throwing you off.

但是,有一个更简单的解决方案.只需访问鼠标事件的默认 .pageX.pageY 属性,它们给出鼠标相对于 HTML 正文的位置,并使用这些坐标来定位您的工具提示 div.

However, there is a much easier solution. Just access the mouse event's default .pageX and .pageY properties, which give the position of the mouse relative to the HTML body, and use these coordinates to position your tooltip div.

示例:http://fiddle.jshell.net/tPv46/1/

关键代码:

.on("mousemove", function () {
    //console.log(d3.event);
    return tooltip
        .style("top", (d3.event.pageY + 16) + "px")
        .style("left", (d3.event.pageX + 16) + "px");
})

即使在 SVG 圆圈上进行旋转变换,鼠标也知道它在页面上的位置,工具提示也会相应地定位.

Even with rotational transforms on the SVG circles, the mouse knows where it is on the page and the tooltip is positioned accordingly.

还有其他方法可以做到这一点,包括让工具提示显示在相对于圆圈的固定位置而不是跟随鼠标四处走动,但我只是检查了我正在处理的示例并意识到它们不是交叉的- 浏览器兼容,所以我必须将它们标准化并回复你.与此同时,我希望这能让您的项目回到正轨.

There are other ways to do this, including getting a tooltip to show up in a fixed location relative to the circle instead of following the mouse around, but I just checked the examples I was working on and realized they aren't cross-browser compatible, so I'll have to standardize them and get back to you. In the meantime, I hope this gets you back on track with your project.

为了比较,这里是使用 HTML 工具提示(

For comparison, here is the same example implemented with both an HTML tooltip (a <div> element) and an SVG tooltip (a <g> element).

元素)和 SVG 工具提示( 元素)实现的相同示例).

http://fiddle.jshell.net/tPv46/4/

http://fiddle.jshell.net/tPv46/4/

默认鼠标事件坐标可能非常适合定位 的直接子元素的 HTML 元素,但它们对于定位 SVG 元素不太有用.d3.mouse() 函数计算应用所有转换后,当前事件相对于指定 SVG 元素坐标系的鼠标坐标.因此,它可用于以我们需要定位 SVG 工具提示的形式获取鼠标坐标.

Key code:

关键代码:

Note that it works even though I've scaled the SVG with a viewBox attribute and put the tooltip inside a <g> with a transform attribute.

请注意,即使我使用 viewBox 属性缩放 SVG 并将工具提示放入带有转换属性的 <g> 中,它也能工作.>

在 Chrome、Firefox 和 Opera(相当新的版本)中测试并运行——尽管根据您的字体设置,SVG 工具提示中的文本可能会超出其矩形.使用 HTML 工具提示的原因之一!另一个原因是它不会被 SVG 的边缘切断.

Tested and works in Chrome, Firefox, and Opera (reasonably recent versions) -- although the text in the SVG tooltip might extend past its rectangle depending on your font settings. One reason to use an HTML tooltip! Another reason is that it doesn't get cut off by the edge of the SVG.

如果您在 Safari 或 IE9/10/11 中有任何错误,请发表评论.(IE8 及以下不走运,因为他们不做 SVG).

Leave a comment if you have any bugs in Safari or IE9/10/11. (IE8 and under are out of luck, since they don't do SVG).

那么您最初的想法是将工具提示放在圆圈本身上呢?能够准确定位笔尖有一定的好处:更好的布局控制,文本不会随鼠标摆动.最重要的是,您只需在 mouseover 事件上将其定位一次,而不用对每个 mousemove 事件做出反应.

So what about your original idea, to position the tooltip on the circle itself? There are definite benefits to being able to position the tip exactly: better layout control, and the text doesn't wiggle around with the mouse. And most importantly, you can just position it once, on the mouseover event, instead of reacting to every mousemove event.

但是要做到这一点,您不能再仅仅使用鼠标位置来确定工具提示的放置位置——您需要确定元素的位置,这意味着您必须处理转换.SVG 规范引入了一组接口,用于定位相对于 DOM 其他部分的 SVG 元素.

But to do this, you can no longer just use the mouse position to figure out where to put the tooltip -- you need to figure out the position of the element, which means you have to deal with transformations. The SVG spec introduces a set of interfaces for locating SVG elements relative to other parts of the DOM.

要在两个 SVG 转换系统之间进行转换,请使用 SVGElement.getTransformToElement(SVGElement);要在 SVG 坐标系和屏幕之间进行转换,您可以使用 SVGElement.getScreenCTM().结果是变换矩阵,您可以从中提取净水平和垂直平移.

For converting between two SVG transformation systems you use SVGElement.getTransformToElement(SVGElement); for converting between an SVG coordinate system and the screen, you use SVGElement.getScreenCTM(). The result are transformation matrices from which you can extract the net horizontal and vertical translation.

SVG 工具提示的关键代码是

The key code for the SVG tooltip is

    var tooltipParent = SVGtooltip[0][0].parentNode;
    var matrix = 
            this.getTransformToElement(tooltipParent)
                .translate(+this.getAttribute("cx"),
                     +this.getAttribute("cy"));
    SVGtooltip
        .attr("transform", "translate(" + (matrix.e)
                  + "," + (matrix.f - 30) + ")");

HTML 工具提示的关键代码是

The key code for the HTML tooltip is

    var matrix = this.getScreenCTM()
            .translate(+this.getAttribute("cx"),
                     +this.getAttribute("cy"));

    absoluteHTMLtooltip
        .style("left", 
               (window.pageXOffset + matrix.e) + "px")
        .style("top",
               (window.pageYOffset + matrix.f + 30) + "px");

实例:http://fiddle.jshell.net/tPv46/89/

再次感谢可以在 Safari 或 IE 或任何移动浏览器中测试此功能的任何人的确认评论.我很确定我对所有东西都使用了标准 API,但仅仅因为 API 是标准的并不意味着它是普遍实现的!

Again, I'd appreciate a confirmation comment from anyone who can test this in Safari or IE -- or any mobile browser. I'm pretty sure I've used standard API for everything, but just because the API is standard doesn't mean it's universally implemented!

这篇关于D3 - SVG 元素上的定位工具提示不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆