Javascript 焦点+;通过刷鼠标的方式显示上下文缩放问题

Javascript 焦点+;通过刷鼠标的方式显示上下文缩放问题,javascript,svg,d3.js,zooming,Javascript,Svg,D3.js,Zooming,完整的代码在中。 问题是当缩放上下图表中的鼠标指针不匹配时,即底部的移动圆不应超出通过刷牙选择的区域。我正在更新移动点,如下所示: focus.on "mousemove", () -> xPos = d3.mouse(this)[0] updateMovingPoints(xPos) context.on "mousemove", () -> xPos = d3.mouse(this)[0] updateMovingPoints(xP

完整的代码在中。 问题是当缩放上下图表中的鼠标指针不匹配时,即底部的移动圆不应超出通过刷牙选择的区域。我正在更新移动点,如下所示:

  focus.on "mousemove", () ->
     xPos = d3.mouse(this)[0]
     updateMovingPoints(xPos)
  context.on "mousemove", () ->
     xPos = d3.mouse(this)[0]
     updateMovingPoints(xPos)


如您所见,底部鼠标盖与顶部图表不匹配,即超出了缩放区域。

我的解决方案基本上使用AmeliaBR的建议将XPO从一个x比例转换为另一个x比例,我使用
xScale(xScale2.invert(xPos))
,然后将修改后的x位置传递给
updateMovingPoints

D3时间标度上的
scale.invert
从原始数据(文档)返回日期,我们可以立即重新缩放,以使用不同的标度将其转换为SVG x坐标

这是小提琴:

首先,我将
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])
然后,只有在底部(上下文)移动鼠标时,我才想进行一些计算,以找到底部
xpo
应如何转换为顶部x刻度:

updateMovingPointsTop(calculatexPosTop(xPos))
calculateExpostop
函数本身有一些注释需要解释。但基本上,它将
xPos
从底部的x比例转换为顶部的x比例,并将顶部比例的范围设置为最小\最大(如果它位于边界之外)。定义刻度时,根据
范围
计算边界:

# The min and max extents (x coords) of the 'context' (top chart)
xScaleTopRange = xScale.range()
minExtent = xScaleTopRange[0]
maxExtent = xScaleTopRange[1]
calculateExpostop
函数如下所示:

# 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 = (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
    ...
。。。然后我使用笔刷最小\最大范围,如下所示:

# 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 = (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
    ...
exposbottom=(xPos)->
xPosInContextScale=xScale2(xScale.invert(xPos))
#检查是否没有拉丝区域(即范围为[0,0])
#笔刷范围在“刷过”功能中定义
如果minBrushExtent==maxBrushExtent
#如果没有画笔,只需在两个刻度上使用相同的点即可
xPos
否则,如果xPosInContextScalemaxBrushExtent
最大范围
...

添加了一张图片,使其更易于理解。乍一看,您似乎没有使用正确的比例在鼠标点和数据值之间进行转换。如果鼠标位于主图形上方,give
xPos
的含义将与鼠标位于焦点图形上方的含义不同,并且您不会将该信息传递给
updateMovingPoints
方法。感谢您的回复。我会尝试在鼠标上方使用不同的刻度来绘制底部图表。我会采取稍微不同的方法。缩放区域将始终与上面图表的宽度相对应。当缩放时,我会得到相对于缩放区域左侧的鼠标XPO,然后从中计算上部图表XPO。感谢您的回复。我还在挖掘AmeliaBR提出的建议。所以我认为你的帖子值得赏金,因为我收集了一些有用的想法和方法。让我们稍等一下,也许会有更多的见解或优雅的解决方案。谢谢ovvn。我也觉得这里可能会有更多的优雅,但我还没有意识到这一点!我对我的方法做了一些改进(更新了解决方案和fiddle链接),以便以更合理的方式获得
brush.extent()
——仅当重新绘制笔刷区域时(
brushed
函数调用),而不是每次鼠标移动时!应该提高绩效。