Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to limit a d3 line-chart from showing the line outside of the range of the axis?

Tags:

d3.js

I have a d3 line chart with a time-based x-axis. I want to show 2 days worth of data, going from the last measurement (as in: the latest in time) to 2 days before that, even if there is more data than that. This works.

To allow the user to see the data that doesn't appear, I have a zoom behaviour (which doesn't allow zooming, only panning on the x-axis). This also works.

The issue I now face is that when I have data that goes out of the range of the axis (either the x or the y axis), it's still plotted up to the boundary of the svg. I want to limit the visible line to the area of the svg bounded by the axis.

I've got a fiddle here, where you can see the issue. Data is shown left of the x-axis and higher than the maximum value of the y-axis, neither is desired. I'm not sure why it's doing this, or how I can stop it. E.g. my y scale:

yScale = d3.scale.linear().domain([41.5, 34.5]),

But when a value 43 is given, it still tries to plot it. Same issue on the x-axis. I'm sure it must be possible to limit the data that is shown, because this guy managed it. Unfortunately I haven't found the code with which the lower 2 charts on that page are being generated.

like image 417
mcProgrammer Avatar asked Mar 03 '16 20:03

mcProgrammer


Video Answer


2 Answers

You can limit which points are displayed using defined

Every sample gets passed through the function and where it returns false, the points aren't shown...

var line = d3.line()
    .defined(function(d) { 
       return d.x < xMax && dx > xMin && d.y > yMin && d.y< yMax; 
    })
    .x(function(d) { return x(d.x); })
    .y(function(d) { return y(d.y); });

Alternatively, you can use a clip-path like in this example.

like image 198
Tim Avatar answered Sep 29 '22 07:09

Tim


What i did was, I divided the data values by multiples of 10 through trial and error. I think d3 would just plot data out of it's range if it's too large, because once I divided the values they were scaled perfectly.

.append("circle")
                    .attr('cx', d => xScale(d.foreign_investement/10000))
                    .attr('cy', d => yScale(d.earnings/1000))
However, my data was fixed and I was not planning to scale up my graph. The clipPath would be the ideal solution for me too but I don't know how to use it yet.
like image 40
theBird Avatar answered Sep 29 '22 07:09

theBird