我正在尝试按照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没有孩子。这是我在控制台中看到的:
当我继续时,它会给我一个错误:&#34;无法读取属性&#39;数据&#39; of null&#34;。如控制台所示,root不会有孩子。我的问题是,我是否需要更改我的json数据格式以使root识别chilren,或者我做错了什么。我是d3js的新手,基本上通过获取源代码并修改它,我正在努力。这是控制台中的错误:
感谢您的帮助,非常感谢您。
答案 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>