d3js径向整齐的树 - dx和dy是如何填充的?

时间:2016-11-27 14:39:44

标签: javascript d3.js svg tree

我是d3js的初学者,玩弄一个非常简单的径向整洁的树来工作。

我编写了以下代码来生成树。

139 function radialTree(window, svg, data) {
140  debugger; 
141   console.log("Will build radial tree here...");
142   var result = radTree.transform(data);
143   console.log("tree data:", result);                                                                                                                                                                                                      
144 
145   g = svg.append("g").attr("transform", "translate(" + (w / 2 + 40) + "," + (h / 2 + 90) + ")");
146 
147   var stratify = d3.stratify()
148             .parentId(function(d) { return d.parent;});
149   var tree = d3.tree()
150               .size([360, 500])
151               .separation(function(a,b) { return (a.parent == b.parent?1:2)/a.depth; });
152   var root = d3.hierarchy(result); 
153 
154   var link = g.selectAll(".link")             
155               .data(root.descendants().slice(1))
156               .enter().append('path')         
157               .attr('class', 'link')          
158               .attr('d', function(d) {          
159                 debugger;
160                 return "M" + project(d.x, d.y)        
161                       + "C" + project(d.x, (d.y + d.parent.y)/2)
162                       + " " + project(d.parent.x, (d.y + d.parent.y)/2)
163                       + " " + project(d.parent.x, d.parent.y)
164               });
165 
166   var node = g.selectAll(".node")             
167               .data(root.descendants())       
168               .enter().append('g')            
169               .attr('class', function(d) { return "node" + (d.children?" node--internal":" node--leaf"); })                
170               .attr('transform', function(d) { return "translate(" + project(d.x, d.y) + ")"; })
171 
172   node.append('circle').attr('r', 2.5);
173   node.append('text')
174      .attr('dy', '.31em')
175      .attr('x', function(d) { return d.x < 180 === !d.children ? 6: -6; })
176      .style('text-anchor', function(d) { return d.x < 180 === !d.children ? "start":"end"; })
177      .attr('transform', function(d) { return "rotate(" + (d.x<180? d.x-90 : d.x+90) + ")"; })
178      .text(function(d) { return d.name; });
179 
180   return svg;
181 }
182 
183 function project(x, y) {
184   var angle = (x-90)/180 * Math.PI,  radius = y;
185   return [radius*Math.cos(angle), radius*Math.sin(angle)];
186 }
187 

因为,我有一个由分层生成的形式的树数据(我猜是这样),我没有明确地调用stratify()函数。提供给树函数的json数据如下:

tree data: { parent: null,
  name: 'root',
  id: 'root',
  status: 'green',
  depth: 0,
  children: 
   [ { parent: 'root',
       name: 'authServer',
       id: 'authServer',
       status: 'green',
       depth: 1,
       children: [Object] },
     { parent: 'root',
       name: 'dndServer',
       id: 'dndServer',
       status: [Object],
       depth: 1,
       children: [Object] },
     { parent: 'root',
       name: 'accServer',
       id: 'accServer',
       status: 'green',
       depth: 1,
       children: [Object] },
     { parent: 'root',
       name: 'contactPolicyServer',
       id: 'contactPolicyServer',
       status: 'green',
       depth: 1,
       children: [Object] },
     { parent: 'root',
       name: 'DB',
       id: 'DB',
       status: undefined,
       depth: 1 },
     { parent: 'root',
       name: 'fileServer',
       id: 'fileServer',
       status: 'green',
       depth: 1,
       children: [Object] },
     { parent: 'root',
       name: 'campaignServer',
       id: 'campaignServer',
       status: 'green',
       depth: 1,
       children: [Object] } ] }

当它在浏览器上呈现时,我看到只绘制了一个圆圈,并且Web控制台显示了很多错误,因为svg转换函数已经收到NaN值。

enter image description here

在尝试调试问题时,我发现传递给回调函数的“d”对象没有名为“x”或“y”的键。对象'd'的调试输出如下所示:

break in ind.js:159
 157               .attr('class', 'link')
 158               .attr('d', function(d) {
>159                 debugger;
 160                 return "M" + project(d.x, d.y)
 161                       + "C" + project(d.x, (d.y + d.parent.y)/2)
repl
Press Ctrl + C to leave debug repl
> d
{ data: 
   { parent: 'root',
     name: 'authServer',
     id: 'authServer',
     status: 'green',
     depth: 1,
     children: [ [Object], [Object] ] },
  height: 1,
  depth: 1,
  parent: 
   { data: 
      { parent: null,
        name: 'root',
        id: 'root',
        status: 'green',
        depth: 0,
        children: [Object] },
     height: 2,
     depth: 0,
     parent: null,
     children: 
      [ [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object] ] },
  children: 
   [ { data: [Object], height: 0, depth: 2, parent: [Object] },
     { data: [Object], height: 0, depth: 2, parent: [Object] } ] }

我想知道d.x和d.y的值何时,何地以及如何填充,以便它们可以在回调函数中安全使用...

1 个答案:

答案 0 :(得分:2)

d3.tree()函数设置xy属性。根据文档,d3.tree()

  

布置指定的根层次结构,在root及其后代上分配以下属性:

     
      
  • node.x - 节点的x坐标
  •   
  • node.y - 节点的y坐标
  •   

因此,您定义了d3.tree()

var tree = d3.tree()
    .size([360, 500])
    .separation(function(a,b){
        return (a.parent == b.parent ? 1 : 2)/a.depth;
    });

你的等级制度:

var root = d3.hierarchy(result);

下一步应该是:

root = tree(root);

这将填充xy属性。

PS:我刚回答你的问题(“dx和dy是如何填充的?”),而不是调试你的代码。