mcProgrammer
mcProgrammer

Reputation: 373

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

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.

Upvotes: 9

Views: 6294

Answers (2)

theBird
theBird

Reputation: 61

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.

Upvotes: 1

Tim
Tim

Reputation: 8186

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.

Upvotes: 7

Related Questions