3

我可以第一次填充堆积条形图,但我的要求是在单击按钮时使用新数据更新堆积条形图。单击按钮时,我正在调用后端并获取数据,请指导我如何更新堆积条形图。我的问题是将新数据传递给条形图。

 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); })

  );

    });
4

1 回答 1

7

要更新您的数据,您只需要再次选择 svg 元素并重新绑定数据。在您的示例中,您已经选择了#barchart,现在您只需要重新绑定数据。您可以像第一次创建 svg 元素时那样做。所以这样的事情应该可以解决问题:

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); });
}
于 2013-08-12T13:21:23.400 回答