Get y coordinate of point along SVG path with given an x coordinate
Asked Answered
G

2

10

I am using raphael.js to draw a simple SVG line graph like this:

line graph

When the user hovers the graph, id like to display a popover pointing to the line at the X position of the cursor, and at the Y position where the line is for that X position like so:

cursors with popovers along the line

I need to take the path and find the Y coordinate for a given X coordinate.

Guilder answered 22/3, 2013 at 19:12 Comment(3)
I made this in D3, but it should be easily transferred to Raphael: bl.ocks.org/duopixel/3824661Aubyn
@Duopixel That's actually the answer. You should post it as an answer.Flypaper
Link is dead, but fortunately it was archived: web.archive.org/web/20181011120958/http://bl.ocks.org/duopixel/…Quintin
N
18

Based on @Duopixel's D3 solution, I wrote the following function for my own use, in pure javascript using DOM API:

function findY(path, x) {
  var pathLength = path.getTotalLength()
  var start = 0
  var end = pathLength
  var target = (start + end) / 2

  // Ensure that x is within the range of the path
  x = Math.max(x, path.getPointAtLength(0).x)
  x = Math.min(x, path.getPointAtLength(pathLength).x)

  // Walk along the path using binary search 
  // to locate the point with the supplied x value
  while (target >= start && target <= pathLength) {
    var pos = path.getPointAtLength(target)

    // use a threshold instead of strict equality 
    // to handle javascript floating point precision
    if (Math.abs(pos.x - x) < 0.001) {
      return pos.y
    } else if (pos.x > x) {
      end = target
    } else {
      start = target
    }
    target = (start + end) / 2
  }
}
Neri answered 22/12, 2017 at 2:59 Comment(0)
C
0

If you know all the points of your path, it might be more performant to search the d attribute of your path for the specific x coordinate you are looking for, and retrieve the y coordinate using regexp:

const regex = new RegExp(`${x} ((\d*.\d*))`)
const match = regex.exec(d)

If you want to find the y of and arbitrary x coordinate not in your paths d attribute, you could loop through all the coordinates of your path and find the x coordinate that is closest to the one you're looking for. Not sure if that would be faster than stepping through the path and calling getPointAtLength though.

Caines answered 12/11, 2019 at 10:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.