2016-08-18 11 views
-1

ツリーのサイズが非常に大きく、コンテナが小さいためd3jsを使用してツリーを構築していますので、divはページロード時にsvgコンポーネントを表示できません。この image on loadd3jsのズーム機能後にsvgコンポーネントを中央に配置

ツリーを表示するためには、私は、ズームインやSVGコンポーネントをドラッグする必要があり、この zoomed image

よう は、ページのロードSVG内のSVGコンポーネントを中央にどのような方法があります?

は、ここに私のコード

<style> 

     .node circle { 
      fill: #fff; 
      stroke: steelblue; 
      stroke-width: 1.5px; 
     } 

     .node { 
      font: 10px sans-serif; 
     } 

     .link { 
      fill: none; 
      stroke: #ccc; 
      stroke-width: 1.5px; 
     } 

     </style> 
      <!--<img src="../image/dummy5.svg" style='width:100%;margin:3px 0;'/>--> 
      <script src="http://d3js.org/d3.v3.min.js"></script> 
      <!--******* vertical *******--> 
      <script> 
      var treeData = [ 
      <?php echo "{'name' : 'CDS','icon': '../image/logo.png','padding':'0','user_id': 'CDS','level':'CDS','children' : ["; echo get_node_ul_frm_adm ($DBconn, 1); echo "]}"; ?>]; 

      var width = $("#agent-tree").width(), 
       height = 2200; 

      var cluster = d3.layout.tree() 
       .nodeSize([100, 200]) 
       .separation(function(){ 
       return .5; 
       }) 
       .size([height, width - 160]); 

      var zoom = d3.behavior.zoom().on("zoom", function() { 
       svg.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")") 
       }) 

      var svg = d3.select("#agent-tree").append("svg") 
       .attr("width", width) 
       .attr("height", height) 
       .attr("object-fit", "cover") 
       .call(zoom) 
       .append("g") 
       .attr("transform", "translate(40,0)"); 
       root = treeData[0]; 
      var nodes = cluster.nodes(root).reverse(); 
      nodes.forEach(function(d) { d.y = d.depth * 100; }); 
      var link = svg.selectAll(".link") 
       .data(cluster.links(nodes)) 
       .enter().append("path") 
       .attr("class", "link") 
       .attr("d", elbow); 

      var node = svg.selectAll(".node") 
       .data(nodes) 
       .enter().append("g") 
       .attr("class", "node") 
       .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }) 

      node.append("circle") 
       .attr("transform", function(d) { return "translate(0,"+d.padding+")"; }) 
       .attr("r", 12.5); 

      function elbow(d) { 
      return "M" + d.source.x + "," + d.source.y 
       + "H" + ((d.target.x-d.source.x)/2,d.source.x) 
       + "V" + d.target.y 
       + "H" + d.target.x 
       + "v" + ((d.source.y-d.target.y)/2,42); 
      } 
      </script> 
+1

私はそれが私の答えはあなたが望むものではありません取りますか? – thatOneGuy

答えて

1

ツリー上の各ノードを通過し、それらに対応する境界ボックスのそれぞれの最小と最大のxとyの値を取得することです。

var smallestBiggestDim = { 
    smallX : "", 
    smallY : "", 
    bigX : "", 
    bigY : "" 
} 
nodes.each(function(d, i){ //loop through tree nodes 
    var thisBBox = d3.select(this).node().getBBox(); //get bbox of current node 
    if(i == 0){ 
    //if i = 0, none are set, so set them 
    smallestBiggestDim.smallX = thisBBox.left; 
    smallestBiggestDim.smallY = thisBBox.top; 
    smallestBiggestDim.bigX = thisBBox.left + thisBBox.width; 
    smallestBiggestDim.bigY = thisBBox.top + thisBBox.height; 
    } else { 
    //check values and set if bigger or smaller 
    if(smallestBiggestDim.smallX > thisBBox.left){ smallestBiggestDim.smallX = thisBBox.left } 
    if(smallestBiggestDim.smallY > thisBBox.top){ smallestBiggestDim.smallY = thisBBox.top } 
    if(smallestBiggestDim.bigX < thisBBox.left + thisBBox.width;){ smallestBiggestDim.bigX = thisBBox.left + thisBBox.width; } 
    if(smallestBiggestDim.bigY < thisBBox.top + thisBBox.height;){ smallestBiggestDim.bigY = thisBBox.top + thisBBox.height; } 
} 
}) 

上記は各ノードのバウンディングボックスを取得し、xとyの最小値と最大値をチェックします。

次に、これらの寸法をあなたのsvgの幅と高さと共に使用してズームを計算します。新しい幅と高さを動作するように

だけで実行します。

var newWidth = smallestBiggestDim.bigX - smallestBiggestDim.smallX; 
var newHeight = smallestBiggestDim.bigY - smallestBiggestDim.smallY; 

は、あなたの計算されたRECTは×300 300だったし、あなたのSVGのあなたの幅と高さは、あなたがどうなる規模を計算するには、X 200 200だったと言います。:あなたは、幅と高さの両方を合わせて最大値を取得する必要があるので、あなただけの1つのスケール値を持っているように、私はMath.maxを使用

だからあなたの規模は今だろう

var scale = Math.max(rectWidth/svgWidth, rectHeight/svgHeight); 
//which is 
var scale = Math.max(300/200, 300/200); 

var newScale = 1.5 

だから、負荷にあなたがそうのようにズームアウトします:

svg.attr('transform', 'scale(' + newScale + ')'; 

動作する必要があること:)

関連する問題