我可以第一次填充堆积条形图,但我的要求是在按钮点击时使用新数据更新堆积条形图。点击按钮,我打电话给后端并获取数据,你能指导我如何更新堆积的条形图。我的问题是将新数据传递给条形图。
d3.json("http://myhost/ITLabourEffortChart/effort/effort",function(error, data){
color.domain(d3.keys(data.effort[0]).filter(function(key) {
return key !== "qName"; }));
data.effort.forEach(function(d) {
var y0 = 0;
d.effortHr = color.domain().map(function(name) {
return {name: name, y0: y0, y1: y0 += +d[name]}; });
d.total = d.effortHr[d.effortHr.length - 1].y1;
});
x.domain(data.effort.map(function(d) { return d.qName; }));
y.domain([0, d3.max(data.effort, function(d) {
return d.total; })]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("FTE");
var state = svg.selectAll(".layer")
.data(data.effort)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d) { return "translate(" + x(d.qName) + ",0)"; });
rect = state.selectAll("rect")
.attr("id", "barchart")
.data(function(d) {
return d.effortHr; })
.enter().append("rect")
.attr("width", x.rangeBand())
.attr("y", function(d) {
return y(d.y1); })
.attr("height", function(d) { return y(d.y0) - y(d.y1); })
.style("fill", function(d) { return color(d.name); });
On Update i am calling below method
function redraw() {
d3.json("http://localhost:8080/ITLabourEffortChart/effort/effort/YrReports",function(error, data){
color.domain(d3.keys(data.effort[0]).filter(function(key) {
return key !== "qName"; }));
data.effort.forEach(function(d) {
var y0 = 0;
d.ages = color.domain().map(function(name) {
return {name: name, y0: y0, y1: y0 += +d[name]}; });
d.total = d.ages[d.ages.length - 1].y1;
});
var updatebar = svg.selectAll("#barchart");
// Update…
updatebar
.transition()
.duration(500)
.delay(function(d, i) { return i * 10; })
.transition()
.attr("width", x.rangeBand())
.attr("y", function(d) {
return y(d.y1); })
.attr("height", function(d) { return y(d.y0) - y(d.y1); })
.style("fill", function(d) { return color(d.name); }
.attr("x", function(d) {
return x(d.x); })
);
});
.attr("x", function(d) {
return x(d.x); })
);
});
答案 0 :(得分:6)
要更新数据,您只需再次选择svg元素并重新绑定数据。在您的示例中,您已经选择了#barchart
,现在您只需要重新绑定数据。你可以像第一次创建svg Elements时那样做。所以这样的事情应该可以解决问题:
var updatebar = svg.selectAll("#barchart");
.data(newdata)
.transition()
.duration(500)
... (etc.)
在这里您可以找到更详细的解释: http://chimera.labs.oreilly.com/books/1230000000345/ch09.html#_updating_data
更新
好的,不幸的是我不能使用Fiddle所以我只是在这里发布我的工作代码。据我所知,你的selectAll有问题,因为没有名为.effort
的元素。以下是重绘功能的更新代码:
function redraw() {
var effort = [];
var obj = {
pfte: "20",
efte: "50",
qName: "Q1"
};
var obj2 = {
pfte: "10",
efte: "13",
qName: "Q2"
};
effort[0] = obj;
effort[1] = obj2;
var newDataSet = new Object();
newDataSet.effort = effort;
color.domain(d3.keys(newDataSet.effort[0]).filter(function (key) {
return key !== "qName";
}));
effortDataSet = newDataSet.effort;
effortDataSet.forEach(function (d) {
var y0 = 0;
d.effortHr = color.domain().map(function (name) {
return { name: name, y0: y0, y1: y0 += +d[name] };
});
d.total = d.effortHr[d.effortHr.length - 1].y1;
});
state = svg.selectAll(".g")
.data(effortDataSet)
.attr("class", "g")
.attr("transform", function (d) { return "translate(" + x(d.qName) + ",0)"; });
state = state.selectAll("rect")
.data(function (d) {
return d.effortHr;
})
.attr("width", x.rangeBand())
.attr("y", function (d) {
return y(d.y1);
})
.attr("height", function (d) {
//console.log(y(d.y0) - y(d.y1));
return y(d.y0) - y(d.y1);
})
.style("fill", function (d) { return color(d.name); });
}