square / crossfilter

Fast n-dimensional filtering and grouping of records.
https://square.github.com/crossfilter/
Other
6.22k stars 1.3k forks source link

Ability to create a (sub) dimension that when filtered does not propogate out its filter #150

Closed vmantese closed 9 years ago

vmantese commented 9 years ago

Say I have a dataset of people. It includes person's name, race,birthcity, and age.

Applying filters across all dimensions is very useful, but sometimes we don't want that.

I want to create a dimension on the data of people's birthcity. I want this particular dimension to filter in(include) only people from St. Louis. The thing is, I don't want this filter to affect the other dimensions(the reason I need a dimension and not a group is because i'm using dc.js dataTables. which does not accept groups). I need this dimension to have all the properties of a normal dimension EXCEPT for the fact that filters applied directly(in the declaration of this sub dimension) to the dimenson do not cross-affect other dimensions. Filters on normal dimensions should STILL filter on this 'sub' dimension.

Let me know if anyone else has wanted something like this, yes I know groups can answer this issue but I need something with the same properties as a dimension EXCEPT outward propagating filters.

If I'm not the only one who wants this and if someone hasn't solved this problem already maybe I'll take a crack at it. Thanks, V

gordonwoodhull commented 9 years ago

dc.js data tables do support groups as dimensions, pretty much by accident. (The coupling between dc.js and crossfilter is very light.)

There is a little bit of info here, and a link to a (complex) example, in this PR: https://github.com/dc-js/dc.js/pull/697. Please try it out and bring any issues to the appropriate dc forums.

gordonwoodhull commented 9 years ago

@vmantese, if this works for you, you should close the ticket. It seems like more a dc.js (documentation) issue than crossfilter.

vmantese commented 9 years ago

Here is the solution I used. Works like a charm.

//Prefilter
function preFilter(dim,okey,oval){

                return{

                    top:function(x1){
                        var a1 = dim.top(x1).filter(function(v){
                            return v[okey] === oval;
                        });
                        return a1;
                    },
                    filter:function(x2){
                        dim.filter(x2);
                    },
                    filterAll:function(){
                        dim.filterAll();
                    },
                    filterExact:function(x4){
                        dim.filterExact(x4);
                    },
                    filterFunction:function(x5){
                        dim.filterFunction(x5);
                    },
                    filterRange:function(x6){
                        dim.filterRange(x6);
                    },
                    bottom:function(x7){
                        dim.bottom(x7);
                    },
                    dispose:function(){
                        dim.dispose();
                    },
                    group:function(x9){
                        dim.group(x9);
                    },
                    groupAll:function(x10){
                        dim.groupAll(x10);
                    },
                    remove:function(){
                        dim.remove();
                    }
                };
            }

Hope this helps someone.