dc.js - Stacked bar chart with empty bin filter displaying in strange way

旧街凉风 提交于 2019-11-28 14:36:49

Wow, that is pretty awful behavior. What is going on here is that the stack mixin doesn't like having different a different set of X values for each stack. The chart displays fine if remove_empty_bins is not used (as demonstrated by @Cyril's answer, which just disables it).

It's a more difficult problem to remove empty bins across a set of groups and make them all have the same bins. The problem isn't really demonstrated by this data set, because all the bins are used by at least one group, and the remove_empty_bins isn't helpful here, but I think I get what you're looking for.

I think the "easiest" thing to do is to create a combined group with all the data and then use accessors for the stacks:

function combine_groups() {
    var groups = Array.prototype.slice.call(arguments);
    return {
        all: function() {
            var alls = groups.map(function(g) { return g.all(); });
            var gm = {};
            alls.forEach(function(a, i) {
                a.forEach(function(b) {
                    if(!gm[b.key]) {
                        gm[b.key] = new Array(groups.length);
                        for(var j=0; j<groups.length; ++j)
                            gm[b.key][j] = 0;
                    }
                    gm[b.key][i] = b.value;
                });
            });
            var ret = [];
            for(var k in gm)
                ret.push({key: k, value: gm[k]});
            return ret;
        }
    };
}

var combined = combine_groups(personDimGroup_filtered_group, personDimGroup2_filtered_group);

barChart
    .width(500)
    .height(250)
    .dimension(personDim)
    .group(combined, "1", function(d) { return d.value[0]; })
    .stack(combined, "2", function(d) { return d.value[1]; })
    .elasticY(true)
    .elasticX(true)
    .xUnits(dc.units.ordinal)
    .x(d3.scale.ordinal());    

Working fork of your fiddle: http://jsfiddle.net/gordonwoodhull/uwczq9n1/5/

The problem is because in data philip has amount =0. Inside your function, you filter records who have value = 0

function remove_empty_bins(source_group) {
    return {
        all:function () {
            return source_group.all().filter(function(d) {
                return value !=0 ;
            });
        }
    };
} 

Thus the function personDimGroup_filtered_group.all() should return 3 values each for philip,steve and robert but it returns 2 i.e. steve and robert because for philip the value is 0, so the stackbarchart break.

The code should have been:

function remove_empty_bins(source_group) {
    return {
        all:function () {
            return source_group.all().filter(function(d) {
                return true;
            });
        }
    };
}

Working fiddle is here: http://jsfiddle.net/cyril123/xdcvr2kf/4/

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