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

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

问题描述

我可以第一次填充堆叠条形图,但我的要求是更新堆叠条形图与按钮点击的新数据。在按钮点击,我打电话给后端和获取数据,请你指导我如何更新堆积条形图表。我的问题是将新数据传递到条形图。

  d3.json(http:// myhost / ITLabourEffortChart / effort /努力,函数(错误,数据){
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 b $ b 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 )
.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){returntranslate(+ 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 (d){
return y(d.y1);})
.attr(height,function(d){return y(d.y0) - y(d.y1);} )
.style(fill,function(d){return color(d.name);});


在更新我调用下面的方法
function redraw(){
d3.json(http:// localhost:8080 / ITLabourEffortChart / effort / effort / YrReports,function(error,data){

color.domain(d3.keys(data.effort [0])。filter(function(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 b .attr(width,x.rangeBand())
.attr(y,function(d){
return y(d.y1);})
.attr (height,function(d){return y(d.y0)-y(d.y1);})
。 ; }
.attr(x,function(d){
return x(d.x);})

);

});
.attr(x,function(d){
return x(d.x);})

);

});


解决方案

要更新您的数据, svg元素并重新绑定数据。在你的例子中,你已经选择 #barchart ,现在你只需要重新绑定数据。你可以这样做,就像你第一次创建svg元素时一样。所以这样的东西应该做的诀窍:

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

您可以在这里找到更详细的解释:
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){returntranslate(+ 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);});
}


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

  );

    });

解决方案

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

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

Update:

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天全站免登陆