2017-01-09 267 views
1

我想製作一個時間軸,用戶可以選擇滾動縮放或選擇要縮放的區域。 有第一喜歡的一些例子: https://bl.ocks.org/mbostock/4015254 或者與刷面積放大: https://bl.ocks.org/mbostock/f48fcdb929a620ed97877e4678ab15e6
但我無法找到兩者兼具的例子。我怎樣才能做到這一點?或者有沒有我錯過的例子?d3的可拖動和縮放時間軸

+0

以下我的評論有幫助嗎? – HamsterHuey

+0

不,我無法實現它。但是現在我專注於考試,所以我沒有時間花費超過1天的時間。 –

回答

0

這不是最直接的實施。您會注意到,基於筆刷的縮放不依賴於d3.zoom,而是通過監聽器執行縮放,該監聽器觸發事件​​以執行縮放軸並相應移動繪圖元素所需的任何操作。

相比較而言,所有基於滾動變焦實例一般依賴於d3.zoom其利用d3.zoom()行爲跟蹤,同時搖攝/變焦和是用於更新各種圖表元素單獨負責在圖上執行的所有變換。難點在於2種方法完全不同,如果您通過刷子手動更改圖表視圖,則需要找出一種方法來更新d3.zoom引用的內部縮放轉換,以便它瞭解通過刷新所做的更改基於畫筆的縮放事件。

這並非易事,因爲d3.zoom並非設計用於從別處獲取信息,而且執行的轉換的內部記錄不意味着可更新/可變。您可以通過selection.call(zoom.transform, d3.zoomIdentity);更新轉換,但不幸的是,它還會觸發與實際縮放行爲有關的大量事件,這不是您想要的,因爲您已經使用基於筆刷的縮放處理了所有縮放行爲。一個醜陋的,但有效的解決辦法,我是可以使用重置縮放轉換是突變綁定到d3.zoom行爲DOM節點的實際.__zoom領域如下:

// WARNING: Ugly mutation of __zoom property of pan/scroll-zoom rect to 
// reset the transform without having to fire events associated with zoom 
// d3.select(".zoom").node().__zoom = {k: 1, x: 0, y: 0}; <-- Fails since __zoom contains other hidden objects 
scrollZoom.node().__zoom["k"] = 1; 
scrollZoom.node().__zoom["x"] = 0; 
scrollZoom.node().__zoom["y"] = 0; 

因此,例如:如果你需要一個用於矩形縮放的二維刷子,而且基於d3.zoom的縮放用於平移和鼠標滾動,隨後在任何時候使用二維刷子進行縮放時,都需要將d3.zoom轉換重置爲上述的標識轉換。當由於記錄變換而造成的平移/鼠標滾動操作鏈接基於2D畫筆的縮放操作時,這可以防止平移/滾動響應中的抖動和粗糙抖動,d3.zoom與顯示的視圖不同步(由於2D畫筆在沒有d3.zoom的知識的情況下改變視圖)。

這裏是別的,重要的是要注意的:

d3.zoom有一個限制,它目前只支持一個共同的縮放比例爲X和Y軸(Source)。這不幸意味着無法將基於二維刷子的縮放映射到基於d3.zoom的方法,因爲基於2D刷子的縮放會在X和Y中產生不同的縮放比例。如果您想用最少的問題進行操作,請使用一致的方法,我建議您使用d3.xyzoom進行調查。這是d3.zoom的一個分支,它實現了對X和Y軸的不同比例的支持。這將使您能夠計算任何2D畫筆選擇的相應X和Y縮放比例和平移值,然後您可以將它們輸入到d3.zoom中,從而使您可以使用常用方法執行所有縮放(這也會導致最小量代碼重複)。這就是說,如果你只對一維基於筆刷的縮放感興趣,你應該能夠將它映射到d3。縮放方式,以便您不必處理2種不同的路徑,以處理圖表中所有軸和其他圖形元素的視圖和縮放。這裏是一個很好的例子:

https://bl.ocks.org/mbostock/34f08d5e11952a80609169b7917d4172

我這個職位的長度道歉,如果這是一個有點散漫。我正在努力在幾天內將我的工作放在一塊,我會盡量繞圈回來,併發佈一個鏈接,當我這樣做。我一週前纔開始學習D3,所以我一直在學習。