我正在使用基于d3和crossfilter的Dimensional Charting javascript库dc.js制作堆叠的条形图。我是dc.js库的新手。我正在尝试使用csv文件显示堆叠的条形图。我不明白如何按照csv格式创建堆叠的条形图。

State_Name   Age_19_Under   Age_19_64   Age_65_84
 AL      26.9             62.3            9.8
 AL      23.5             60.3            14.5
 NW      24.3             62.5            11.6
 NW      24.6             63.3            10.9
 BR      24.5             62.1            12.1
 BR      24.7             63.2            10
 GH      25.6             58.5            13.6
 GH      24.1             61.6            12.7
 KS      24.8             59.5            13.5


我正在尝试以下代码:

<script type="text/javascript">
   var stacked = dc.barChart("#chart");
  d3.csv("{% static 'sampledata/healthdata111.csv' %}", function(error, experiments) {

   var ndx = crossfilter(experiments);
   var all = ndx.groupAll();

   var stateDim=ndx.dimension(function (d){
    return d.State_Name;
   });

   var eventsByDate = stateDim.group().reduce(
        function (p, v) {
            p.Age_19_Under += v.Age_19_Under;
            p.Age_19_64 += v.Age_19_64;
            p.Age_65_84 += v.Age_65_84;
            return p;
        },
        function (p, v) {
            p.Age_19_Under -= v.Age_19_Under;
            p.Age_19_64 -= v.Age_19_64;
            p.Age_65_84 -= v.Age_65_84;
            return p;
        },
        function () {
            return {
                Age_19_Under: 0,
                Age_19_64: 0,
                Age_65_84: 0
            };
        }
  );

  var colorRenderlet = function (chart) {
    chart.selectAll("rect.bar")
            .on("click", function (d) {
                function setAttr(selection, keyName) {
                    selection.style("fill", function (d) {
                        if (d[keyName] == "Age_19_Under") return "#63D3FF";
                        else if (d[keyName] == "Age_19_64") return "#FF548F";
                        else if (d[keyName] == "Age_65_84") return "#9061C2";
                    });
                }
                setAttr(_chart.selectAll("g.stack").selectAll("rect.bar"), "layer");
                setAttr(_chart.selectAll("g.dc-legend-item").selectAll("rect"), "name")
            });
};

 stacked
        .margins({top: 50, right: 20, left: 50, bottom: 50})
        .width(500)
        .height(200)
        .gap(50)
        .dimension(stateDim)
        .group(eventsByDate, "Age_19_Under")
        .valueAccessor(function (d) {
            return d.value.Age_19_Under;
        })
        .stack(eventsByDate, "Age_19_64", function (d) {
            return d.value.Age_19_64;
        })
        .stack(eventsByDate, "Age_65_84", function (d) {
            return d.value.Age_65_84;
        })
        .x(d3.time.scale().domain([0,5000]))
        .xUnits(d3.time.days)
        .centerBar(true)
        .elasticY(true)
        .brushOn(false)
        .renderlet(colorRenderlet);
       // .legend(dc.legend().x(100).y(0).itemHeight(13).gap(5));

     dc.renderAll();

  });

</script>

最佳答案

我不确定您要尝试与事件处理程序进行哪种互动,因此,撇开这一点,我认为,如果您只为每个年龄类别创建一个单独的组,就可以简化操作。

var experiments = [
    { State_Name: "AL", Age_19_Under: 26.9, Age_19_64: 62.3, Age_65_84: 9.8, Age_85_and_Over: 0.9 },
    { State_Name: "AL", Age_19_Under: 23.5, Age_19_64: 60.3, Age_65_84: 14.5, Age_85_and_Over: 1.8 },
    { State_Name: "NW", Age_19_Under: 24.3, Age_19_64: 62.5, Age_65_84: 11.6, Age_85_and_Over: 1.6 },
    { State_Name: "NW", Age_19_Under: 24.6, Age_19_64: 63.3, Age_65_84: 10.9, Age_85_and_Over: 1.2 },
    { State_Name: "BR", Age_19_Under: 24.5, Age_19_64: 62.1, Age_65_84: 12.1, Age_85_and_Over: 1.3 },
    { State_Name: "BR", Age_19_Under: 24.7, Age_19_64: 63.2, Age_65_84: 10.0, Age_85_and_Over: 2.2 },
    { State_Name: "GH", Age_19_Under: 25.6, Age_19_64: 58.5, Age_65_84: 13.6, Age_85_and_Over: 2.4 },
    { State_Name: "GH", Age_19_Under: 24.1, Age_19_64: 61.6, Age_65_84: 12.7, Age_85_and_Over: 1.5 },
    { State_Name: "KS", Age_19_Under: 24.8, Age_19_64: 59.5, Age_65_84: 13.5, Age_85_and_Over: 2.2 },
];

var ndx = crossfilter(experiments);

var stateDim = ndx.dimension(function (d) { return d.State_Name; });
var age19UnderGroup = stateDim.group().reduceSum(function (d) { return d.Age_19_Under; });
var age19To64Group = stateDim.group().reduceSum(function (d) { return d.Age_19_64; });
var age65To84Group = stateDim.group().reduceSum(function (d) { return d.Age_65_84; });
var age85AndOverGroup = stateDim.group().reduceSum(function (d) { return d.Age_85_and_Over; });

var stackedBarChart = dc.barChart("#chart-row-Poverty1");

stackedBarChart
    .dimension(stateDim)
    .group(age19UnderGroup)
    .x(d3.scale.ordinal())
    .xUnits(dc.units.ordinal)
    .stack(age19To64Group)
    .stack(age65To84Group)
    .stack(age85AndOverGroup)
;

dc.renderAll();


请注意,如果以这种方式进行操作,则必须将四个组之一分配给基本图表才能开始工作。然后剩下的三个图表就放在其顶部。

10-04 19:41