如何在d3中更新条形图的更新数据?

时间:2017-06-25 01:41:09

标签: javascript d3.js charts bar-chart

我试图通过D3了解条形图中的过渡。我现在正在做的是更新两个不同数据集之间的图表。我有一个转换,但它从轴的底部开始,而不是在两者之间转换。我的目标是让它在两者之间转换,然后改变颜色。我使用这个有用的example来了解更新的数据(我的代码段没有太大差异)。谢谢你看看。

var bothData = [
{
    "year": "2014",
    "product": "Books & DVDs",
    "purchase": "0.5"
    },
    {
    "year": "2002",
    "product": "Books & DVDs",
    "purchase": "10"
    },
    {
    "year": "2014",
    "product": "Beer & Wine",
    "purchase": "7"
    },
    {
    "year": "2002",
    "product": "Beer & Wine",
    "purchase": "3"
    },
    {
    "year": "2014",
    "product": "Food",
    "purchase": "12"
    },
    {
    "year": "2002",
    "product": "Food",
    "purchase": "12"
    },
    {
    "year": "2014",
    "product": "Home Supplies",
    "purchase": "7"
    },
    {
    "year": "2002",
    "product": "Home Supplies",
    "purchase": "6"
    }
    ];

    var data2002 = [];
    var data2014 = [];

    for(var i = 0; i < bothData.length; i++){
        if(bothData[i]["year"] === "2002"){
            data2002.push(bothData[i]);
        }else{
            data2014.push(bothData[i]);
        }
    }

    function change(value){

        if(value === '2002'){
            update(data2002);
        }else if(value === '2014'){
            update(data2014);
        }
    }

    function update(data){
        xChart.domain(data.map(function(d){ return d.product; }) );
        yChart.domain( [0, d3.max(data, function(d){ return + d.purchase; })] );

        var barWidth = width / data.length;

        var bars = chart.selectAll(".bar")
                .remove()
                .exit()
                .data(data, function(d){ return d.purchase; })
                .enter()
                .append("rect")
                .attr("class", "bar")
                .attr("x", function(d, i){ return i * barWidth + 1 })
                .attr("y",500)
                .attr("height",0)
                .attr("width", barWidth - 5)
                .each(function(d){ 
                  if(d.year === "2014"){
                    d3.select(this)
                    .style('fill','#ea5454');
                  }else{
                    d3.select(this)
                    .style('fill','#4e97c4');
                  };
                });

        bars.transition()
          .duration(600)
          .ease(d3.easeLinear)
          .attr('y', function(d){ return yChart(d.purchase); })
          .attr('height', function(d){ return height - yChart(d.purchase); });

        chart.select('.y').call(yAxis);


        chart.select('.xAxis')
            .attr("transform", "translate(0," + height + ")")
            .call(xAxis)
            .selectAll("text")
                .style("text-anchor", "end")
                .attr("dx", "-.8em")
                .attr("dy", ".15em")
                .attr("transform", function(d){
                    return "rotate(-65)";
                });

         }

    var margin = {top: 20, right: 20, bottom: 95, left: 50};
    var width = 400;
    var height = 500;

    var chart = d3.select(".chart")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
            .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    var xChart = d3.scaleBand()
                .range([0, width]);

    var yChart = d3.scaleLinear()
                .range([height, 0]);

    var xAxis = d3.axisBottom(xChart);
    var yAxis = d3.axisLeft(yChart);


    chart.append("g")
        .attr("class", "y axis")
        .call(yAxis)

    chart.append("g")
        .attr("class", "xAxis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis)
        .selectAll("text")
        .style("text-anchor", "end")
        .attr("dx", "-.8em")
        .attr("dy", ".15em")
        .attr("transform", function(d){
            return "rotate(-65)";
                });

    chart.append("text")
        .attr("transform", "translate(-35," +  (height+margin.bottom)/2 + ") rotate(-90)")
        .text("Purchases");

    chart.append("text")
        .attr("transform", "translate(" + (width/2) + "," + (height + margin.bottom - 5) + ")")
        .text("Products");

    update(data2002);

1 个答案:

答案 0 :(得分:2)

你有正确的想法......你想要实现Mike Bostock所描述的here对象的持久性。坚持不懈的关键应该是&#34;产品&#34;来自您的数据(不是&#34;购买&#34;)。

update功能中,定义bars,如下所示:

var bars = chart.selectAll(".bar")
            .data(data, function(d){ return d.product; })

然后将.enter.exit.transition函数分开:

       bars.exit()
         .remove()
       bars.enter()
         ....
       bars.transition()

你的.enter函数中有一些奇怪的东西 - 比如将条形高度设置为零。所以我修改了你的.enter和.transition函数:

          bars.enter()
            .append("rect")
            .attr("class", "bar")
            .attr("x", function(d, i){return i * barWidth + 1 })
            .attr("y",function(d){ return yChart(d.purchase); })
            .attr("height",function(d){ return height - yChart(d.purchase); })
            .attr("width", barWidth - 5)
            .attr('fill', function(d){ 
              if(d.year === "2014"){
                return'#ea5454'
              }else{
                return'#4e97c4'
              }

            })
    bars.transition()
      .duration(600)
      .ease(d3.easeLinear)
      .attr('y', function(d){ return yChart(d.purchase); })
      .attr('height', function(d){ return height - yChart(d.purchase); })
      .style('fill', function(d){
        if(d.year === "2014"){
          return '#ea5454'
        } else {
          return '#4e97c4'
        }
      })

这是一个有效的jsfiddle:https://jsfiddle.net/genestd/asoLph2w/
请注意顶部的按钮以实现转换。