javascript 如何在 d3.js 中返回路径的 y 坐标?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12431595/
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
How do I return y coordinate of a path in d3.js?
提问by Jimmy C
I have a graph, and I want the line representing the graph to show a circle at the x coordinate when hovering on top of the svg area. This circle should follow the path of the line that represents the curve. The problem is that I don't know how to do this.
我有一个图形,我希望表示图形的线在悬停在 svg 区域顶部时在 x 坐标处显示一个圆圈。这个圆圈应该沿着代表曲线的线的路径。问题是我不知道该怎么做。
The code below shows how far I have succeded, and it indeed adds a circle to the document at the right x coordinate. Now, what do I replace the question mark with?
下面的代码显示了我成功了多远,它确实在文档的右侧 x 坐标处添加了一个圆圈。现在,我用什么替换问号?
svg.on("mousemove", function() {
d3.select("path.line")
.style("stroke-width", "2.5px");
svg.append("svg:circle")
.attr("cx", Math.floor(event.offsetX-m[1]))
.attr("cy", ?)
.attr("r", "10")
.attr("fill", "red");
});
回答by methodofaction
SVG provides a native function called .getPointAtLength()
which returns a the x and y values of a path at any length you pass at it.
SVG 提供了一个被调用的本机函数.getPointAtLength()
,该函数返回您传递给它的任何长度的路径的 x 和 y 值。
You would need to iterate through the length of the line until you find the corresponding y position. Here is how you would do it in D3:
您需要遍历线的长度,直到找到相应的 y 位置。以下是您在 D3 中的做法:
var svg = d3.select("#line").append("svg")
var path =
svg.append("path")
.attr("d", "M0,168L28,95.99999999999997L56,192L84,71.99999999999997L112,120L140,192L168,240L196,168L224,48L252,24L280,192L308,120L336,24L364,168L392,95.99999999999997L420,168L448,95.99999999999997L476,192L504,71.99999999999997L532,120L560,192L588,216L616,168L644,48L672,24L700,192L728,120L756,24L784,192L812,71.99999999999997")
.attr("fill", "none")
.attr("stroke", "black");
var circle =
svg.append("circle")
.attr("cx", 100)
.attr("cy", 350)
.attr("r", 3)
.attr("fill", "red");
var pathEl = path.node();
var pathLength = pathEl.getTotalLength();
var BBox = pathEl.getBBox();
var scale = pathLength/BBox.width;
var offsetLeft = document.getElementById("line").offsetLeft;
var randomizeButton = d3.select("button");
svg.on("mousemove", function() {
var x = d3.event.pageX - offsetLeft;
var beginning = x, end = pathLength, target;
while (true) {
target = Math.floor((beginning + end) / 2);
pos = pathEl.getPointAtLength(target);
if ((target === end || target === beginning) && pos.x !== x) {
break;
}
if (pos.x > x) end = target;
else if (pos.x < x) beginning = target;
else break; //position found
}
circle
.attr("opacity", 1)
.attr("cx", x)
.attr("cy", pos.y);
});
You can see a demo here: http://bl.ocks.org/3824661
你可以在这里看到一个演示:http: //bl.ocks.org/3824661