首页 > 解决方案 > 按单位和百分比的堆积条形图

问题描述

概括

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

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},
]

我可以设置一个条形图 by 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 上方和中)以创建第二个,只是为了直观地展示我想要做什么。

在此处输入图像描述 在此处输入图像描述

标签: dc.jscrossfilter

解决方案


我这通常称为标准化堆积条形图

我只用一组来组织数据,以便使用自定义 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 {};
    });

这几乎是从常见问题解答中一次减少多个值的标准方法

这样做的好处是,当您访问这些值时,您可以轻松地除以所有值的总和:

  .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)))

和一堆栈

你的小提琴的叉子。


推荐阅读