2013-03-05 80 views
4

我有一个带缩放功能的图形。我的主要观察结果是x轴根据我当前的缩放级别更新了其比例。我希望Y轴也这样做,所以启用zoom.y(y),不希望的副作用是现在用户可以在所有方向上缩小,甚至在图的“下方”为负值。d3.js保持可缩放的y轴不低于零

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

var zoom = d3.behavior.zoom().scaleExtent([0.2, 5]) .on("zoom", draw);似乎并没有真正采取y轴的考虑。用户仍然可以在任何方向将图表拖动到无穷远处。

我想到的一个想法是独立于启用了zoom.y(y),并且只需要根据它在当前可见范围内的内容重新绘制y轴。就像基于X轴位置的某种重绘一样。我现在不想上下滚动,只能左右移动

除了注释掉//zoom.y(y)这个怎么做? Insight深表谢意。

回答

11

您需要做的就是更新绘图方法中的y比例域。

缩放功能将修改关联的比例尺并将其域设置为模拟缩放。例如,您可以通过执行x.invert(0)和x.invert(width)来获得x可见数据边界。如果您将数据转换为使用Date而不是字符串,那么这是我建议您使用的过滤器,它可能会更有效。

尽管如此,仍然可以使用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(); 

你可以尝试一下here

为了更好地解释这是怎么回事:

缩放行为监听鼠标事件并修改相关比例的范围。

这些比例尺被轴线用来绘制它们作为具有刻度线的线条,并且比例尺也被用于与您的路径和区域相关的数据,就像您在回调中设置它们一样。

所以当变焦改变它激发的回调和基本方法是你有什么:

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阵列的滤波方法拔出只有那些数据对象,它们的映射使他们在我们的可见范围:

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

然后我们使用得心应手D3程度方法返回的最大值和最小值在数组中。但是,由于我们的阵列中的所有对象,我们需要一个访问功能,使得该范围的方法有一些数字实际的比较(这是D3的通用模式)

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

所以,现在我们知道所有的最小值和最大值根据我们当前的x比例绘制数据点。最后一点就是设置y尺度的域并继续正常!

y.domain(yExtent).nice(); 

的不错方法,我在api发现,因为这是你想要的比例做那种事情,D3经常做的事情为你,你想做的事情。

找出这些东西的一个很好的教程是:http://alignedleft.com/tutorials/ 即使你认为你已经知道的部分也值得一试。

+1

这对我来说“行得通”,但我仍然不完全明白。我真的不明白的是,你如何熟悉d3库,这些教程并不是那么直观的 – CQM 2013-03-05 21:09:23

+1

有一个明确的转变思考D3如何工作的方式。我认为它的核心是映射数据,而不是组件。所以做映射会把所有东西放在一起作为一个副作用......无论如何,我会编辑答案来尝试解释更好的情况。 – Superboggly 2013-03-06 19:49:28

+0

我刚刚意识到,相比之下,该函数使图形根据视口中当前数据集的最低值创建y轴和路径。我希望它在y轴上始终为零,但不能低于零。我如何在这里修改你的函数 – CQM 2013-04-04 18:02:01