2012-11-30 111 views
5

我的目標是使用d3強制佈局來顯示共享相同節點的兩個不同網絡。例如,在四個人當中,你可以定義一個社交網絡和一個家譜網絡;節點將是相同的(人),但鏈接(關係)可能不同。 儘管創建了兩個單獨的力佈局,兩個單獨的svg畫布,並試圖定義單獨的變量,節點共享x和y位置信息。這裏是一個小例子,在拖動一個網絡上的節點改變等網絡中的位置: http://amath.colorado.edu/student/larremore/nodesSharingPositiond3在同一頁面上的多個d3強制佈局實例

下面,我貼被稱爲創造了網絡的一個功能,和代碼來創建其他非常相似,但在所有情況下使用不同的變量名稱。用於創建兩個網絡的註釋代碼可在http://amath.colorado.edu/student/larremore/nodesSharingPositiond3/lib/minimal.js中找到,用於定義變量的腳本可在/driver/minimalScript.js中找到。< - 我沒有足夠的信譽來直接鏈接它。我很抱歉!

d3.force的工作方式,位置信息是全球性的,或被全球選中,或某事。任何人都可以闡明這一點嗎?我對保持位置信息分離的解決方案以及理解d3.force如何處理和更新位置計算感興趣。

function makeYNet() { 

// This populates the YactiveLinks variable with the proper YLinks. The goal is to be able to only display links whose value is above some threshold. 
for (var i=0; i<YLinks.length; i++) { 
    if (YLinks[i].link2 > thr) { 
     YactiveLinks.push(YLinks[i]); 
    } 
} 

// Add nodes and links to forceY 
forceY 
.nodes(YNodes) 
.links(YactiveLinks); 

// Draw lines 
var Ylink = svgY.selectAll("line.link") 
.data(YactiveLinks) 
.enter() 
.append("line") 
.attr("class", "link") 
.style("stroke-width", 2.0); 

// Draw nodes 
var Ynode = svgY.selectAll("circle.node") 
.data(YNodes) 
.enter().append("circle") 
.attr("class", "node") 
.attr("r", radius) 
.attr("high",0) 
.attr("id", function(d,i) { 
     return ("idy" + i); 
     }) 
.style("fill", function(d) { return color(d.group1); }) 
.call(forceY.drag) 
; 

// Define tick 
forceY.on("tick", function() { 
      Ylink 
      .attr("x1", function(d) { return d.source.x; }) 
      .attr("y1", function(d) { return d.source.y; }) 
      .attr("x2", function(d) { return d.target.x; }) 
      .attr("y2", function(d) { return d.target.y; }); 

      Ynode.attr("cx", function(d) { return d.x; }) 
      .attr("cy", function(d) { return d.y; }); 
      }); 

// Start 'er up 
forceY.start(); 
} 
+0

我正在嘗試做同樣的事情:在同一頁上同步兩個強制佈局的節點位置。由於Alex Reynolds的回覆,我有兩個部隊佈局。但是,我沒有在哪裏設置位置同步的鉤子。由於到DBLaremore的方法的鏈接不再工作,有沒有人有暗示從哪裏開始或可能鏈接到另一個例子? – tty56

回答

4

我寫了一個工具,允許瀏覽生物regulatory networks,顯示兩個SVG面板並排。每個面板都包含一個由d3.js API繪製的強制佈局網絡。

我發現使這項工作的關鍵是給DOM中的每個元素一個唯一的名稱,在那裏可以重複。

在我的情況下,我使用_left_right作爲每個面板元素的足夠,其中元素分別在左側或右側面板中。跟蹤記錄需要很多工作,但網絡渲染器可以將其呼叫和事件定位到正確的元素和網絡。

你的情況:

.attr("id", function(d,i) { 
     return ("idx" + i); 
     }) 

您想更換return價值的東西,唯一解決該節點關聯的網絡。無論您使用索引編號方案還是基於後綴的方法(如我一樣),訣竅在於確保所有名稱都是唯一的。

+0

你的網站的例子是一個很好的模仿 - 看起來很棒!但是,我無法通過更改ID來解決我的問題。我嘗試過使用不同的ID,以及沒有ID,並且在這兩種情況下,顯示屏仍然互相更新。我已經檢查過左側(X)和右側(Y)的名稱在佈局,節點,鏈接和svg畫布的名稱上有所不同。還有其他建議嗎?我不知道這是否相關,但如果您拖動並保持一個網絡足夠長的時間,另一個網絡會冷卻/凍結,然後不再鏈接(顯然)。 – DBLarremore

+0

我不知道還有什麼可行的。我確實知道,確保每個網絡中的每個元素都是唯一的,這是做這項工作的關鍵。如果有任何重複的'id'名稱,事情就會中斷。希望我能更多的幫助! –

+0

我注意到的另一件事(可能)提供了一條線索: 經過一段時間/耗散後,佈局將凍結當前位置的節點。如果您抓住左側佈局並左右移動,直到右側凍結,您將無法間接移動右側佈局。然後,如果您抓住正確的佈局,則只能使用它來影響左側的**,直到左側凍結。對我而言,這意味着雖然佈局的位置可能受到影響,但製冷計時器不受該運動的影響。節點在兩個圖中移動,但只有一個寄存器動態。 – DBLarremore

0

JavaScript是混淆狀態是否共享的臭名昭着。你最小的例子不再可用,但當我遇到同樣的問題時,我的結論是,我只是在需要完整克隆的地方製作淺拷貝。 (我說的是關於D3作爲輸入的鏈路和節點。)

沒有一個真正的副本,所產生的行爲會有點亂,因爲你發現,這取決於D3代碼是否據法權產修改任何共享數據「原位」還是不。一般來說,出於性能原因,D3嘗試而不是來創建副本。

這就是json調用解決方法的原因:通過將所有數據完全字符串化,實際上是強制執行克隆操作。