How do I return y coordinate of a path in d3.js?

后端 未结 1 1048
借酒劲吻你
借酒劲吻你 2020-11-30 02:22

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 t

相关标签:
1条回答
  • 2020-11-30 03:00

    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.

    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:

    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

    0 讨论(0)
提交回复
热议问题