你只需要在绘图方法中更新y轴比例尺的范围即可。缩放函数将修改关联的比例尺并设置它们的域以模拟缩放。因此,例如,您可以通过执行x.invert(0)和x.invert(width)来获取x可见数据范围。如果您将数据转换为使用日期而不是字符串,则我建议您使用此方法进行过滤,这可能更有效率。虽然目前,您仍然可以使用x比例尺来筛选出可见数据,找到这些值的y轴极限,并相应地设置y比例尺的域。实际上,您只需在缩放更新回调中添加几行代码即可完成这些操作。
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();
您可以在这里尝试它。
为了更好地解释发生了什么:
缩放行为侦听鼠标事件并修改相关比例尺的范围。
比例尺由轴使用,它们将它们作为带有刻度线的线绘制,并且您在回调中设置的路径和区域的数据也使用比例尺。
因此,当缩放更改时,它会触发回调,基本方法就是您所拥有的:
svg.select("g.x.axis").call(xAxis);
svg.select("g.y.axis").call(yAxis);
svg.select("path.area").attr("d", area);
svg.select("path.line").attr("d", line);
我们重新绘制了x轴和y轴,并使用新更新的域重新绘制(重新计算)区域和线条 - 同时使用新的x和y比例尺。因此,为了获得所需的行为,我们取消了y轴上的默认缩放行为,而是在缩放或平移时自己修改y轴的域:方便的是,由于缩放行为,我们已经有了回调函数。计算y比例尺域的第一步是找出哪些数据值可见。x轴已配置为输出0到宽度的范围,缩放行为已更新x比例尺的域,以使原始域的仅子集输出到此范围。因此,我们使用JavaScript数组的filter方法仅提取那些映射将它们放在我们可见范围内的数据对象:
data.filter(function(d) {
var dt = x(d.date);
return dt > 0 && dt < width;
}
然后我们使用方便的d3 extent方法返回一个包含最小值和最大值的数组。但由于我们的数组都是对象,所以我们需要一个访问器函数,以便extent方法有一些数字可以进行比较(这是D3中常见的模式)。
d3.extents(filteredData, function(d) { return d.value; });
所以,现在我们知道了当前x轴比例尺下绘制的所有数据点的最小值和最大值。最后一步就是设置y轴比例尺的域并像往常一样继续操作!
y.domain(yExtent).nice()
我在
api中找到了一个不错的方法,因为它是你想要一个比例尺做的事情,而d3通常会帮你完成一些你想要做的事情。
一个很好的教程来解决一些东西是:
http://alignedleft.com/tutorials/
即使是你认为已经知道的部分,也值得逐步学习。