D3 - SVG元素上的定位工具提示无效 [英] D3 - Positioning tooltip on SVG element not working

查看:1084
本文介绍了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.

它在屏幕右侧出现,也许约300px。
我用来获取坐标的代码如下:

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

我得到这个代码 this SO post

我改变了$(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> / code>元素,那么这可能是引发你的原因。

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工具提示(< div> 元素)和SVG工具提示(a < g> / code>元素)。

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

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

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

The default mouse event coordinates may be great for positioning HTML elements that are direct children of <body>, but they are less useful for positioning SVG elements. The d3.mouse() function calculates the mouse coordinates of the current event relative to a specified SVG element's coordinate system, after all transformations have been applied. It can therefore be used to get the mouse coordinates in the form we need to position an SVG tooltip.

键码:

.on("mousemove", function () {


    var mouseCoords = d3.mouse(
        SVGtooltip[0][0].parentNode);
    //the d3.mouse() function calculates the mouse
    //position relative to an SVG Element, in that 
    //element's coordinate system 
    //(after transform or viewBox attributes).

    //Because we're using the coordinates to position
    //the SVG tooltip, we want the coordinates to be
    //with respect to that element's parent.
    //SVGtooltip[0][0] accesses the (first and only)
    //selected element from the saved d3 selection object.

    SVGtooltip
        .attr("transform", "translate(" + (mouseCoords[0]-30)
                  + "," + (mouseCoords[1]-30) + ")");

    HTMLtooltip
        .style("top", (d3.event.pageY + 16) + "px")
        .style("left", (d3.event.pageX + 16) + "px");
})

注意,即使我将SVG缩放为 viewBox 属性,并将工具提示放在具有transform属性的< g> 中。

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.

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

那么,你的原始想法,将工具提示放置在圆圈本身呢?有确切的好处是能够精确定位尖端:更好的布局控制,并且文本不摇摆与鼠标。最重要的是,你可以在鼠标悬停事件上放置一次,而不是对每个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天全站免登陆