2016-03-08 70 views
1

我试图找到一种方法将自动缩放添加到当前的代码。通常的缩放平移工作正常。但是,当一棵树中的节点数量很多时,就会被角落切断。无论如何,只要树通过svg的宽度和高度的边界,就会自动缩放。也许基于深度大小或节点的总数。D3Js树布局自动缩放功能

function buildTree(treeData){ 

    var contextMenuList = [ 
    { 
     title: 'Remove Node', 
     action: function(elm, d, i) { 

     if (d.parent && d.parent.children){ 
      var nodeToDelete = _.where(d.parent.children, {name: d.name}); 
      if (nodeToDelete){ 
      d.parent.children = _.without(d.parent.children, nodeToDelete[0]); 
      } 
      update(d); 
     } 
     } 
    }, 
    { 
     title: 'Synopsis', 
     action: function(elm, d, i) { 

     console.log("Option 2 clicked"); 
     console.log("Node Name: "+ d.name); 
     setNodeTopic(d.name); 
     } 
    } 
    ]; 

    var margin = {top:40, right:120,bottom:20,left:20}; 
    var width = 960 - margin.right - margin.left; 
    var height = 900 - margin.top - margin.bottom; 

    var i = 0,duration = 750; 
    //refers to the tree itself 
    var tree = d3.layout.tree() 
    .size([height,width]) 
    .nodeSize([100,100]); 

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

    //refers to the rectangle outside 
    var zm; 
    var svg = d3.select("#tree").append("svg") 
    .attr("width",width+margin.right+margin.left) 
    .attr("height",height+margin.top+margin.bottom) 
    .append("svg:g") 
    .attr("transform","translate("+margin.left+","+margin.top+")") 
    .call(zm = d3.behavior.zoom().scaleExtent([0.5,2]).on("zoom", redraw)).append("g") 
    .attr("transform","translate("+400+","+50+")"); 

    zm.translate([400,20]); 

    var root = treeData; 


    function autoOpen(head, time) { 
    window.setTimeout(function() { 
     nodeclick(head); //do node click 
     if (head._children) { 
     //if has children 
     var timeOut = 1000; //set the timout variable 
     head._children.forEach(function(child) { 
      autoOpen(child, timeOut); //open the child recursively 
      timeOut = timeOut + 1000; 
     }) 
     } 
    }, time); 
    } 

    autoOpen(root,1000); 

    update(root); 

    function update(source){ 
    var nodes = tree.nodes(root).reverse(), 
     links = tree.links(nodes); 

    nodes.forEach(function(d){ 
     d.y = d.depth * 150; 
    }); 

    var node = svg.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){ 
     if(!source.x0 && !source.y0) 
      return ""; 
     return "translate("+source.x0 + "," + source.y0 + ")"; 
     }) 
     .on("click",nodeClick) 
     .on('contextmenu', d3.contextMenu(contextMenuList)); 

    nodeEnter.append("circle") 
     .attr("r",50) 
     .attr("stroke",function(d){ 
     return d.children || d._children ? "steelblue" : "#00c13f"; 
     }) 
     .style("fill",function(d){ 
     return d.children || d._children ? "lightsteelblue" : "#fff"; 
     }) 

    nodeEnter.append("text") 
     .attr("y",function(d){ 
     //return d.children || d._children ? -18 : 18; 
     return -10; 
     }) 
     .attr("dy",".35em") 
     .attr("text-anchor","middle") 
     .style("fill-opacity",1e-6) 
     .each(function (d) { 
     var arr = d.name.split(" "); 
     for (i = 0; i < arr.length; i++) { 
      d3.select(this).append("tspan") 
      .text(arr[i]) 
      .attr("dy", i ? "1.2em" : 0) 
      .attr("x", 0) 
      .attr("text-anchor", "middle") 
      .attr("class", "tspan" + i); 
     } 
     }); 

    var nodeUpdate = node.transition() 
     .duration(duration) 
     .attr("transform",function(d){ 
     return "translate(" + d.x + "," + d.y + ")"; 
     }); 

    nodeUpdate.select("circle") 
     .attr("r",50) 
     .style("fill",function(d){ 
     return d._children ? "lightsteelblue" : "#fff"; 
     }); 

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

    var nodeExit = node.exit().transition() 
     .duration(duration) 
     .attr("transform",function(d){ 
     return "translate("+ source.x+","+source.y+")"; 
     }) 
     .remove(); 

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

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


    var link = svg.selectAll("path.link") 
     .data(links,function(d){ 
     return d.target.id; 
     }); 

    link.enter().insert("svg:path","g") 
     .attr("class","link") 
     .attr("d",function(d){ 
     if(!source.x0 && !source.y0) 
      return ""; 
     var o = {x:source.x0,y:source.y0}; 
     return diagonal({source:o,target:o}); 
     }); 

    link.transition() 
     .duration(duration) 
     .attr("d",diagonal); 

    link.exit().transition() 
     .duration(duration) 
     .attr("d",function(d){ 
     var o = {x:source.x,y:source.y}; 
     return diagonal({source:o,target:o}); 
     }) 
     .remove(); 

    nodes.forEach(function(d){ 
     d.x0 = d.x; 
     d.y0 = d.y; 
    }); 
    } 

    function nodeClick(d) { 
    if (d.children) { 
     d._children = d.children; 
     d.children = null; 
    } else { 
     d.children = d._children; 
     d._children = null; 
    } 
    update(d); 
    } 

    function redraw() { 
    svg.attr("transform", 
     "translate(" + d3.event.translate + ")" 
     + " scale(" + d3.event.scale + ")"); 
    } 
} 

buildTree(that.objectList); 
}; 

回答

0

我对这个问题的解决方案是使用viewbox。使svg负责允许svg能够根据浏览器窗口大小调整大小。

以下是一个示例: Making SVG Responsive