使用 nest() 和 rollup 的圆包布局
Circle pack layout using nest() and rollup
我正在尝试使用 nest()
和 .rollup
创建一个圆包图。我收到以下错误:
Error: Invalid value for <g> attribute transform="translate(undefined,undefined)"
Error: Invalid value for <circle> attribute r="NaN"
我希望根据每个国家/地区的公司数量来调整圆圈的大小。我正在尝试改编 Mike Bostock 的 Flare circle-pack 示例。
如果有人能指出任何信息的方向,我将不胜感激。
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>
数据文件(来自 MySQL 使用 PHP 脚本):
[
{
"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"
},
.....
感谢阅读。
那么,您想要一个父圆(我们称它为世界),子圆代表每个国家/地区的大小与 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。
您的代码中存在一些需要修复的错误:
您需要为您的包布局中的子项和值设置访问器函数:
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()
returns 一个数组,但 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。
我正在尝试使用 nest()
和 .rollup
创建一个圆包图。我收到以下错误:
Error: Invalid value for <g> attribute transform="translate(undefined,undefined)"
Error: Invalid value for <circle> attribute r="NaN"
我希望根据每个国家/地区的公司数量来调整圆圈的大小。我正在尝试改编 Mike Bostock 的 Flare circle-pack 示例。
如果有人能指出任何信息的方向,我将不胜感激。
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>
数据文件(来自 MySQL 使用 PHP 脚本):
[
{
"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"
},
.....
感谢阅读。
那么,您想要一个父圆(我们称它为世界),子圆代表每个国家/地区的大小与 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。
您的代码中存在一些需要修复的错误:
您需要为您的包布局中的子项和值设置访问器函数:
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()
returns 一个数组,但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。