我的解決方法基本上是採用AmeliaBR的建議到XPOS從一個X級轉換爲其他的,這一點我用用xScale(xScale2.invert(xPos))
,然後通過這個修改的X位置updateMovingPoints
scale.invert
在D3的時間尺度變回從原始數據(文檔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])
這樣,只有在底部(上下文)mousemoving的時候,我想要做一些計算找到底部xPos
應如何翻譯成頂的X級:
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])
...然後我用畫筆最小\最大程度上是這樣的:
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
...
增加了圖片,使之更容易理解。 – 2014-09-09 10:33:32
一眼就可以看出您沒有使用正確的縮放比例來在鼠標點和數據值之間進行轉換。如果鼠標懸停在主圖上,則給出的'xPos'將具有與鼠標懸停在焦點圖上不同的含義,並且不會將該信息傳遞給'updateMovingPoints'方法。 – AmeliaBR 2014-09-09 17:34:44
謝謝你的迴應。我會嘗試在mouseover上使用不同比例的底部圖表。 – 2014-09-10 13:29:46