2014-09-03 57 views
1

完整的代碼在jsfiddle。 問題是當放大頂部和底部圖表中的鼠標懸停不匹配時,即在底部移動圓圈不應超出通過刷牙選擇的區域。我更新的移動要點如下:Focus +上下文通過刷鼠標放大問題

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

enter image description here

正如你看到的,底部的鼠標懸停不匹配上圖,即超越放大區域。

+0

增加了圖片,使之更容易理解。 – 2014-09-09 10:33:32

+0

一眼就可以看出您沒有使用正確的縮放比例來在鼠標點和數據值之間進行轉換。如果鼠標懸停在主圖上,則給出的'xPos'將具有與鼠標懸停在焦點圖上不同的含義,並且不會將該信息傳遞給'updateMovingPoints'方法。 – AmeliaBR 2014-09-09 17:34:44

+0

謝謝你的迴應。我會嘗試在mouseover上使用不同比例的底部圖表。 – 2014-09-10 13:29:46

回答

1

我的解決方法基本上是採用AmeliaBR的建議到XPOS從一個X級轉換爲其他的,這一點我用用xScale(xScale2.invert(xPos)),然後通過這個修改的X位置updateMovingPoints

scale.invert在D3的時間尺度變回從原始數據(文檔here),我們可以迅速地重新規模,日期轉換爲SVG使用不同的比例

這裏x座標是小提琴:http://jsfiddle.net/henbox/pusauc5q/10/

首先我分裂updateMovingPoints函數分成兩個updateMovingPointsTopupdateMovingPointsbottom,因爲更新底部(上下文)圖表總是很容易,而更新頂部(焦點)是棘手的一點。

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 
    ... 
+0

謝謝你的回覆。我還在挖掘AmeliaBR提出的[方向](http://stackoverflow.com/questions/25654621/focuscontext-via-brushing-mouseovers-zoom-issue#comment40265081_25654621)。所以我認爲,自從我收集了一些有用的想法和方法以來,您的帖子值得賞金。讓我們等一等,也許有更多的見解或優雅的解決方案。 – 2014-09-11 21:53:11

+0

謝謝ovvn。我也覺得這裏可能會有更多的優雅,但它還沒到我身上呢!我改進了一下我的方法(更新的解決方案和小提琴鏈接),以便以更合理的方式得到'brush.extent()' - 只有在刷新區域被刷新(被刷新的函數調用)每次鼠標移動!應該提高性能。 – 2014-09-12 10:11:36