按单位和百分比的堆积条形图

Stacked Bar Chart by Units & Percentage

总结

我想显示一个条形图,其维度是天数,堆叠类别是另一个(即 x 轴 = 天数和堆栈 = 类别 1),但是,而不是显示每个的简单数量总和group/stack,我想显示一天的百分比

JSFiddle https://jsfiddle.net/wostoj/L1q50d4g/

详情

我有日期、数量和其他分类器的数据。为了这个问题的目的,我可以将其简化为:

data = [
 {day: 1, cat: 'a', quantity: 25},
 {day: 1, cat: 'b', quantity: 15},
 {day: 1, cat: 'b', quantity: 10},
 {day: 2, cat: 'a', quantity: 90},
 {day: 2, cat: 'a', quantity: 45},
 {day: 2, cat: 'b', quantity: 15},
]

我可以通过 day 设置条形图,显示总单位数 (quantity),堆叠 cat (参见 JSFiddle)。但我想做的是设置相同的图表,以便它显示每个 day 的数量,由 cat 堆叠,作为当天总 quantity 的百分比。所以输出看起来像下面这样。

[
 {day: 1, cat: 'a', percent: 0.5}, //   25    / (25+15+10)
 {day: 1, cat: 'b', percent: 0.5}, // (15+10) / (25+15+10)
 {day: 2, cat: 'a', percent: 0.9}, // (90+45) / (90+45+15)
 {day: 2, cat: 'b', percent: 0.1}  //   15    / (90+45+15)
]

图片

左边的来自上面的数据,可以在JSFiddle中制作。右边的是我要基于相同数据集 (xf = crossfilter(data);) 制作的。我对它进行了硬编码(在 JSFiddle 之上和中)以创建第二个只是为了直观地显示我想要做什么。

我这个通常叫一个normalized stacked bar chart.

我只用一组来组织数据,这样所有的值都可以同时访问,使用自定义的 reduce 函数:

var group = dayDim.group().reduce(
    function(p, v) {
        p[v.cat] = (p[v.cat] || 0) + v.quantity;
        return p;
    },
    function(p, v) {
        p[v.cat] = p[v.cat] - v.quantity;
        return p;
    },
    function() {
        return {};
    });

这几乎是常见问题解答中的标准 way to reduce multiple values at once

这样做的好处是,当你访问值时,你可以很容易地除以所有值的总和:

  .group(group, 'a', kv => kv.value.a / d3.sum(Object.values(kv.value)))
  .stack(group, 'b', kv => kv.value.b / d3.sum(Object.values(kv.value)))

Fork of your fiddle.