2013-07-18 39 views
2

我是新的d3,我想知道是否可以使svg遵循樹的層次結構。使svg遵循分層結構

比方說,我有一個這樣的JSON:

{ 
     "name": "root", 
     "children": [ 
      { 
       "name" : "child1", 
       "children": [ 
        { 
         "name": "child1_1" 
        }, 
        { 
         "name": "child1_2" 
        } 
       ] 
      }, 
      { 
       "name": "child2", 
       "children": [ 
        { 
        "name": "child2_1" 
        }, 
        { 
         "name": "child2_2" 
        } 
       ] 
      } 
     ] 
} 

怎樣纔可以有一個SVG的結構是這樣的:

<g class="root"> 
    <g class="child1"> 
    <g class="child1_1"> 
    </g> 
    <g class="child1_2"> 
    </g> 
    </g> 
    <g class="child2"> 
    <g class="child2_1"> 
    </g> 
    <g class="child2_2"> 
    </g> 
    </g> 
</g> 

我已經試過類似的東西:

var w = 960, 
    h = 2000, 
    i = 0, 
    root; 

var diagonal = d3.svg.diagonal() 
    .projection(function(d) { return [d.y, d.x]; }); 

var vis = d3.select("#chart").append("svg:svg") 
    .attr("width", w) 
    .attr("height", h) 
    .append("svg:g") 
    .attr("transform", "translate(40,0)"); 

d3.json(
    './small_tree.json', 
    function(json) { 
     json.x0 = 800; 
     json.y0 = 0; 
     update(root = json); 
    } 
); 
function update(source) { 

    var nodes = tree.nodes(root); 
    var child = vis.selectAll('g.child_node') 
     .data(nodes,function(d){return d.children;}) 
     .enter() 
     .append('g') 
     .attr("class", "child_node"); 
} 

而且我得到了根節點的孩子的標籤,但我不知道如何遞歸地創建ch的嵌套組孩子的孩子。

任何人有想法?

感謝,

雷姆

+0

您是否嘗試過什麼自己了嗎?你不可能得到任何答案,如果這只是一個「爲我而做」的問題,而不是「我有這個代碼的問題,幫我修復它」 – tnw

+0

對不起,我應該從那開始...... – user2596192

回答

1

D3本身不處理遞歸,它看起來像標準的分層佈局不,在一般情況下,創建嵌套結構。相反,你需要遞歸你自己的代碼。這裏有一個實現:

// simple offset, just to make things visible 
var offset = 0; 

// recursion function 
function addNode(selection, depth) { 
    // set the current children as the data array 
    var nodeGroup = selection.selectAll('g.child_node') 
     .data(function(d) { return d.children }) 
    .enter() 
     // add a node for each child 
     .append('g') 
     .attr("class", "child_node") 
     // very simple depth-based placement 
     .attr("transform", "translate(" + (depth * 30) + "," + 
      (++offset * 15) + ")"); 

    nodeGroup.append("text") 
     .attr("dy", "1em") 
     .text(function(d) { return d.name }); 

    // recurse - there might be a way to ditch the conditional here 
    nodeGroup.each(function(d) { 
     if (d.children) nodeGroup.call(addNode, depth + 1); 
    }); 
} 

d3.json(
    './small_tree.json', 
    function(root) { 
     // kick off the recursive append 
     vis 
      .datum({ children: [root] }) 
      .call(addNode, 0); 
    } 
} 

見琴:http://jsfiddle.net/nrabinowitz/ELYWa/

+0

謝謝很多爲您的幫助! 您是否認爲這種組織會在爲大樹摺疊子樹時對性能有所幫助? – user2596192

+0

我不確定。大部分D3樹處理實際上都使用一個平面列表,並且只是將事物放置在一個層次佈局中,而不是嵌套結構 - 不知道哪一個更具性能。 – nrabinowitz