Dinesh Singh
Dinesh Singh

Reputation: 41

In d3.js , Is there any way to get the path length at particular point?

I am new to d3.js , I can find that d3 api provides the way to get the svg point at particular length via method getPointAtLength(l) but i am looking for a way to calculate the the path length at specific point in d3?

Please share your suggestion if any.

Upvotes: 3

Views: 3925

Answers (1)

Henry S
Henry S

Reputation: 3112

There's no simple way to do this, like the SVG getPointAtLength method. However it is easy to get the total length of a path using getTotalLength().

Given that, the option I would suggest is to draw a new path, that follows the existing path up to the new point.

This is a working example: http://jsfiddle.net/henbox/b4bbgdnz/5/

Hovering the mouse over a selected point on the existing thin black path causes a 'sub-path' to be drawn (in red) up to the selected point. The text below shows the selected coordinates and the length of the path from (0,0), the first point to it.

showing path and sub path for length calculations

Here I assume that points along the x axis are ordered, so that when I get the mouseover x-value from the event handler, I know that any points where x is lower than this value should be inculded in the sub-path. I add these points, plus the mouseover point coords, to a new array from which the sub-path will be created:

for (var i = 0; i < pathData[0].length; i++) {
    var coord = pathData[0][i];
    if ((coord.x <= mouse_coord.x)) {
        subPathData[0].push(coord);
    }
}

subPathData[0].push(mouse_coord); 

Then I calculate the length of the subpath:

subpath_length = d3.select(".subpath")[0][0].getTotalLength();

A note on interpolation

The approach works when not using line interpolation. However it will fail if you replace, for example, .interpolate("none"); with .interpolate("monotone"); in the jsfiddle. That's because the sub-path won't follow the full path correctly in some cases, like this:

showing how this method fails with interpolation

A solution that always worked on interpolated lines would probably be a lot more complicated

Upvotes: 5

Related Questions