2013-06-21 83 views
0

我想获得一个堆叠的条形图,以与此条形图相同的方式过渡 - http://www.animatedcreations.net/d3/animatedBarChart_Slide.html 我一直关注Mike Bostock的“条形图,第2部分”示例,并且事情是好的,直到过渡堆叠酒吧进出。
我的破碎的例子在这里 - http://www.animatedcreations.net/d3/stackedBarChart7.html 我相当确定问题在于我如何设置数据,如下所示。我甚至想知道数据是否需要转换为列而不是图层? 洞察力非常感谢:)谢谢。D3.js堆积的条形图破碎的过渡

从重绘():

// 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. 

回答

1

在这个问题中,转变显然是最棘手的部分,所以我者优先从您提供的simple bar example去,去用迈克·博斯托克的例子中,stacked bar图。

您提供的堆栈实现的主要问题是信息是“反向的”,因为您希望每个栏位于数据数组的不同元素中,这样您可以通过其时间戳识别数据。

因此,首先,让我们定义一些数据与值的每个元素的数组:

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() 
    

Here is a working example

PS:下一次,请提供jsFiddles,以便我们不必转到您的页面的源代码来提供解决方案。另外,尽量尽量减少你的例子的代码(删除轴,无用的解析等),所以我们可以专注于什么是错的。另外,在这个过程中,你会经常在你孤立它时发现问题。

+0

谢谢。你的回答描述得很好:) – user2477109