2016-04-26 64 views
1

我有在D3.js如何改變徑向樹的根在D3.js

與我的徑向樹問題

我希望把所選擇的節點(上單擊)的中心徑向樹,並讓整個樹適應這個新的設置。在我更新功能,我可以根設置爲選擇的節點:

root = source; 

但是這隻能說明所選節點和孩子,但我想有父(及其子女)所選擇的節點之上以及底部選定節點的子節點。

我試過的是從父項的子項數組中刪除選定的節點。然後將這個已更改的父項作爲所選節點的子項,但這會產生遞歸錯誤。

var index = source.parent.children.indexOf(source); 
source.parent.children.splice(0, 1); 
source.parent.parent = source; 
source.children.push(source.parent); 

的完整代碼here

我希望得到任何幫助或指示的。

謝謝

+0

您嘗試過的方法很好,它必定是您的函數中的一個問題。你能分享你試過的功能的代碼嗎? – tarulen

+0

我已經添加了我在帖子中提到的代碼。 –

+0

你想只在樹中選擇節點的父節點,還是隻有父節點等,直到原始根節點? – tarulen

回答

0

這裏是一個遞歸函數照顧重排:

function makeRoot(source) { 
    if (!source.parent) return; //nothing to do if source is already root 

    makeRoot(source.parent); //flip the higher branches recursively so that the parent becomes root of the tree 

    var index = source.parent.children.indexOf(source); 
    source.parent.children.splice(index, 1); //corrected here: you need to remove the right element from the children list 
    source.parent.parent = source; 
    source.children.push(source.parent); 
    delete source.parent; //added: now that the original parent is linked, make source the root of the tree 
} 

我不知道如何強制原始節點的孩子被吸引到南部和在北邊休息。首先要做的事情是到知道每個節點必須在哪一邊(這很容易:默認情況下所有節點都是「北」的),然後在撥打makeRoot之前訪問source的子樹,並告訴它們是「南」)。但之後,我對d3的樹佈局不夠熟悉,無法執行「北/南」約束。


更新爲南北走向,你可以嘗試以下方法:

  • 保持指針oldParent=source.parent到所選擇的節點
  • 一旦佈局完成後的原始父,在更新svg之前,計算offsetX= 90- oldParent.x(父位置和北軸之間的差異 - 注意:我不確定北軸是90°,但它應該是0,90,180或270中的一個。只是嘗試所有;))
  • 轉變周圍的所有節點通過offsetX量(保持在0和359之間的夾角):

    nodes.forEach(function(d) { 
        d.x = (d.x + offsetX) % 360; 
    }); 
    
  • ,那麼你可以更新SVG:整個樹應當使原來的母公司點北旋轉。 ..這應該足以獲得你想要的視覺效果。


更新#2另一種方法,使南北排列。

見小提琴這裏:https://jsfiddle.net/qo4w0ktn/4/

的想法是計算最左邊和最右邊,最葉片的角度,原來的兒童中,並旋轉整個圖,直到平均南這兩個角度點。這意味着您需要跟蹤樹中的「原始」孩子,這是通過我的d.real_children屬性完成的。功能leftmostLeafrightmostLeaf很簡單(請參閱小提琴)。

function rotateSouth(source, nodes) { 
    var lx = leftmostLeaf(source); 
    var rx = rightmostLeaf(source); 

    if (lx>rx) rx += 360; //this happens if the interval overlap angle 0 

    var offsetX= 180- (lx+rx)/2; //the median point (=(lx+rx)/2) should be pushed south (=180) 

    nodes.forEach(function(d) { 
     d.x = (d.x + offsetX) % 360; //rotate every node by the same offset 
    }); 
    } 
+0

太好了,謝謝你D3天才! 對於最後一部分,關於旋轉整棵樹,你能給我一些提示嗎? –

+0

以下是您的小提琴的暫定更新:https://jsfiddle.net/qo4w0ktn/2/ ....我在makeRoot中添加了「奇偶校驗」功能,讓祖先的樹左右交替(平均而言,挺直的),但結果並不如預期那麼好。我會嘗試更多的f 012 – tarulen

+0

@AnasHelalouch看到我的第二個更新。我認爲這回答你的原始問題,剩下的是修復線條圖(已倒轉的鏈接向後拉),但總體結構應該沒問題。 – tarulen