简体   繁体   English

D3处理堆积的条形图错误

[英]D3 processes a stacked bar chart wrong

I have a CSV file named dummydata_genreCountByYear.csv . 我有一个名为dummydata_genreCountByYear.csv的CSV文件。 It looks like this: 看起来像这样:

Year,Unknown,show tunes,jazz,rock,heavy metal,rap,r&b,trap,hip hop
1950,1,2,5,,,,,,
1990,,,,2,2,2,,,
2016,,,,,,,5,1,3

I want to make a normalized stacked bar chart showing popularity of genres for each year. 我想制作一个标准化的堆叠条形图,以显示每年流派的流行程度。 I'm mostly following this example of a normalized stacked bar chart. 我主要关注的是标准化堆叠条形图的示例

Here's my index.html : 这是我的index.html

<div id="genre-by-year-chart-container" class="chart">
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.js" charset="utf-8"></script>
<script type="text/javascript">
    var x, y, xAxis, yAxis;

    var genreByYearContainerID= "genre-by-year-chart-container";
    var margin= {
        top: 50,
        right: 30,
        bottom: 100,
        left: 0
    };
    var marginTop=      margin.top;
    var marginLeft=     margin.left;
    var marginBottom=   margin.bottom;
    var marginRight=    margin.right;

    var width=  document.getElementById(genreByYearContainerID).clientWidth - marginRight - marginLeft;

    var widthWithMargins=   width+marginRight+marginLeft;
    var height=             1000;

    var chart=      d3.select('#'+genreByYearContainerID)
                    .append("svg");
    chart.attr('width',widthWithMargins);
    chart.append('g')
        .attr("transform","translate("+marginLeft+','+marginTop+')');

    var color=  d3.scale.category20();
    d3.csv("dummydata_genreCountByYear.csv", function(error, data){
        x=  d3.scale
            .ordinal()
            .rangeRoundBands([0,width], 0.1);

        y=  d3.scale
            .linear()
            .rangeRound([height,0]);

        xAxis=  d3.svg.axis()
                .scale(x)
                .orient("bottom");

        yAxis=  d3.svg.axis()
                .scale(y)
                .orient("left")
                .tickFormat(d3.format(".0%"));

        color.domain(d3.keys(data[0])
            .filter(function(key){
                return key !== "Year";
            }
        ));

        data.forEach(function(d){
            var y0= 0;
            d.Genres=   color.domain().map(function(name){
                var obj=    {
                    name:   name,
                    y0:     y0,
                    y1:     y0 += +d[name]
                };
                return obj;
            });

            d.Genres.forEach(function(d){
                d.y0 /= y0;
                d.y1 /= y0;
            });
        });

        data.sort(function(a,b){
            return b.Genres[0].y1 + a.Genres[0].y1;
        });

        x.domain(data.map(function(d){
            return d.Year;
        }));

        chart.append('g')
            .attr("class","x axis")
            .attr("transform","translate(0,"+height+')')
            .call(xAxis);

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

        var year=   chart.selectAll(".year")
                    .data(data)
                    .enter()
                    .append('g')
                    .attr("class","year")
                    .attr("transform",function(d){
                        return "translate(" + x(d.Year) + ",0)";
                    });

        year.selectAll("rect")
            .data(function(d){
                return d.Genres;
            })
            .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);
            });
    });
</script>

But when I open up the file, here's what I see: 但是,当我打开文件时,会看到以下内容:

试图制作标准化的堆叠条形图

And when I inspect the elements of the DOM in my browser for each .year element, here's an example of what I see: 当我在浏览器中针对每个.year元素检查DOM元素时,以下是我看到的示例:

<g class="year" transform="translate(30,0)">
  <rect width="261" y="1000" height="0" style="fill: rgb(31, 119, 180);">
  <rect width="261" y="1000" height="0" style="fill: rgb(174, 199, 232);">
  <rect width="261" y="1000" height="0" style="fill: rgb(255, 127, 14);">
  <rect width="261" y="667" height="333" style="fill: rgb(255, 187, 120);">
  <rect width="261" y="333" height="334" style="fill: rgb(44, 160, 44);">
  <rect width="261" y="0" height="333" style="fill: rgb(152, 223, 138);">
  <rect width="261" y="0" height="0" style="fill: rgb(214, 39, 40);">
  <rect width="261" y="0" height="0" style="fill: rgb(255, 152, 150);">
  <rect width="261" y="0" height="0" style="fill: rgb(148, 103, 189);">
</g>

The above HTML is for the leftmost .year element. 上面的HTML用于最左边的.year元素。 The rect elements seem to have the correct y , height and style attributes. rect元素似乎具有正确的yheightstyle属性。 So why won't this code properly display a normalized stacked bar chart? 那么,为什么这段代码不能正确显示标准化的堆积条形图呢?

You have to define a height for your svg . 您必须为svg定义height

Something like (or whatever height you need for your area): 某种东西(或您所在区域需要的高度):

chart.attr('height', 1000);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM