根元素没有显示它的孩子在森伯斯特

时间:2018-02-19 13:36:31

标签: d3.js sunburst-diagram

我正在尝试按照https://bl.ocks.org/denjn5/3b74baf5edc4ac93d5e487136481c601上的3部分教程制作一个sunburst。我的json包含基于国家和产品部门的销售信息。我试图在第一层销售基于国家和第二层销售基于产品部门。我的Json文件如下所示:

    {
       "country": "All", 
        "shares":[

        {
            "country": "at",
            "shares":[
                {
                "productdivision": "accessorie",
                "label": 53222
                },
                {
                "productdivision": "apparel",
                "label": 365712
                },
                {
                "productdivision": "footwear",
                "label": 523684
                }
            ]
        },

        {
            "country": "be",
            "shares":[
                {
                "productdivision": "accessorie",
                "label": 57522
                },
                {
                 "productdivision": "apparel",
                 "label": 598712
                },
                {
                "productdivision": "footwear",
                "label": 52284
                }
            ]
        },

        {
            "country": "DE",
            "shares":[
                {
                "productdivision": "accessorie",
                "label": 56982

                },
                {
                "productdivision": "apparel",
                "label": 55312
                },
                {
                "productdivision": "footwear",
                "label": 67284
                }
            ]
         },

        {
            "country": "Fr",
            "shares":[
                {
                "productdivision": "accessorie",
                "label": 5862
                },
                {
                "productdivision": "apparel",
                "label": 45312
                },
                {
                "productdivision": "footwear",
                "label": 26284
                }
            ]
        }

    ]
    }

这个json文件的名字是kpiDrillDown2.json,我用d3.json()在我的代码中调用它。我对代码进行了细微更改,以便为我的数据工作。代码如下:

<html>
    <head>
        <style>
            @import url('https://fonts.googleapis.com/css?family=Raleway');
            body {
                    font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif;
                }
        </style>

        <script src="https://d3js.org/d3.v4.min.js"></script>
    </head>
    <body>
        <svg></svg>
        <script>
            //initialize variables
            var width = 500; 
            var height = 500;
            var radius = Math.min(width, height) / 2;  
            var color = d3.scaleOrdinal(d3.schemeCategory20b);  

            //setting up svg workspace
            var g = d3.select('svg')  
                    .attr('width', width)  
                    .attr('height', height)
                    .append('g')  
                    .attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')'); 

            //formatting the data
            var partition = d3.partition()      
                            .size([2 * Math.PI, radius]);

            function draw(nodeData){

                debugger;
                //finding the root node
                var root = d3.hierarchy(nodeData)     
                            .sum(function (d) { return d.label});           

                //calculating each arc
                partition(root);    

                var arc = d3.arc()  
                            .startAngle(function (d) { return d.x0; })     
                            .endAngle(function (d) { return d.x1; })       
                            .innerRadius(function (d) { return d.y0; })    
                            .outerRadius(function (d) { return d.y1; });   

                g.selectAll('g')   
                    .data(root.descendants())
                    .enter()
                    .append('g')
                    .attr("class", "node")  
                    .append('path') 
                    .attr("display", function (d) { return d.depth ? null : "none"; })
                    .attr("d", arc)
                    .style('stroke', '#fff')
                    .style("fill", function (d) { return color((d.parent ? d : d.parent).data.productdivision); })


                g.selectAll(".node")  
                    .append("text")  
                    .attr("transform", function(d) {
                        return "translate(" + arc.centroid(d) + ")rotate(" + computeTextRotation(d) + ")"; })  
                    .attr("dx", "-20")  
                    .attr("dy", ".5em") 
                    .text(function(d) { return d.parent ? d.data.productdivision : "" }); 


                    function computeTextRotation(d) {
                        var angle = (d.x0 + d.x1) / Math.PI * 90;  

                        // Avoid upside-down labels
                        return (angle < 90 || angle > 270) ? angle : angle + 180; 
                    }

            }

            d3.json('kpiDrillDown3.json', draw);

        </script>
    </body>
</html>

我在绘图功能中放了一个debbuger来检查根元素。 Root没有孩子。这是我在控制台中看到的:Inspect the root element

当我继续时,它会给我一个错误:&#34;无法读取属性&#39;数据&#39; of null&#34;。如控制台所示,root不会有孩子。我的问题是,我是否需要更改我的json数据格式以使root识别chilren,或者我做错了什么。我是d3js的新手,基本上通过获取源代码并修改它,我正在努力。这是控制台中的错误:

Console error in redeading productDivision attribute

感谢您的帮助,非常感谢您。

1 个答案:

答案 0 :(得分:0)

根据API

  

为每个数据调用指定的子访问器函数,从根数据开始,并且必须返回表示子项的数据数组,如果当前数据没有子项,则返回null。如果未指定子项,则默认为:

function children(d) {
    return d.children;
}

但是,在您的数据结构中,您没有children,而是shares

因此,层次结构应为:

var root = d3.hierarchy(data, function(d) {
    return d.shares;
})

请注意这样一个事实:在你所链接的教程的JSON中(就像在API的例子中一样),子节点的数组被命名为children

这是一个演示,看一下控制台(浏览器的控制台,而不是片段):

var data = {
  "country": "All",
  "shares": [{
      "country": "at",
      "shares": [{
          "productdivision": "accessorie",
          "label": 53222
        },
        {
          "productdivision": "apparel",
          "label": 365712
        },
        {
          "productdivision": "footwear",
          "label": 523684
        }
      ]
    },
    {
      "country": "be",
      "shares": [{
          "productdivision": "accessorie",
          "label": 57522
        },
        {
          "productdivision": "apparel",
          "label": 598712
        },
        {
          "productdivision": "footwear",
          "label": 52284
        }
      ]
    },
    {
      "country": "DE",
      "shares": [{
          "productdivision": "accessorie",
          "label": 56982

        },
        {
          "productdivision": "apparel",
          "label": 55312
        },
        {
          "productdivision": "footwear",
          "label": 67284
        }
      ]
    },
    {
      "country": "Fr",
      "shares": [{
          "productdivision": "accessorie",
          "label": 5862
        },
        {
          "productdivision": "apparel",
          "label": 45312
        },
        {
          "productdivision": "footwear",
          "label": 26284
        }
      ]
    }
  ]
};

var root = d3.hierarchy(data, function(d) {
    return d.shares;
  })
  .sum(function(d) {
    return d.label
  });

console.log(root)
<script src="https://d3js.org/d3.v4.min.js"></script>