如何在 D3 中更新堆栈条形图中的数据 [英] How to update data in stack bar chart in D3

查看:17
本文介绍了如何在 D3 中更新堆栈条形图中的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am able to populate a stacked bar chart first time, but my requirement is to update the stacked bar chart with new data on button click. On button click, i m making call to backend and getting the data, Could you please guide me as how to update the stacked bar char chart. My problem is passing the new data to bar chart.

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

  );

    });

推荐答案

要更新数据,您只需再次选择 svg 元素并重新绑定数据.在您的示例中,您已经选择了 #barchart,现在您只需要重新绑定数据.您可以按照与第一次创建 svg Elements 时相同的方式进行操作.所以这样的事情应该可以解决问题:

To update your data you will just need to select the svg elements again and rebind the data. In your example you are already selecting the #barchart, now you just need to rebind the data. And you can do that in the same way you did it when you first created the svg Elements. So something like this should do the trick:

var updatebar = svg.selectAll("#barchart");
.data(newdata)
.transition()
.duration(500)
... (etc.)

在这里你可以找到更详细的解释:http://chimera.labs.oreilly.com/books/1230000000345/ch09.html#_updating_data

Here you can find a more detailed explaination: http://chimera.labs.oreilly.com/books/1230000000345/ch09.html#_updating_data

更新:

好吧,不幸的是我不能使用 Fiddle,所以我只是在这里发布我的工作代码.据我所知,您的 selectAll 有问题,因为没有名为 .effort 的元素.以下是重绘功能的更新代码:

Ok, unfortunately I cannot use Fiddle so I just post my working code here. As far as I could see you have a problem with your selectAll, because there is no element called .effort. Here is the updated code for your redraw-function:

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

这篇关于如何在 D3 中更新堆栈条形图中的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆