簡體   English   中英

如何在D3中的條形圖更新數據之間轉換?

[英]How to transition between updated data of bar chart, in d3?

我試圖了解使用D3的條形圖中的過渡。 我現在正在做的是更新兩個不同數據集之間的圖表。 我包含一個過渡,但它是從軸的底部開始的,而不是在兩者之間過渡。 我的目標是讓它在兩者之間過渡,然后再更改顏色。 我正在使用這個有用的示例來了解更新的數據(我的代碼段差別不大)。 感謝您的關注。

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

您有正確的主意...您想要實現Mike Bostock 在此描述的對象恆定性。 保持穩定性的關鍵應該是數據中的“產品”(而不是“購買”)。

在你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/
注意頂部的按鈕以實現過渡。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM