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.