完整代码位于jsfiddle。 问题是当顶部和底部图表中的缩放鼠标移动不匹配时,即底部的移动圆圈不应超出通过刷涂选择的区域。我正在更新移动点,如下所示:
focus.on "mousemove", () ->
xPos = d3.mouse(this)[0]
updateMovingPoints(xPos)
context.on "mousemove", () ->
xPos = d3.mouse(this)[0]
updateMovingPoints(xPos)
如您所见,底部鼠标悬停与顶部图表不匹配,即超出缩放区域。
答案 0 :(得分:1)
我的解决方案主要使用AmeliaBR的建议将xPos从一个x-scale转换为另一个x-scale,我使用xScale(xScale2.invert(xPos))
进行转换,然后将此修改后的x位置传递给updateMovingPoints
scale.invert
从原始数据(文档here)中获取日期,我们可以立即重新缩放,以使用不同的比例转换为SVG x坐标
这是小提琴:http://jsfiddle.net/henbox/pusauc5q/10/
首先,我将updateMovingPoints
函数拆分为两个updateMovingPointsTop
和updateMovingPointsbottom
,因为更新底部(上下文)图表总是很容易,而更新顶部(焦点)是棘手的一点。
updateMovingPointsTop = (xPos) ->
focusLine1 = focus.select(".line1").attr("d", line1(data))
focusLine2 = focus.select(".line2").attr("d", line2(data))
updatePointPosition(xPos, focusLine1, focusCircles[0])
updatePointPosition(xPos, focusLine2, focusCircles[1])
updateMovingPointsBottom = (xPos) ->
contextLine1 = context.select(".line1").attr("d", line3(data))
contextLine2 = context.select(".line2").attr("d", line4(data))
updatePointPosition(xPos, contextLine1, contextCircles[0])
updatePointPosition(xPos, contextLine2, contextCircles[1])
然后,只有当鼠标移动到底部(上下文)时,我才想进行一些计算,以找出底部xPos
应该如何转换为顶部x-scale:
updateMovingPointsTop(calculatexPosTop(xPos))
calculatexPosTop
函数本身有一些注释要解释。但基本上它将xPos
从底部x刻度转换为顶部x刻度,并且如果它位于边界之外,则设置为该顶部刻度的最小\最大范围。在定义比例时,边界由range
计算:
# The min and max extents (x coords) of the 'context' (top chart)
xScaleTopRange = xScale.range()
minExtent = xScaleTopRange[0]
maxExtent = xScaleTopRange[1]
密钥calculatexPosTop
函数如下所示:
# When mousemoving on the bottom chart, calculate where the equivaluent point is on the top chart
calculatexPosTop = (xPos) ->
# The translation of the 'context' x-scale (xScale2) to the 'focus' x-scale (xScale)
# Note that when there's no zooming, xScale and xScale2 are the same so xPosInFocusScale = xPos
xPosInFocusScale = xScale(xScale2.invert(xPos))
# Check if the translated point lies outside the extents of the focus scale's range
if xPosInFocusScale < minExtent
minExtent
else if xPosInFocusScale > maxExtent
maxExtent
else
xPosInFocusScale
修改强>
我意识到我错过了解决方案的一部分:当放大时,沿顶部图表移动并未将点保持在拉丝区域内。小提琴链接现在更新了此修复程序。
这涉及添加另一个与calculatexPosBottom
非常相似的函数calculatexPosTop
,但我没有使用scale.range
来获取最大和最小范围,而是使用brush.extent()
brushed
用于查找拉丝区域的“大小”:
# Get the x-limits of the brush
brushExtent = brush.extent()
# Convert using the x-scale to get SVG coordinates
minBrushExtent = xScale2(brushExtent[0])
maxBrushExtent = xScale2(brushExtent[1])
...然后我使用刷子min \ max范围,如下所示:
calculatexPosBottom = (xPos) ->
xPosInContextScale = xScale2(xScale.invert(xPos))
# Check if there is no brushed area (ie the extent is [0, 0])
# The brush extent is defined in the 'brushed' function
if minBrushExtent == maxBrushExtent
# If there is no brush, just use the same points on both scales
xPos
else if xPosInContextScale < minBrushExtent
minBrushExtent
else if xPosInContextScale > maxBrushExtent
maxBrushExtent
...