按单位和百分比的堆积条形图
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)))
总结
我想显示一个条形图,其维度是天数,堆叠类别是另一个(即 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)))