Crossfilter dimension and group to filter out data below certain threshold

寵の児 提交于 2019-12-10 10:55:11

问题


I have the following data, and I am trying to plot 2 bar charts:

  • Total units of a given type
  • Units of a type less than version 2.0

Where x-axis in both the charts is the type of unit.

The charts are fine. The problem is:

When I select the bar on the 2nd chart I expect to see only units with version < 2.0 in the data table and the 1st chart i.e. one record in this case. But what I get is all the units of that particular type (which is what I expect if I click on a bar in first chart) i.e. 3 records.

See http://jsfiddle.net/y1o52tk4/6/

The problem I guess is with how I group for version chart:

var versionGroup = type1Dim.group().reduceSum(dc.pluck('version_count'));

Data:

var data = [{
         "version": 1.0,
         "serial": '1A',
         "type": "a"
},{
         "version": 2.0,
         "serial": '2A',
         "type": "a"
},{
         "version": 2.0,
         "serial": '2AA',
         "type": "a"
},{
         "version": 2.0,
         "serial": '2B',
         "type": "b"
},{
         "version": 2.5,
         "serial": '25B',
         "type": "b"
},{
         "version": 1.0,
         "serial": '1B',
         "type": "b"
}];

回答1:


As described in the comments above, but let's spell it out and clarify a couple of things.

You can use composite keys and then filter the group using a "fake group", as you did in your updated fiddle above, in order to get this effect. And this is probably the most general and most stable way to do this, without having to do any UI hacks.

The thing to understand about crossfilter keys, however, is that it is always going to coerce them to values. So if you want a composite key, it's best to just construct it as a string yourself, because if you pass it as a an array, crossfilter will coerce it to a string and give you a join with , - which can be made to work, and I am aware that the dc.js scatterplot does this, but I don't recommend it. It's less efficient than creating the strings yourself (because you will only do it once rather than having it happen inside crossfilter internals), and because you have a lot more control.

Here is a long discussion with Jason Davies which convinced me: https://github.com/square/crossfilter/pull/48

So here's a string concatenation composite key version of your fiddle.

First the composite key:

    var type1Dim = ndx.dimension(function(d){
                            if(d.version<2.0)
                                return '1.' + d.type;
                            else
                                return '2.' + d.type;});

(The most foolproof separator would be '\x0' but '.' works fine here.)

Next, a plain key accessor:

    .keyAccessor(function(d) {return d.key;})

And we let dc.js infer the domain of the ordinal scale too:

    .x(d3.scale.ordinal());

And it works, but now the ticks have the ugly composite key. To fix that:

    versionChart.xAxis().tickFormat(function(d) {
        return d.split('.')[1];
    });

My fork: http://jsfiddle.net/gordonwoodhull/y09cok1z/4/

EDIT: I forgot to update the fake group generator, which happens not to matter here, but for generality, it should split the key as well:

function removeVersion2(source_group) {
    return {
        all:function () {
            return source_group.all().filter(function(d) {
                return d.key.split('.')[0] != 2;
            });
        }
    };
}



回答2:


The problem here is that you created a custom count of versions less than 2 and plotted that in your bar chart. Crossfilter has no idea what that refers to in the reverse direction. Thus when you click on the second chart in area 'b' crossfilter applies .filter("b") to that dimension and then the crossfilter object. Thus your output is correct. To do what you want to do I would recommend adding a new dimension

var versionDim = ndx.dimension(function(d) {return d.version});

and then add an onfiltered listener to your second chart This listener checks to see if you tried to filter your second chart and if so applies a filter on the new dimension i created above.

.on("filtered", function(chart){
    if(typeDim.top(ndx.size()).length) < ndx.size())
    {
        versionDim.filter(1);
    }else{
        versionDim.filterAll();
    }
})


来源:https://stackoverflow.com/questions/29107224/crossfilter-dimension-and-group-to-filter-out-data-below-certain-threshold

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