2014-02-20 55 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);发生的代表性绑定。 –

相关问题