D3.js 数组中对象键上的d3连接
我的数据如下所示:D3.js 数组中对象键上的d3连接,d3.js,D3.js,我的数据如下所示: [ { name: "Joel Spolsky", values: [ { timestamp: 1380432214730, value: 55 }, { timestamp: 1380432215730,
[
{
name: "Joel Spolsky",
values: [
{
timestamp: 1380432214730,
value: 55
},
{
timestamp: 1380432215730,
value: 32
},
{
timestamp: 1380432216730,
value: 2
},
{
timestamp: 1380432217730,
value: 37
},
// etc
]
},
{
name: "Soul Jalopy",
values: [
{
timestamp: 1380432214730,
value: 35
},
{
timestamp: 1380432215730,
value: 72
},
{
timestamp: 1380432216730,
value: 23
},
{
timestamp: 1380432217730,
value: 3
},
// etc
]
},
// and so on
]
var nameGroups = this.chartBody.selectAll(".nameGroup")
.data(this.layers, function (d) {
return d.name;
});
我将此数据传递到d3.layout.stack
中,以便添加y
和y0
。然后我画这个堆叠的布局
当数据更改时,我将新数据加入旧数据
我可以像这样加入name
上的组:
[
{
name: "Joel Spolsky",
values: [
{
timestamp: 1380432214730,
value: 55
},
{
timestamp: 1380432215730,
value: 32
},
{
timestamp: 1380432216730,
value: 2
},
{
timestamp: 1380432217730,
value: 37
},
// etc
]
},
{
name: "Soul Jalopy",
values: [
{
timestamp: 1380432214730,
value: 35
},
{
timestamp: 1380432215730,
value: 72
},
{
timestamp: 1380432216730,
value: 23
},
{
timestamp: 1380432217730,
value: 3
},
// etc
]
},
// and so on
]
var nameGroups = this.chartBody.selectAll(".nameGroup")
.data(this.layers, function (d) {
return d.name;
});
但我在时间戳上连接矩形(或“条”)时遇到问题。到目前为止,我所能做的就是在values
键上加入它们:
var rects = nameGroups.selectAll("rect")
.data(function (d) {
return d.values;
});
如何在时间戳
键上加入此“内部数据”
我已尝试包含数组索引:
var rects = nameGroups.selectAll("rect")
.data(function (d, i) {
return d.values[i].timestamp;
});
但这不起作用,因为(我认为)时间戳是按数组索引匹配的。也就是说,联接并不是查看匹配的所有时间戳值,而是查看该索引处的时间戳值
更新
以下是我的完整更新功能:
updateChart: function (data) {
var that = this,
histogramContainer = d3.select(".histogram-container"),
histogramContainerWidth = parseInt(histogramContainer.style('width'), 10),
histogramContainerHeight = parseInt(histogramContainer.style('height'), 10),
width = histogramContainerWidth,
height = histogramContainerHeight,
nameGroups, rects;
/*
FWIW, here's my stack function created within my
init function:
this.stack = d3.layout.stack()
.values(function (d) { return d.values; })
.x(function (dd) { return dd.timestamp; })
.y(function (dd) { return dd.value; });
*/
// save the new data
this.layers = this.stack(data);
// join the new data to the old via the "name" key
nameGroups = this.chartBody.selectAll(".nameGroup")
.data(this.layers, function (d, i) {
return d.name;
});
// UPDATE
nameGroups.transition()
.duration(750);
// ENTER
nameGroups.enter().append("svg:g")
.attr("class", "nameGroup")
.style("fill", function(d,i) {
//console.log("entering a namegroup: ", d.name);
var color = (that.colors[d.name]) ?
that.colors[d.name].value :
Moonshadow.helpers.rw5(d.name);
return "#" + color;
});
// EXIT
nameGroups.exit()
.transition()
.duration(750)
.style("fill-opacity", 1e-6)
.remove();
rects = nameGroups.selectAll("rect")
.data(function (d) {
// I think that this is where the change needs to happen
return d.values;
});
// UPDATE
rects.transition()
.duration(750)
.attr("x", function (d) {
return that.xScale(d.timestamp);
})
.attr("y", function(d) {
return -that.yScale(d.y0) - that.yScale(d.y);
})
.attr("width", this.barWidth)
.attr("height", function(d) {
return +that.yScale(d.y);
});
// ENTER
rects.enter().append("svg:rect")
.attr("class", "stackedBar")
.attr("x", function (d) {
return that.xScale(d.timestamp); })
.attr("y", function (d) {
return -that.yScale(d.y0) - that.yScale(d.y); })
.attr("width", this.barWidth)
.attr("height",function (d) {
return +that.yScale(d.y); })
.style("fill-opacity", 1e-6)
.transition()
.duration(1250)
.style("fill-opacity", 1);
// EXIT
rects.exit()
.transition()
.duration(750)
.style("fill-opacity", 1e-6)
.transition()
.duration(750)
.remove();
}
实际上,您并没有在代码中传递键函数。key函数是
.data()
的可选第二个参数(请参阅)。因此,在您的情况下,代码应该是
.data(function(d) { return d.values; },
function(d) { return d.timestamp; })
这里,第一个函数告诉D3如何从嵌套的上层提取值,第二个函数告诉D3如何为在第一个参数中提取的数组中的每个项获取键。这类似于
d.values[0]。timestamp
,no?Hmm。它不需要类似于d.values[i]。timestamp吗?所以它连接每个rect的时间戳
,而不仅仅是第一个?这取决于您想做什么。请给我们看一下完整的代码好吗?我不太确定你要在哪里进行匹配。哦,等等,你实际上并没有在那里传递一个键函数。请尝试.data(函数(d){return d.values;},函数(d){return d.timestamp;})
。键函数是第二个参数,您只传递了一个。我会加上它作为答案。