我正在尝试使用nest()
和.rollup
创建圈组图。我收到以下错误:
Error: Invalid value for <g> attribute transform="translate(undefined,undefined)"
Error: Invalid value for <circle> attribute r="NaN"
我希望根据每个国家/地区的公司数量来确定圈子的大小。我正在尝试改编迈克博斯托克的Flare圈子包装示例。
如果有人能指出我的任何信息,我将非常感激。
JS代码:
var diameter = 960,
format = d3.format(",d");
var pack = d3.layout.pack()
.size([diameter - 4, diameter - 4])
.value(function(d) { return d.size; });
var svg = d3.select("body").append("svg")
.attr("width", diameter)
.attr("height", diameter)
.append("g")
.attr("transform", "translate(2,2)");
//Get data
d3.json("data/countriesNested.php", function(error, data){
var submissionsByCountry = d3.nest()
.key(function(d) { return d.Country; })
.key(function(d) { return d.Organisation; })
.rollup(function(leaves) { return leaves.length; })
.entries(data);
var node = svg.datum(data).selectAll(".node")
.data(pack.nodes)
.enter().append("g")
.attr("class", function(d) { return d.children ? "node" : "leaf node"; })
.attr("transform", function(d) { return "translate(" + d.cx + "," + d.cy + ")"; });
node.append("title")
.text(function(d) { return d.name + (d.children ? "" : ": " + format(d.size)); });
node.append("circle")
.attr("r", function(d) { return d.r; });
});
d3.select(self.frameElement).style("height", diameter + "px");
</script>
数据文件(使用PHP脚本从MySQL获得):
[
{
"Country":"USA",
"ID":4,
"Organisation":"Company 1"
},
{
"Country":"USA",
"ID":5,
"Organisation":"Company 2"
},
{
"Country":"USA",
"ID":6,
"Organisation":"Company 3"
},
{
"Country":"FRANCE",
"ID":19,
"Organisation":"Company 4"
},
{
"Country":"FRANCE",
"ID":24,
"Organisation":"Company 5"
},
{
"Country":"GERMANY",
"ID":10,
"Organisation":"Company 6"
},
{
"Country":"ITALY",
"ID":7,
"Organisation":"Company 7"
},
.....
感谢阅读。
答案 0 :(得分:4)
您的代码中有一些错误需要修复:
您需要为包布局上的子项和值设置访问器功能:
var pack = d3.layout.pack()
.size([diameter - 4, diameter - 4])
.children(function(d) {
return d.values; // accessor for children
})
.value(function(d) {
return d.values; // accessor for values
});
您的d3.nest()
会返回一个数组,但d3.pack()
要求您提供包含该层次结构的根对象。您必须创建一个根对象并将嵌套数组放在:
var countryRoot = {
key: "root",
values: submissionsByCountry
};
在您的代码中,您将数据嵌套到submissionsByCountry
,但您没有在其他地方使用此变量。因此,在将数据绑定到svg
时,您显然必须引用它。这是通过上面提到的根对象实现的,该对象稍后绑定到svg
。
var node = svg.datum(countryRoot).selectAll(".node")
数据包布局添加到数据节点的属性包括值x
和y
,而您将它们称为cx
和cy
属性为<svg:circle>
,但您的数据中不存在。因此,您收到了transform="translate(undefined,undefined)"
错误消息。您应该使用这些属性:
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
我整理了一个有效的plunk。
答案 1 :(得分:1)
那么,你想要一个父圆圈(让它称之为世界),子圆圈代表每个国家的大小,并且你的JSON数组中有一个条目数?
d3.json("data/countriesNested.php", function(error, data) {
var submissionsByCountry = d3.nest()
.key(function(d) {
return d.Country;
})
.rollup(function(leaves) {
return leaves.length;
})
.entries(data);
var root = {
"key": "world",
"children": submissionsByCountry
};
...
这将为您提供与flare.json
非常相似的内容。
接下来,您需要为d3指定适合您的圈子大小的accessor。
var pack = d3.layout.pack()
.size([diameter - 4, diameter - 4])
.value(function(d) {
return d.values; //<-- this comes from your roll-up and is the count.
});
最后看起来您更改了示例代码以访问结果节点数据中不存在的cx
和cy
属性:
var node = svg.datum(root).selectAll(".node")
.data(pack.nodes)
.enter().append("g")
.attr("class", function(d) {
return d.children ? "node" : "leaf node";
})
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")"; //<-- this is .x, .y
});
这里是example。