【问题标题】:Root element is not showing its children in sunburst根元素未在旭日形中显示其子元素
【发布时间】:2018-02-19 13:36:31
【问题描述】:

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

{ “国家”:“全部”, “分享”:[ { “国家”:“在”, “分享”:[ { “产品部门”:“配件”, “标签”:53222 }, { “产品部门”:“服装”, “标签”:365712 }, { “产品部门”:“鞋类”, “标签”:523684 } ] }, { “国家”:“是”, “分享”:[ { “产品部门”:“配件”, “标签”:57522 }, { “产品部门”:“服装”, “标签”:598712 }, { “产品部门”:“鞋类”, “标签”:52284 } ] }, { “国家”:“德国”, “分享”:[ { “产品部门”:“配件”, “标签”:56982 }, { “产品部门”:“服装”, “标签”:55312 }, { “产品部门”:“鞋类”, “标签”:67284 } ] }, { “国家”:“法国”, “分享”:[ { “产品部门”:“配件”, “标签”:5862 }, { “产品部门”:“服装”, “标签”:45312 }, { “产品部门”:“鞋类”, “标签”: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>

我在绘图函数中放置了一个调试器来检查根元素。 Root 没有孩子。这是我在控制台看到的:

当我继续时,它给了我错误:“无法读取 null 的属性‘数据’”。如控制台所示,root 没有孩子。我的问题是,我是否需要更改我的 json 数据格式以使 root 识别孩子,或者我做错了什么。我是 d3js 的新手,基本上通过获取源代码并对其进行修改,我正在努力。这是控制台中的错误:

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

【问题讨论】:

    标签: d3.js sunburst-diagram


    【解决方案1】:

    根据API

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

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

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

    所以,层次结构应该是:

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

    请注意,在您链接的该教程的 JSON 中(就像在 API 的示例中一样)子数组被命名为 children

    这是一个demo,看控制台(你浏览器的控制台,不是sn-p那个):

    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)
    &lt;script src="https://d3js.org/d3.v4.min.js"&gt;&lt;/script&gt;

    【讨论】:

    • 您好,非常感谢您的回答。它现在显示每个元素的高度;在控制台根目录中是:vo {data: {…}, height: 2, depth: 0, parent: null, children: Array(4), …} 但仍然是 line: .style("fill", function (d) { return color((d.parent ? d : d.parent).data.productdivision); }) 给出同样的错误:Cannot read property 'data' of null at SVGPathElement. (sunburst_modified.html:78)
    • 是不是因为我的数据有两个不同的属性country和productDivision?与我在获取代码的问题中提供的链接不同,在我的数据中,一些节点只有像根节点这样的国家,没有产品部门,而孙子只有产品部门,没有国家。此外,通过评论错误行,我发现并非所有标签都可以显示。仅显示产品部门标签,不显示国家/地区!
    • d.parent ? d : d.parent 毫无意义。无论如何,由于这是另一个问题,我建议您发布另一个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-14
    • 2021-12-01
    相关资源
    最近更新 更多