2015-02-23 79 views
0

一直在奮鬥的年齡到創建一個水平的樹形佈局與矩形而不是圓形,並有文本包裝在那些矩形內。我沒有做似乎工作,我已經試過this code但任何人制造它已經離開了關鍵的一步,在該行 if (d.name.length > 26)從停止運行整個腳本之前定義的變量dD3水平樹佈局與矩形和文字環繞

我也一直在努力,以包裹內rect標籤文字使用d3plus.js從http://d3plus.org/但它實際上不工作一半時間,似乎需要像click功能的觸發條件才能正常工作。同時考慮使用this example作爲文本換行的指南。

在我的研究我還沒有發現任何人做了水平,矩形的組合,在一個包裹圖表文本。 另外我有點d3 noob所以所有的幫助表示讚賞。

這裏是一個JSFiddle

下面是當前的代碼我使用的是不工作:

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

    var tree = d3.layout.tree() 
     .size([h, w - 160]); 

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

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

    root = treeData[0]; 
    root.x0 = h/2; 
    root.y0 = 0; 
    update(root); 
    function update(source) { 

     // Compute the new tree layout. 
     var nodes = tree.nodes(root).reverse(); 

     // Update the nodes… 
     var node = vis.selectAll("g.node") 
      .data(nodes, function(d) { return d.id || (d.id = ++i); }); 

     var nodeEnter = node.enter().append("svg:g") 
      .attr("class", "node") 
      .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; }); 


     // Enter any new nodes at the parent's previous position. 

     nodeEnter.append("svg:rect") 
      .attr("width", 150) 
      .attr("height", function(d) { return (d.name.length > 30) ? 38 : 19;}) 
      .attr("y",-11) 
      .attr("rx",2) 
      .attr("ry",2) 
      .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; }) 
      .on("click", click); 


      if (d.name.length > 26) { 

       nodeEnter.append("svg:text") 
        .attr("x", function(d) { return d._children ? -8 : 8; }) 
        .attr("y", 3) 
        .text(function(d) { return d.name; }); 

      } else { 
       nodeEnter.append("svg:text") 
       .attr("x", function(d) { return d._children ? -8 : 8; }) 
       .attr("y", 3) 
       .append("svg:tspan") 
       .text(function(d) { return d.name.slice(0,26); }) 
       .append("svg:tspan") 
       .attr("x", function(d) { return d._children ? -8 : 8; }) 
       .attr("y",15) 
       .text(function(d) { return d.name.slice(26); }); 

      } 
     } 
     // Transition nodes to their new position. 
     nodeEnter.transition() 
      .duration(duration) 
      .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; }) 
      .style("opacity", 1) 
     .select("rect") 

      .style("fill", "lightsteelblue"); 

     node.transition() 
      .duration(duration) 
      .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; }) 
      .style("opacity", 1); 


     node.exit().transition() 
      .duration(duration) 
      .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; }) 
      .style("opacity", 1e-6) 
      .remove(); 

     // Update the links… 
     var link = vis.selectAll("path.link") 
      .data(tree.links(nodes), function(d) { return d.target.id; }); 

     // Enter any new links at the parent's previous position. 
     link.enter().insert("svg:path", "g") 
      .attr("class", "link") 
      .attr("d", function(d) { 
       var o = {x: source.x0, y: source.y0}; 
       return diagonal({source: o, target: o}); 
      }) 
      .transition() 
      .duration(duration) 
      .attr("d", diagonal); 

     // Transition links to their new position. 
     link.transition() 
      .duration(duration) 
      .attr("d", diagonal); 

     // Transition exiting nodes to the parent's new position. 
     link.exit().transition() 
      .duration(duration) 
      .attr("d", function(d) { 
       var o = {x: source.x, y: source.y}; 
       return diagonal({source: o, target: o}); 
      }) 
      .remove(); 

     // Stash the old positions for transition. 
     nodes.forEach(function(d) { 
      d.x0 = d.x; 
      d.y0 = d.y; 
     }); 
    } 

    // Toggle children on click. 
    function click(d) { 
     if (d.children) { 
      d._children = d.children; 
      d.children = null; 
     } else { 
      d.children = d._children; 
      d._children = null; 
     } 
     update(d); 
    } 

    d3.select(self.frameElement).style("height", "2000px"); 

,以及我的JSON:

var treeData = [ 
    { 
     "name": "Do trainees require direction as to what to do or how to do the task (either before they start or while they are completing it?", 
     "children": [ 
     { 
      "name": "Can they satisfactorily complete the task assigned to them?", 
      "children": [ 
       { 
        "name": "Rating level 4", 
        "parent": "A", 
       }, 
       { 
        "name": "How many problems/queries are there that still need to be addressed/resolved to be able to satisfactorily complete the task?", 
        "children": [ 
       { 
        "name": "Are problems/queries fundamental to the completion of the task at hand?", 
        "children": [ 
       { 
        "name": "Rating level 4", 
       }, 
       { 
        "name": "Can the problems be resolved by the trainee (after receiving guidance)?", 
        "children": [ 
       { 
        "name": "Rating level 3", 
       }, 
       { 
        "name": "Can the problems be resolved by the trainee (after receiving guidance)?", 
        "children": [ 
       { 
        "name": "Rating level 2", 
       }, 
       { 
        "name": "Rating level 1", 
       } 
        ] 
       } 
        ] 
       } 
        ] 
       }, 
       { 
        "name": "Are problems/queries fundamental to the completion of the task at hand?", 
       } 
        ] 
       } 
      ] 
     }, 
     { 
      "name": "Can they satisfactorily complete the task assigned to them?", 
      "children": [ 
       { 
        "name": "Rating 1", 
       }, 
       { 
        "name": "Rating 2", 
       }, 
       { 
        "name": "Rating 3", 
       }, 
      { 
       "name": "Rating 4", 
      } 
      ] 
     } 
     ] 
    }]; 

回答

1

你的代碼拋出這一行錯誤:

if (d.name.length > 26) { 

d沒有定義。當d3代碼引用d時,通常在數據綁定的範圍內。在這個地方在代碼中,你是不是循環的結合,如:

nodeEnter.append("text") 
    .attr("x", function(d) { 
     return d._children ? -8 : 8; 
    }) 
    .attr("y", 3) 
    .attr("dy", "0em") 
    .text(function(d) { 
     return d.name; // d is defined from the binding 
    }); 

這麼說,我喜歡wrap功能您鏈接到。因此,添加text像上面,然後自動換行:

wrap(d3.selectAll('text'),150); 

這裏有一個快速修改該會重新調整你的rects以及包裹:

function wrap(text, width) { 
    text.each(function() { 
    var text = d3.select(this), 
     words = text.text().split(/\s+/).reverse(), 
     word, 
     line = [], 
     lineNumber = 0, 
     lineHeight = 1.1, // ems 
     y = text.attr("y"), 
     dy = parseFloat(text.attr("dy")), 
     tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em"); 
    while (word = words.pop()) { 
     line.push(word); 
     tspan.text(line.join(" ")); 
     if (tspan.node().getComputedTextLength() > width) { 
     line.pop(); 
     tspan.text(line.join(" ")); 
     line = [word]; 
     tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word); 
     } 
    } 
    // find corresponding rect and reszie 
    d3.select(this.parentNode.children[0]).attr('height', 19 * (lineNumber+1)); 

    }); 
} 

here

+0

你可能挽救了我的生命,我將盡快嘗試。 – 2015-02-23 20:12:31

+0

這工作!有沒有辦法縮短初始路徑(從原點),以便它們不會伸展得那麼遠,有點像這樣http://blog.pixelingene.com/2011/07/building-a-tree-diagram-在-D3-JS / – 2015-02-23 21:58:15