我的数据如下:
[
{
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
]
我将此数据传递到d3.layout.stack
,以便添加y
和y0
。然后我绘制这个堆叠的布局。
当数据发生变化时,我将新数据加入旧数据。
我可以像name
这样加入小组:
var nameGroups = this.chartBody.selectAll(".nameGroup")
.data(this.layers, function (d) {
return d.name;
});
但是我在时间戳上加入矩形(或#34; bar")时遇到了麻烦。我能做的最好(到目前为止)是将它们加在values
键上:
var rects = nameGroups.selectAll("rect")
.data(function (d) {
return d.values;
});
我如何加入这个"内部数据"在timestamp
键上?
我尝试过包含数组索引:
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();
}
答案 0 :(得分:1)
您实际上并未在代码中传递密钥功能。关键函数是.data()
的可选第二个参数(参见the documentation)。所以在你的情况下,代码应该是
.data(function(d) { return d.values; },
function(d) { return d.timestamp; })
这里第一个函数告诉D3如何从嵌套的上层提取值,第二个函数告诉第一个参数中提取的数组中的每个项如何获取键。