D3处理堆积的条形图错误

时间:2016-05-11 18:24:11

标签: javascript jquery html csv d3.js

我有一个名为dummydata_genreCountByYear.csv的CSV文件。它看起来像这样:

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

我想制作一个标准化的叠加条形图,显示每年流派的流行程度。我主要关注标准化堆积条形图的this example

这是我的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>

但是当我打开文件时,这就是我所看到的:

Trying to make a normalized stacked bar chart

当我在浏览器中检查每个.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>

以上HTML适用于最左边的.year元素。 rect元素似乎具有正确的yheightstyle属性。那么为什么这段代码不能正确显示标准化的堆积条形图?

1 个答案:

答案 0 :(得分:2)

您必须为height定义svg

类似的东西(或您所在地区需要的任何高度):

chart.attr('height', 1000);