0

我试图让堆积条形图以与此条形图相同的方式进行转换 - http://www.animatedcreations.net/d3/animatedBarChart_Slide.html 我一直在关注 Mike Bostock 的“条形图,第 2 部分”示例,并且可以将堆叠的条形移入和移出。
我的坏例子在这里 - http://www.animatedcreations.net/d3/stackedBarChart7.html 我有理由确定问题在于我如何设置数据,如下所示。我什至想知道是否需要将数据转换为列而不是层?非常感谢 Insight :) 谢谢。

从重绘():

// stack the new data
var stacked = d3.layout.stack()(["act1", "act2","act3","other"].map(function(activity){
    return stats.map(function(d) {
        return {x:(d.hour), y: +d[activity]};
    });
}));

// update x axis 
x.domain(stacked[0].map(function(d) { return d.x; })); 

var valgroup = graph.selectAll("g.valgroup").data(stacked);

// want the data in d.  var rect contains the data AND functions. 
// I am guessing this is where it all breaks??
var rect = valgroup.selectAll("rect")
    .data((function(d) { return d; }), (function(d) { return d.x; }));   
         // new data set.  slide by hour on x axis.
4

1 回答 1

2

在这个问题中,转换显然是最棘手的部分,所以我更喜欢从您提供的简单条形图示例转到使用 Mike Bostock 的示例的堆叠条形图。

您提供的堆叠实现的主要问题是信息是“颠倒的”,因为您希望每个条形图位于数据数组的不同元素中,这样您就可以通过时间戳来识别数据。

所以,首先,让我们为每个元素定义一个包含一组值的数据:

function next () {
    return {
        time: ++t,
        value: d3.range(3).map(getRand)
    };
}

然后,在redraw()函数内部:

  • 首先格式化条形堆栈的数据:

    customData = data.map(function(d){
        y0=0
        return {value:d.value.map(function(d){return {y0:y0, y1: y0+=d}}), time:d.time}
    })
    
  • 然后为每一堆酒吧创建组

    var state = graph.selectAll(".g")
        .data(customData, function(d) { return d.time; });
    var stateEnter = state.enter().append("g")
        .attr("class", "g")
        .attr("transform", function(d) { return "translate(" + x(d.time+1) + ",0)"; });
    
  • 然后,添加该组的堆叠条:

    stateEnter.selectAll("rect")
        .data(function(d) { return d.value; })
        .enter().append("rect")
        .attr("width", barWidth)
        .attr("y", function(d) {return y(d.y1); })
        .attr("height", function(d) { return y(d.y0) - y(d.y1); })
        .attr("class", "bar")
        .style("fill", function(d,i) { return color(i); });
    
  • 移动每个条形组以更新 x 值:

    state.transition().duration(1000)
        .attr("transform", function(d) {console.log(d); return "translate(" + x(d.time) + ",0)"; });
    
  • 删除旧值

    state.exit()
        .attr("transform", function(d) {return "translate(" + x(d.time) + ",0)";})
        .remove()
    

这是一个工作示例

PS:下次请提供jsFiddles,这样我们就不用去你页面的源代码提供解决方案了。此外,尽量减少您示例的代码(删除轴,无用的解析等),以便我们可以集中精力解决问题。此外,在此过程中,您通常会在隔离问题时自己发现问题。

于 2013-06-21T07:15:48.993 回答