2014-02-20 54 views
0

我正在嘗試使用d3js來繪製位置處的服務器圖。以下是輸入數據的示例提取。使用d3js,我如何使用樹形佈局將子節點可視化地放在其父節點中?

{"type": "customer", "name": "Acme", "children": [ 
    { 
     "type": "site", 
     "name": "Wichita", 
     "children": [ 
      { 
       "type": "server", 
       "name": "server1" 
      }, 
      { 
       "type": "server", 
       "name": "server2" 
      } 
     ] 
    }, 
    { 
     "type": "site", 
     "name": "Springfield", 
     "children": [ 
      { 
       "type": "server", 
       "name": "server1" 
      }, 
      { 
       "type": "server", 
       "name": "server2" 
      }, 
      { 
       "type": "server", 
       "name": "server3" 
      } 
     ] 
    } 
]} 

該網站將有不同數量的服務器。每個服務器應該是一個代表站點的矩形內的矩形。 我可以單獨創建站點和服務器矩形,但我想我需要將服務器節點綁定到其父節點的 節點上進行適當的分組,特別是如果稍後將svg導入到Visio。輸入json在var treeData中。另外,我是 無法正確定位,看起來使用正確的分組可能更容易。

var viz = d3.select("#viz").append("svg:svg") 
    .attr("width", 1200) 
    .attr("height", layoutHeight) 
    .append("svg:g"); 

var tree = d3.layout.tree().size([layoutHeight, 300]); 

var nodes = tree.nodes(treeData); 

viz.append("svg:text") 
    .attr("dx", "0") 
    .attr("dy", 20) 
    .attr("font-size", 24) 
    .attr("text-anchor", "start") 
    .text(json.customerName); 

var siteNodes = viz.selectAll("g.node") 
    .data(nodes) 
    .enter().append("svg:g") 
    .filter(function(d) { return d.type === "site" }) 
    .attr("transform", function(d) { return "translate(" + d.y + "," + (d.x * 1.5 - (d.children.length * serverHeight * 1.1/2)) + ")"; }); 

siteNodes.append("svg:rect") 
    .attr("width", 300) 
    .attr("height", function(d) { return serverHeight * (d.children.length + 1); }) 
    .attr("stroke", "black") 
    .attr("stroke-width", "1") 
    .attr("fill", "white"); 

var serverNodes = viz.selectAll("g.node") 
    .data(nodes) 
    .enter().append("svg:g") 
    .filter(function(d) { return d.type === "server" }) 
    .attr("transform", function(d) { return "translate(" + (d.y - 125) + "," + d.x + ")"; }); 

serverNodes.append("svg:rect") 
    .attr("width", 250) 
    .attr("height", serverHeight) 
    .attr("font-size", 10) 
    .attr("stroke", "black") 
    .attr("stroke-width", "1") 
    .attr("fill-opacity", "0.1") 
    .attr("fill", "blue"); 

我是新來d3js,我懷疑的一個主要因素是,我不相當,但考慮在適當的方式d3js。

回答

0

這是我摸索出用knowledge stockpilethis discussion on Google幫助的解決方案:

我的數據改變了一些字段名,所以它現在看起來更像是:

var treeData = {type: "customer", name: "Acme", children: [ 
    {type: "site", name: "Wichita", servers: [ 
     {type: "server", name: "server1", status: "Powered On"}, 
     {type: "server", name: "server2", status: "Powered On"}]}, 
    {type: "site", name: "Springfield", servers: [ 
     {type: "server", name: "server1", status: "Powered On"}, 
     {type: "server", name: "server2", status: "Powered On"}, 
     {type: "server", name: "server3", status: "Powered On"}] 
    } 
]}; 

計算佈局所需空間:

var serverHeight = 50; 
var serverWidth = 250; 

var siteWidth = serverWidth + 50; 

var layoutVerticalOffset = 20; 
var layoutHeight = 150 + (maxServerCount + 2) * serverHeight * 1.5; 
var layoutWidth = treeData.children.length * siteWidth * 1.5; 

var viz = d3.select("#viz").append("svg:svg") 
    .attr("height", layoutHeight) 
    .attr("width", layoutWidth + siteWidth) 
    .append("svg:g"); 

var tree = d3.layout.tree().size([layoutWidth, 0]); 

我加一類的網站節點:

var siteNodes = viz.selectAll("g.node") 
    .data(nodes) 
    .enter().append("svg:g") 
    .filter(function(d) { return d.type === "site" }) 
    .attr("class", "site") 
    .attr("transform", function(d) { 
     return "translate(" + d.x + "," + 100 + ")"; 
    }); 

和構建服務器節點時使用該類選擇:

var serverNodes = siteNodes.selectAll(".site") 
    .data(function(d) { return d.servers; }) 
    .enter().append("svg:g") 
    .attr("class", "server") 
    .attr("transform", function(d, i) { 
     return "translate(" + 25 + "," + (serverHeight/2 + i * serverHeight * 1.5) + ")"; 
    }); 

其結果是,該服務器是由克節點正確嵌套站點內表示節點:

<g class="site" transform="translate(300,35)"> 
    <rect width="300" height="165" stroke="black" stroke-width="1" fill="white"/> 
    <text dx="0" dy="12" font-size="18" text-anchor="end">Site</text> 
    <text dx="0" dy="34" font-size="18" text-anchor="end">Wichita</text> 
    <g class="server" transform="translate(25,25)"> 
     <rect width="250" height="50" font-size="10" stroke="black" stroke-width="1" fill-opacity="0.1" fill="blue"/> 
    </g> 
    <g class="server" transform="translate(25,100)"> 
     <rect width="250" height="50" font-size="10" stroke="black" stroke-width="1" fill-opacity="0.1" fill="blue"/> 
    </g> 
</g> 

這就形成了正確的分組,這是很重要的出口,並通過使它們相對於站點圖簡化了服務器的圖形計算我知道了。

enter image description here

1

由於您沒有提供完整的代碼,因此我必須對數值做出一些假設。我所做的改變應該很容易遵循。 Here是幫助你的小提琴。您在網站中使用的轉換對我而言並不明確,因此我推出了一個近似值讓您前進。你一定需要調整它。希望這可以幫助。

.attr("transform", function(d) { return "translate(" + (d.y) + "," + (d.x * 1.25 - (d.children.length * serverHeight * 0.9)) + ")"; }); 
+0

謝謝你的回答,並對遺失的作品表示歉意。我正在思考如何將子節點綁定到父節點。如果這不是首發,我可以調整值直到它們一直工作。 –

+0

[tree layout](https://github.com/mbostock/d3/wiki/Tree-Layout)在每個節點上填充的屬性之一是對父節點的引用。 – FernOfTheAndes

+0

那麼,我真的在談論發生在serverNodes.append()上的圖形綁定,而不是在var nodes = tree.nodes(treeData);發生的代表性綁定。 –

相關問題