2012-09-14 2 views
21

나는 그래프를 가지고 있고, 그래프를 나타내는 선이 svg 영역 위에 올 때 x 좌표에 원을 표시하기를 원합니다. 이 원은 곡선을 나타내는 선의 경로를 따라야합니다. 문제는이 작업을 수행하는 방법을 모른다는 것입니다.d3.js에서 경로의 y 좌표를 반환하려면 어떻게해야합니까?

아래 코드는 내가 얼마나 succeded했는지를 보여주고 실제로 문서를 오른쪽 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"); 
    }); 

답변

25

SVG는 그것을 전달되는 길이 x 및 경로의 y 값 다시 발생 .getPointAtLength()라는 기본 기능을 제공합니다.

해당 y 위치를 찾을 때까지 줄의 길이를 반복해야합니다. 당신은 여기에서 데모를 볼 수 있습니다

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

: http://bl.ocks.org/3824661

+0

내가이 임의의 타임 라인 스타일의 경로 형태, 예를 들어, 작동하지 않습니다 확신 다음은 D3에 그것을 할 것입니다 방법입니다 한 점에서 매우 날카로운 스파이크가있는 선은 경로 길이와 x 위치 사이의 선형 보간을 허용하지 않습니다. – nrabinowitz

+0

@nrabinowitz는 http://jsfiddle.net/FPfFJ/을 테스트하기에 충분히 간단하고 그렇습니다. – Duopixel

+0

그래,이 경우 정확하게 .getPointAtLength()를 사용하여 정확한 점을 얻는 유일한 방법은'x' 값이'd3.event.pageX'에 가까운 점을 찾을 때까지 행을 검색하는 것입니다 . – nrabinowitz

관련 문제