d3js line chart — how to extend last step to end of range?

大憨熊 提交于 2019-12-12 14:13:18

问题


It's simple, but I can't get rid of the problem.

A line is a link between two points (values) and is drawn from value A to value B. So let's say A has value 10, B has value 20 and C is missing. The line is now drawn from 0 to 10 to 20 and finished. I want to draw the line from 0 to 10 to 20 to 25. Value is ment as the scale of the x-axis (0, 10, 20, 30, 40). Is this possible without changing the beginning of my line, so it still starts at the zero-point of the x-axis?

Without drawing a additional line from 20 to 25 of course :)

The code of my line:

 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");

thx in advance

Here two pictures. The first one, how it looks like now, and the second one, how it should look like.


(source: www.axi.at)


(source: www.axi.at)

©a-x-i (d3js is driving my crazy, but it's cool....)


回答1:


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:

  • Create a custom interpolation function; or,
  • Add an "end-value" data point when you pass your data array to d3.svg.line.


来源:https://stackoverflow.com/questions/21185198/d3js-line-chart-how-to-extend-last-step-to-end-of-range

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!