用新数据更新堆积条形图

问题描述

我开始在 js 中学习 d3(使用 d3 v4)。我可以使用我在某处找到的代码成功地用我的数据绘制一个堆积条形图。现在我想让它响应用户从下拉菜单中的选择。我知道我需要退出数据并根据连接模式进行合并。但我无法更改代码以使其工作。当我在输入和追加之后的某处添加 .merge() 时(就像我之前为简单条形图所做的那样),它不再绘制。

我已经处理了我的数据,现在它是:{country:"name-of-country",Civil: number,Military: numbr}.58 行。对于任何选定的年份。所以 Stack 由 2 个类别组成。 xAxis 代表国家,yAxis 代表数字。 我有一个函数可以从下拉列表中读取并将选定的 YEAR 传递给 draw 函数。 有人能帮我更新我的堆叠栏吗?

//d3.csv(...
    //do process
    //StackedBar("44"); for the first time
//});
//end of Process data
//Country array is the name of countries. CountryCiv and CountryMil both contain rows of 8 numbers. each row is for a country. CountryCiv and CountryMil will be the categories of stacked bar.

function ChangeYear(v) {
    NewDraw=document.getElementById("chosenyear").value;
    console.log(NewDraw);
    StackedBar(NewDraw);
}

function StackedBar(SpecYear){

    var IndYear= d3.scaleLinear()
        .domain([39,46]).range([0,7]);
    year=IndYear(SpecYear);
    
  
  //for this selected year:
    data=[];t=0;
    for (let i=0; i<Country.length; i++){
            data.push({country: Country[i],civilian: Math.round(CountryCiv[i][year]),military: Math.round(CountryMil[i][year])
                       //total: Math.round(CountryCiv[i][year]+CountryMil[i][year])
            });     
            if (Math.round(CountryCiv[i][year]+CountryMil[i][year])>t){t=Math.round(CountryCiv[i][year]+CountryMil[i][year])};  
    };
  //result:
    //console.log(data); 
  // example: an array of: {country: "Latvia",civilian: 32857,military: 0},.......


    //Make the svg
    var svg = d3.select("#stacked"),margin = {top: 20,right: 180,bottom: 80,left: 40},width = +svg.attr("width") - margin.left - margin.right,height = +svg.attr("height") - margin.top - margin.bottom,g = svg.append("g").attr("transform","translate(" + margin.left + "," + margin.top + ")");

    
    var x = d3.scaleBand()
        .rangeRound([0,width])
        .padding(0.3)
        .align(0.3);

    var y = d3.scaleLinear()
        .rangeRound([height,0]);

    var z = d3.scaleOrdinal(d3.schemeCategory20);


    var stack = d3.stack();
    data.sort((a,b) => d3.ascending(a.civilian+a.military,b.civilian+b.military)).reverse();
console.log(data);
data=data.splice(0,20);
console.log(Object.keys(data[0]));
console.log(data);

    x.domain(data.map(function(d) { return d.country; }));
    y.domain([0,t]).nice();
    z.domain(Object.keys(data[0]).slice(1));

    g.selectAll(".serie")
        .data(stack.keys(Object.keys(data[0]).slice(1))(data))
        .enter().append("g")
          .attr("class","serie")
          .attr("fill",function(d) { return z(d.key); })
        .selectAll("rect")
        .data(function(d) { return d; })
        .enter().append("rect")
          .attr("x",function(d) { return x(d.data.country); })
          .attr("y",function(d) { return y(d[1]); })
          .attr("height",function(d) { return y(d[0]) - y(d[1]); })
          .attr("width",x.bandwidth());

      g.append("g")
          .attr("class","axis axis--x")
          .attr("transform","translate(0," + height + ")")
          .call(d3.axisBottom(x))
          .selectAll("text")
            .style("text-anchor","end")
            .attr("dx","-.8em")
            .attr("dy","-.15em")
            .attr("transform","rotate(-65)");

      g.append("g")
          .attr("class","axis axis--y")
          .call(d3.axisLeft(y).ticks(10,"s"))
        .append("text")
          .attr("x",2)
          .attr("y",y(y.ticks(10).pop()))
          .attr("dy","0.35em")
          .attr("text-anchor","start")
          .attr("fill","#000")
          .text("Casualties");


      //Add legend
      var legend = g.selectAll(".legend")
        .data(Object.keys(data[0]).slice(1).reverse())
        .enter().append("g")
          .attr("class","legend")
          .attr("transform",function(d,i) { return "translate(0," + i * 20 + ")"; })
          .style("font","10px sans-serif");

      legend.append("rect")
          .attr("x",width + 18)
          .attr("width",18)
          .attr("height",18)
          .attr("fill",z);

      legend.append("text")
          .attr("x",width + 44)
          .attr("y",9)
          .attr("dy",".35em")
          .attr("text-anchor","start")
          .text(function(d) { return d; })        
}
<body class="time">

<div id="year-selector">
    <label>Year:</label>
    <select id="chosenyear" onchange="ChangeYear(this.options[this.selectedindex].value)">
                            <option selected value="39">1939</option>
                            <option value="40">1940</option>
                            <option value="41">1941</option>
                            <option value="42">1942</option>
                            <option value="43">1943</option>
                            <option value="44">1944</option>
                            <option value="45">1945</option>
                            <option value="46">1946</option>
                        </select>
                    </div>

<div id="stackedbars">
                <h1>Stacked Bar Chart</h1>
                <svg id="stacked" width="600" height="500">
                </svg>
      </div>
      
<script src="time.js"></script> 
</body>

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)