Javascript ale将像素转换为由my d3.scale函数设置的x/y值 function findYatX(x,path,error){ var length = apath.getTotalLength() , point = path.g

Javascript ale将像素转换为由my d3.scale函数设置的x/y值 function findYatX(x,path,error){ var length = apath.getTotalLength() , point = path.g,javascript,graphics,svg,d3.js,Javascript,Graphics,Svg,D3.js,ale将像素转换为由my d3.scale函数设置的x/y值 function findYatX(x,path,error){ var length = apath.getTotalLength() , point = path.getPointAtLength(length) , bisection_iterations_max=50 , bisection_iterations = 0 error = error || 0.1

ale将像素转换为由my d3.scale函数设置的x/y值

function findYatX(x,path,error){
    var length = apath.getTotalLength()
        , point = path.getPointAtLength(length)
        , bisection_iterations_max=50
        , bisection_iterations = 0
    error = error || 0.1
    while (x < revXscale(point.x) -error || x> revXscale(point.x + error) {
        point = path.getPointAtlength(length)
        if (x < revXscale(point.x)) {
             length = length/2
        } else {
             length = 3/2*length
        }
        if (bisection_iterations_max < ++ bisection_iterations) {
              break;
        }
    }
return revYscale(point.y)
}
函数findYatX(x,路径,错误){
var length=apath.getTotalLength()
,point=path.getPointAtLength(长度)
,二等分迭代次数最大值=50
,二等分迭代次数=0
误差=误差| | 0.1
而(xrevXscale(point.x+error){
点=路径。getPointAtlength(长度)
如果(x
看起来像是一个棘手的问题,因为d3 is为您计算中间值。如果使用和d3.geom.polygon的组合,您可能会更幸运……您是否能够从svg容器中选择线(例如通过id),并获取其
x1
x2
y1
y2
属性?(如果我误解了你的问题,我很抱歉)看起来像是一个棘手的问题,因为d3是为你计算中间值的。如果使用和d3.geom.polygon的组合,你可能会更幸运……你能选择线吗(例如,通过id)从svg容器中获取其
x1
x2
y1
y2
属性?(如果我误解了您的问题,我很抱歉)除非我误解了文档,否则这是不正确的-你不会在
x=3
处得到点,你会在
pathLength=3
处得到点,这可能会根据路径的形状而变化很大。@nrabinowitz-yikes,你说得很对。不确定我是怎么误读的。我会在找到真正的解决方案后编辑我的答案。谢谢。我很好确保插值线的唯一解决方案是搜索
。getPointAtLength(i)
,直到
Math.abs(i-x)
小于某个阈值。二进制搜索在这里可能相当有效。我会自己发布答案,但我没有时间:).Yah,这也是我所能想到的。见编辑后的帖子。非常感谢@nrabinowitz。看看我的答案。它非常快O(log(n))你可以设置精度/错误。除非我误解了文档,否则这是不正确的-你不会在
x=3
处得到点,你会在
pathLength=3
处得到点,这可能会根据路径的形状变化很大。@nrabinowitz-yikes,你是对的。不确定我是如何误读的。我将在找到一个真正的解决方案。谢谢。我非常确定插值线的唯一解决方案是搜索
。getPointAtLength(I)
,直到
Math.abs(I-x)
小于某个阈值。二进制搜索可能在这里工作得相当好。我自己会发布答案,但我没有时间:)。耶,这也是我所能想到的。见编辑后的文章。非常感谢@nrabinowitz。看看我的答案。这是非常快的O(log(n)),你可以设置精度/误差。我认为你的算法在某些情况下会非常糟糕。而且它似乎比二分法有更多的迭代次数。例如,如果你的长度是100,而你的点是90,那么你的算法将执行:1)90<100 so长度=100/2=50 2)90>50 so长度=50*1.5=75 3)90>75 so长度=75*1.5=112.5 4)90<112.5 so长度=112.5/2=56.5 5 5)90>56.5 so长度=56.5*1.5=84.75 6)90>84.75 so长度=84.75*1.5=127.125 7)90<127.125 so长度=127.125/2=63.5625正如你所见,你的算法有时只是在跳跃,甚至超过了初始长度。我认为你的算法在某些情况下会非常糟糕。而且它似乎比二分法有更多的迭代次数。例如,如果你的长度是100,而你的点是90,那么你的算法将执行:1)90<100 so长度=100/2=50 2)90>50 so长度=50*1.5=75 3)90>75 so长度=75*1.5=112.5 4)90<112.5 so长度=112.5/2=56.5 5 5)90>56.5 so长度=56.5*1.5=84.75 6)90>84.75 so长度=84.75*1.5=127.125 7)90<127.125 so长度=127.125/2=63.5625正如您看到的,您的算法有时只是在跳跃,甚至超过初始长度。当路径之间有空值时,这不起作用..就像我们使用D3的line.undefined函数一样伟大!非常好,比公认的解决方案快得多!因此,它适用于鼠标悬停或滚动事件。谢谢:)您帮助methis在路径之间存在空值时不起作用..就像我们使用D3的line.undefined函数一样棒极了!非常好,比公认的解决方案快得多!所以它适合鼠标悬停或滚动活动。谢谢:)你帮了我
// Line
var line = d3.svg.line()
     .interpolate("basis")
     .x(function (d) { return i; })
     .y(function(d, i) { return 100*Math.sin(i) + 100; });

// Append the path to the DOM
d3.select("svg#chart") //or whatever your SVG container is
     .append("svg:path")
     .attr("d", line([0,10,20,30,40,50,60,70,80,90,100]))
     .attr("id", "myline");

// Get the coordinates
function findYatX(x, linePath) {
     function getXY(len) {
          var point = linePath.getPointAtLength(len);
          return [point.x, point.y];
     }
     var curlen = 0;
     while (getXY(curlen)[0] < x) { curlen += 0.01; }
     return getXY(curlen);
}

console.log(findYatX(5, document.getElementById("myline")));
var findYatXbyBisection = function(x, path, error){
  var length_end = path.getTotalLength()
    , length_start = 0
    , point = path.getPointAtLength((length_end + length_start) / 2) // get the middle point
    , bisection_iterations_max = 50
    , bisection_iterations = 0

  error = error || 0.01

  while (x < point.x - error || x > point.x + error) {
    // get the middle point
    point = path.getPointAtLength((length_end + length_start) / 2)

    if (x < point.x) {
      length_end = (length_start + length_end)/2
    } else {
      length_start = (length_start + length_end)/2
    }

    // Increase iteration
    if(bisection_iterations_max < ++ bisection_iterations)
      break;
  }
  return point.y
}
function findYatX(x,path,error){
    var length = apath.getTotalLength()
        , point = path.getPointAtLength(length)
        , bisection_iterations_max=50
        , bisection_iterations = 0
    error = error || 0.1
    while (x < revXscale(point.x) -error || x> revXscale(point.x + error) {
        point = path.getPointAtlength(length)
        if (x < revXscale(point.x)) {
             length = length/2
        } else {
             length = 3/2*length
        }
        if (bisection_iterations_max < ++ bisection_iterations) {
              break;
        }
    }
return revYscale(point.y)
}