交叉过滤器维度计数的DC.js直方图 [英] DC.js histogram of crossfilter dimension counts

查看:51
本文介绍了交叉过滤器维度计数的DC.js直方图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个输入以下数据结构的交叉过滤器。

I have a crossfilter with the following data structure being inputted.

project | subproject | cost
data = [
["PrA", "SubPr1", 100],
["PrA", "SubPr2", 150],
["PrA", "SubPr3", 100],
["PrB", "SubPr4", 300],
["PrB", "SubPr5", 500],
["PrC", "SubPr6", 450]]

我可以创建一个条形图,其中包含每个项目的总成本:

I can create a barchart that has the summed cost per project:

var ndx = crossfilter(data)
var projDim = ndx.dimension(function(d){return d.project;});
var projGroup = costDim.group().reduceSum(function(d){return d.budget;});

我要做的是根据项目成本创建dc.js直方图...所以{450 :2,300:1}等。据我所知,交叉过滤器只能为维度输入每行的属性。有没有解决的办法?

What I want to do is create a dc.js histogram by project cost...so {450: 2, 300: 1}, etc. As far as I can tell, crossfilter can have only attributes of each row be input for a dimension. Is there a way around this?

推荐答案

接受挑战!

是的,交叉过滤器确实可以不支持这种双重缩减,但是如果您愿意接受效率的轻微损失,则可以创建伪尺寸和 假组具有所需的行为。幸运的是,dc.js并没有使用太多的crossfilter API,因此您不必实现太多的方法。

It is true, crossfilter does not support this kind of double-reduction, but if you are willing to accept a slight loss of efficiency, you can create "fake dimensions" and "fake groups" with the desired behavior. Luckily, dc.js doesn't use very much of the crossfilter API, so you don't have to implement too many methods.

技巧的第一部分是复制维度和组,以便新维度和旧维度将各自进行过滤。

The first part of the trick is to duplicate the dimension and group so that the new dimension and old dimension will each observe filtering on the other.

第二部分是创建伪造的组和维度,其中沿着复制的组的箱走,然后根据值而不是键重新进行重新过滤。

The second part is to create the fake groups and dimensions, which walk the bins of the copied group and rebin and refilter based on the values instead of the keys.

下面是一般解决方案的开始。对于某些图表,还必须实现 group.top(),通常可以将其转发给 group.all()

A start of a general solution is below. For some charts it is also necessary to implement group.top(), and it is usually okay to just forward that to group.all().

function values_dimension(dim, group) {
    return {
        filter: function(v) {
            if(v !== null)
                throw new Error("don't know how to do this!");
            return dim.filter(null);
        },
        filterFunction: function(f) {
            var f2 = [];
            group.all().forEach(function(kv) {
                if(f(kv.value))
                    f2.push(kv.key);
            });
            dim.filterFunction(function(k) {
                return f2.indexOf(k) >= 0;
            });
            return this;
        }
    };
}

function values_group(group) {
    return {
        all: function() {
            var byv = [];
            group.all().forEach(function(kv) {
                if(kv.value === 0)
                    return;
                byv[kv.value] = (byv[kv.value] || 0) + 1;
            });
            var all2 = [];
            byv.forEach(function(d, i) {
                all2.push({key: i, value: d});
            });
            return all2;
        }
    };
}

// duplicate the dimension & group so each will observe filtering on the other
var projDim2 = ndx.dimension(function(d){return d.project;});
var projGroup2 = projDim2.group().reduceSum(function(d){return d.budget;});
var countBudgetDim = values_dimension(projDim2, projGroup2),
    countBudgetGroup = values_group(projGroup2);

jsfiddle此处: http://jsfiddle.net/gordonwoodhull/55zf7L1L/

jsfiddle here: http://jsfiddle.net/gordonwoodhull/55zf7L1L/

这篇关于交叉过滤器维度计数的DC.js直方图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆