D3.js does not change the scalable y axis from zero

I have a graph with zoom features. My main observation was that the X axis updated the scale based on my current zoom value. I would like the y axis to do this too, so zoom.y(y) enabled, the undesirable side affects the fact that now the user can zoom out in all directions, even to negative values ​​"below" the graph.

http://jsfiddle.net/ericps/xJ3Ke/5/

var zoom = d3.behavior.zoom().scaleExtent([0.2, 5]) .on("zoom", draw); apparently does not account for the y axis. And the user can still drag the chart in any direction to infinity.

One of the ideas that I was thinking about was independent of the inclusion of the zoom.y (y) function and simply required a redrawing of the y axis based on the fact that it is in the currently visible range. Like some kind of redrawing based only on the position of the X axis. I don’t want everything to scroll up and down now, only left and right.

except comments //zoom.y(y) how to do this? Insight is appreciated.

+4
source share
1 answer

All you have to do is update the y-domain in the drawing method.

The scaling function will change the associated scales and set their domain to simulate scaling. This way you can get your visible data borders x, for example, using x.invert (0) and x.invert (width). If you convert your data to use Date instead of strings, then this is what I suggest you use for filtering, it will probably be more efficient.

Be that as it may, you can still use the x scale to filter your visible data, find the extents of the y axis of these values, and set the corresponding y scale domain. And in fact, you can do all this with just a few lines (in the zoom update callback):

 var yExtent = d3.extent(data.filter(function(d) { var dt = x(d.date); return dt > 0 && dt < width; }), function(d) { return d.value; }); y.domain(yExtent).nice(); 

You can try here

To better explain what is happening:

The zoom effect listens for mouse events and changes the range of related scales.

Scales are used by axes, which draw them as lines with ticks, and scales are also used by data related to your paths and areas, as you configured them in callbacks.

Therefore, when the scale changes, it calls the callback, and the main method is what you had:

 svg.select("gxaxis").call(xAxis); svg.select("gyaxis").call(yAxis); svg.select("path.area").attr("d", area); svg.select("path.line").attr("d", line); 

we redraw the x and y axes with newly updated domains, and we redraw (resell) the region and line - also with the newly dominated x- and y-scales.

Thus, in order to get the desired behavior, we will cancel the default zoom behavior on the y scale, and instead we will change the y zoom range itself when we get the zoom or pan: we already have a callback for these actions due to the zoom behavior.

The first step to compute our scale domain is to find out what data values ​​are visible. The x axis has been configured to output in the range of 0 to width, and the scaling behavior has updated the x-domain, so only a subset of the source domain will go out of that range. Therefore, we use the javascript array filtering method to pull out only those data objects whose display puts them in our visible range:

 data.filter(function(d) { var dt = x(d.date); return dt > 0 && dt < width; } 

Then we use the convenient length method d3 to return the min and max values ​​to the array. But since our array is all objects, we need the accessor function, so the extents method has some values ​​for actual comparison (this is a common template in D3)

 d3.extents(filteredData, function(d) { return d.value; }); 

So now we know the minimum and maximum values ​​for all data points that are drawn based on our current x scale. The last bit is just to set the zoom area y and continue as usual!

 y.domain(yExtent).nice(); 

A good method I found in api , because this is what you need to do the scale, and d3 often does what you want to do for you.

A great tutorial for finding out some of these things: http://alignedleft.com/tutorials/ It’s worth going through the parts that you think you already know.

+11
source

All Articles