2014-10-20 183 views
1

an example我們可以點擊一個圓圈並看到內圈。
也有不同的力佈局的例子。無限放大力佈局d3.js

是否可以有一個力佈局,它的每個節點將會/可以是一個具有內力佈局的圓?
因此,它將作爲這些圓圈的無限縮放(帶有額外的數據加載)。

歡迎任何想法/例子。

+2

是的,這是可能的。您需要將力量和包裝佈局結合起來。 [本教程](http://www.delimited.io/blog/2013/12/19/force-bubble-charts-in-d3)不是那樣,但可能有所幫助。 – 2014-10-20 14:43:02

+0

謝謝,@LarsKotthoff,但也許有這些的一些例子?在每個例子中,所有數據一次加載。我需要動態加載它在一個特定的縮放級別... – Andron 2014-10-20 16:35:45

+0

我不知道任何具體做你要找的例子。 – 2014-10-20 17:12:29

回答

1

我會這樣處理這個問題:從一個教程開始(也許this one,因爲它構建了一些使用圓圈打包進行初始化的東西),構建一個強制定向佈局。添加D3的縮放行爲。

var force = d3.layout.force() 
// force layout settings 

var zoom = d3.behavior.zoom() 
// etc. 

到目前爲止,這麼好。除了強制佈局喜歡在[width/2, height/2]附近閒逛外,如果你圍繞着[0, 0]居中,它會使縮放變得更容易。與geometric zooming戰鬥一段時間,直到你意識到這個問題真的需要semantic zooming。實現語義縮放。去喝杯咖啡。

找出您的圈子大小和縮放級別之間的關係,可以讓您知道何時需要揭示下一個級別。類似這樣的:

// expand when this percent of the screen is covered 
var coverageThreshold = 0.6; 
// the circles should be scaled to this size 
var maxRadius = 20; 
// the size of the visualization 
var width = 960; 
// which means this is the magic scale factor 
var scaleThreshold = maxRadius/(coverageThreshold * width) 
// note: the above is probably wrong 

現在,實現一個空間數據過濾器。當你放大時,你基本上想要隱藏任何已縮小視圖的數據點,這樣你就不會浪費GPU時間來計算它們的表示。另外,找出一個算法來確定用戶正在放大哪個節點。這很好,可能會使用Voronoi tessalation。學習方式比你想象的更需要幾何。

我們需要解決的另一個數學問題。我們將讓子節點代替父節點,所以我們需要根據父節點的總大小來縮放它們的大小。這會很煩人,需要調整才能正確使用,除非你知道正確的算法......我不知道。

// size of the parent node 
var parentRadius = someNumberPossiblyCalculated; 
// area of the parent node 
var parentArea = 2 * Math.PI * parentRadius; 
// percent of the the parent's area that will be covered by children 
// (here be dragons) 
var childrenCoverageRatio = 0.8; 
// total area covered by children 
var childrenArea = parentArea * childrenCoverageArea; 
// the total of the radiuses of the children 
var childTotal = parent.children 
    .map(radiusFn) 
    .reduce(function(a, b) { return a + b; }); 

// the child radius function 
// use this to generate the child elements with d3 
// (optimize that divide in production!) 
var childRadius = function(d) { 
    return maxRadius * radiusFn(d)/childTotal; 
}; 
// note: the above is probably wrong 

好的,現在我們已經準備好了製作魔法醬的作品了。在zoom處理程序中,針對您的參考點檢查d3.event.scale。如果用戶已經放大過去吧,請執行以下步驟非常迅速:

  • 隱藏父元素是關閉屏幕
  • 刪除被放大到
  • 父節點添加子節點在父的X和Y位置是父佈局的
  • 明確運行force.tick()的時間屈指可數讓孩子移開一點
  • 可能使用循環包裝設計,使這個過程更清潔

好的,所以現在我們有一個很好的小縮放佈局。放大時,您會達到一定的閾值,希望通過可視化代碼自動計算。當你這樣做時,你放大的節點「爆炸」到所有它的組成節點中。

現在弄清楚如何構建代碼,以便您可以「重置」事情,讓您繼續放大並再次發生。這可能是遞歸的,但將尺度縮小几個數量級並同時將SVG元素擴大反比因子可能會更清晰。

Now zooming out。首先,你需要一個明顯的縮放閾值來控制逆向過程,這是控制器中的滯後效應,如果有人騎着鼠標滾輪,這將有助於防止可視化。你放大並擴大,然後你必須再縮小一點,然後再縮小。

好吧,當您點擊縮小閾值時,您只需放下子元素並將父元素添加回到子元素位置的質心。

var parent.x = d3.mean(parent.children, function(d) { return d.x; }); 
var parent.y = d3.mean(parent.children, function(d) { return d.y; }); 

而且,你縮小開始展示你而放大躲在那些節點。

正如@Lars提到的,這可能會需要一點時間。