2013-12-04 3 views
1

Привет, я очень новый t D3JS, и я пишу визуализацию дерева. У меня возникают трудности с изменением макета дерева от горизонтального до вертикального (сверху вниз). Я могу успешно отображать узлы по вертикали, но ссылки всегда горизонтальны. Любая помощь будет назначена. Спасибо.Изменение макета дерева в D3JS

Вот мой код:

var m = [20, 120, 20, 120], 
     w = 1280 - m[1] - m[3], 
     h = 800 - m[0] - m[2], 
     i = 0, 
     root; 


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

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

    var vis = d3.select("#visualize") 
     .append("svg:svg") 
     .attr("width", w + m[1] + m[3]) 
     .attr("height", h + m[0] + m[2]) 
     .append("svg:g") 
     .attr("transform", "translate(" + m[3] + "," + m[0] + ")"); 

    d3.json("flare.json", function(json) { 
     root = json; 
     root.x0 = h/2; 
     root.y0 = 0; 

     function toggleAll(d) { 
     if (d.children) { 
      d.children.forEach(toggleAll); 
      toggle(d); 
     } 
     } 

     // Initialize the display to show a few nodes. 
     root.children.forEach(toggleAll); 

     update(root); 
    }); 

    function update(source) { 
     var duration = d3.event && d3.event.altKey ? 5000 : 500; 

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

     // Normalize for fixed-depth. 
     nodes.forEach(function(d) { d.y = d.depth * 180; }); 

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

     // Enter any new nodes at the parent's previous position. 
     var nodeEnter = node.enter().append("svg:g") 
      .attr("class", "node") 
      .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; }) 
      .on("click", function(d) { toggle(d); update(d); }); 

     nodeEnter.append("rect") 
     .attr("y", function(d) { return d.children || d._children ? -5 : -5; }) 
     .attr("width","9") 
     .attr("height","9") 
     .style("fill", function(d) { return d._children ? "skyblue" : "#fff"; }) 
     .style("stroke","green") 
     .style("stroke-width", "1.5px"); 

     nodeEnter.append("svg:text") 
      .attr("x", function(d) { return d.children || d._children ? -10 : 10; }) 
      .attr("dy", ".35em") 
      .attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; }) 
      .text(function(d) { return d.name; }) 
      .style("fill-opacity", 1e-6); 

     // Transition nodes to their new position. 
     var nodeUpdate = node.transition() 
      .duration(duration) 
      .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; }); 

     nodeUpdate.select("rect") 
     .attr("y", function(d) { return d.children || d._children ? -5 : -5; }) 
     .attr("width","9") 
     .attr("height","9") 
     .style("fill", function(d) { return d._children ? "skyblue" : "#fff"; }) 
     .style("stroke","green"); 

     nodeUpdate.select("text") 
      .style("fill-opacity", 1); 

     // Transition exiting nodes to the parent's new position. 
     var nodeExit = node.exit().transition() 
      .duration(duration) 
      .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; }) 
      .remove(); 

     nodeExit.select("circle") 
      .attr("r", 1e-6); 

     nodeExit.select("text") 
      .style("fill-opacity", 1e-6); 

     // 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. 
    function toggle(d) { 
     if (d.children) { 
     d._children = d.children; 
     d.children = null; 
     } else { 
     d.children = d._children; 
     d._children = null; 
     } 
    } 
+0

Вы видели [пример] (http://bl.ocks.org/mbostock/ 3184089)? –

+0

Ларс, да, да, но, похоже, я не могу применить его к моему примеру. Я не уверен, что мне не хватает – Leon

+0

Вы имеете в виду изменение '.projection (function (d) {return [dy, dx];})' to '.projection (function (d) {return [dx, dy];}) 'не помогло? –

ответ

1

Вот как я решил его @ dev_marshell08

<script type="text/javascript"> 
    var w = 1600, 
     h = 2600, 
     r = 6, 
     fill = d3.scale.category20(); 
      var root; 

    var force = d3.layout.force() 
     .charge(-120) 
     .linkDistance(30) 
     .size([w, h]); 

    var svg = d3.select("#visualize").append("svg:svg") 
     .attr("width", w) 
     .attr("height", h); 

    d3.json("flare.json", function(json) { 
     root = json; 
    var nodes = flatten(root), 
     links = d3.layout.tree().links(nodes); 

     var link = svg.selectAll("line") 
       .data(links) 
       .enter().append("svg:line") 
       .attr("class", "link"); 

     var node = svg.selectAll("circle") 
      .data(nodes) 
      .enter().append("svg:circle") 
      .attr("r", r - .75) 
      .style("fill", function(d) { return fill(d.group); }) 
      .style("stroke", function(d) { return d3.rgb(fill(d.group)).darker(); }) 
      .call(force.drag); 

     force 
      .nodes(nodes) 
      .links(links) 
      .on("tick", tick) 
      .start(); 

     function tick(e) { 

     // Push sources up and targets down to form a weak tree. 
     var k = 6 * e.alpha; 
     links.forEach(function(d, i) { 
      d.source.y -= k; 
      d.target.y += k; 
     }); 

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

     link.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; }); 
     } 
    }); 

    function flatten(root) { 
    var nodes = [], i = 0; 

    function recurse(node) { 
     if (node.children) node.children.forEach(recurse); 
     if (!node.id) node.id = ++i; 
     nodes.push(node); 
    } 

    recurse(root); 
    return nodes; 
    } 
</script> 
Смежные вопросы