我正在构建一个d3.js图表,该图表在数据中有一定程度的嵌套,并且在应用data()
函数时我在指定行的键时遇到问题。以下是对相关位的简单了解。
我的数据是这种形式:
[
{
name: 'United States',
values: [ {year:1960, imports:12, exports:13}, etc... ]
},
{
name: 'China',
values: [ {year:1960, imports:10, exports:11}, etc... ]
}
]
我创建了这样的基本图形:
var svg = d3.select(this).selectAll('svg').data([data]);
var g = svg.enter().append('svg').append('g').attr('class', 'main');
g = svg.select('g.main')
一切似乎都很好。对于数据中的每个国家/地区,我绘制了两行,因此我将它们组合在一起(as described in this answer)。
var lines_g = g.selectAll("g.lines")
.data(function(d) { return d; },
function(d) { console.log(d.name); return d.name; });
lines_g.enter().append("g").attr("class", "lines");
这似乎也很好 - 控制台显示'中国'和'美国'来自data()
电话的关键部分。
但是我在为每个lines_g
组中的线路添加密钥时苦苦挣扎。例如,这样做:
lines_g.selectAll('path.line.imports')
.data(function(d) { return [d.values]; },
function(d) { console.log(d); return d.name; })
.enter().append('path')
.attr('class', 'line imports');
控制台显示我希望通过记录d.values
而非d
而预期的数组:
[ {year:1960, imports:12, exports:13}, etc... ]
为什么我不能在那时访问d
,因此d.name
?并且,为组内的行提供与其组相同的键是否正确?
答案 0 :(得分:1)
您正在处理嵌套选择。也就是说,您对每个国家/地区都有一个顶级选择,并且每个国家/地区都只选择一个值 - 这就是您在说
时所做的事情。.data(function(d) { return [d.values]; })
在此之后,您只能直接访问d.values
中的内容。您正在记录d
的关键功能,将获得您之前指定的数组元素 - [d.values]
。
如果您需要访问父数据元素的名称,我建议您也将此信息放入子元素中。也就是说,每个{year: 1960, ...}
也有一个name: 'China'
成员。您可以使用以下代码实现此目的:
data.forEach(function(d) {
d.values.forEach(function(e) {
e.name = d.name;
});
});
这会复制很多信息,但在您的情况下可能不是必需的。由于每个国家/地区只有一个数据元素,因此您可以直接传递[d]
而不是[d.values]
。这只需要调整行生成器的方式稍作改动,也可以访问键功能中的国家名称。
我已经从另一个问题修改了jsfiddle以执行here。