Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In d3, how to get the interpolated line data from a SVG line?

I display a line chart with D3 with roughly the following code (given the scale functions x, y and the float array data):

 var line = d3.svg.line()
         .interpolate("basis")
         .x(function (d, i) { return x(i); })
         .y(function (d) { return y(d); });
 d3.select('.line').attr('d', line(data));

Now I want to know the vertical height of the line at a given horizontal pixel position. The data array has lesser data points than pixels and the displayed line is interpolated, so it is not straight-forward to deduce the height of the line at a given pixel just from the data array.

Any hints?

like image 562
Phae7rae Avatar asked Jul 16 '12 11:07

Phae7rae


1 Answers

This solution is much more efficient than the accepted answer. It's execution time is logarithmic (while accepted answer has linear complexity).

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
}
like image 170
bumbu Avatar answered Sep 21 '22 07:09

bumbu