Stacked Bar Chart by Units & Percentage

给你一囗甜甜゛ 提交于 2019-12-22 12:26:33

问题


Summary

I want to display a bar chart who's dimension is days and who's stacked categories is another (i.e. x-axis = days and stack = category-1), but then, rather than display the simple quantity-sum of each group/stack, I want to show the percentage of the day.

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

Details

I have data with dates, quantities, and other classifiers. For the purpose of this question I can simplify it to this:

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

I can set up a bar chart, by day, that shows total units (quantity), stacked by cat (see JSFiddle). But what I'd like to do is set that same graph so that it shows the quantity on each day, stacked by cat, as a percent of total quantity that day. So the output would look, graphically, like the following.

[
 {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)
]

Images

The one on the left comes from the data above and can be made in the JSFiddle. The one on the right is what I'm trying to make, based on the same dataset (xf = crossfilter(data);). I hardcoded it (above and in the JSFiddle) to create the second just to visually show what I'm looking to do.


回答1:


I this is usually called a normalized stacked bar chart.

I'd organize the data with just one group so that all the values are accessible at once, using a custom reduce function:

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 {};
    });

This is pretty much the standard way to reduce multiple values at once from the FAQ.

The advantage of this is that when you access the values, you can easily divide by the sum of all the values:

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



来源:https://stackoverflow.com/questions/51141367/stacked-bar-chart-by-units-percentage

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!