score:8

d3 will never extend a line beyond the final data point. However, the appearance of the line, and how the data points are connected, depends on the interpolator setting for d3.svg.line.

For a simple example, imagine you only had two points (10,20) and (15,30).

The normal ("linear") interpolator would draw a straight line between them.

The "step-after" interpolator starts at the first point (10,20), and draws a horizontal line out to the x-value of the second-point (i.e., to (15,20) ), then draws a vertical line up to (15,30). The result: the first value is shown as a horizontal line that is held constant until the second value applies.

In contrast, the "step-before" interpolator starts at the first point (10,20), and draws a vertical line up to the y-value of the second-point (i.e., to (10,30) ), then draws the horizontal line to (15,30). The result: the first value is shown only as the starting point of the vertical step, with the second value being shown as held constant during the time in between.

Finally, the "step" interpolator changes y-values half-way between the two x-values. The result is that both start values and end values are shown as horizontal line lasting for half the distance between them.

Here's a comparison of the different line interpolator options:
http://fiddle.jshell.net/c2mru/1/

I think what would look best for you is if you:

  • use the "step" interpolator function
  • set the x-values for the line to be the middle of your horizontal bars.

You do this by changing

 var line = d3.svg.line()
        .defined(function (d) { return d.value != null; })
        .x(function (d, i) {                
            return x(d.xValue);
        })
        .y(function (d) {
            return y(d.value);
        }).interpolate("step-after");

to

 var line = d3.svg.line()
        .defined(function (d) { return d.value != null; })
        .x(function (d, i) {                
            return x(d.xValue) + x.rangeBand()/2;
        })
        .y(function (d) {
            return y(d.value);
        }).interpolate("step");

This will result in a line that starts at the mid-point of your first bar and ends at the mid-point of your last bar, but clearly shows the value at each bar with a horizontal line.

If your really must have the line start and end at the very end of your range, then you have two options:


Related Query

More Query from same tag