Search code examples
crossfilter

Crossfilter for Date for string values


I've a JSON model that contains strings instead of dates (the model is generated via T4TS, so I cannot change that).

The code is currently using an expanded model extending the original json, where the dates are recalculated on new fields.

I was wondering if it would be possible to apply the filters on the fields being string without adding that additional step of extending the model.

private makeNumeric(label: string, property: string) {
        return {
            label: label,
            key: property,
            prepareDimension: (crossfilter) => (CrossfilterUtils.makeNumeric(crossfilter, property)),
            prepareGroup: (dimension) => {

                if (!this.values[property]) {
                    var group = CrossfilterUtils.makeNumericGroup(dimension);

                    this.values[property] = group;
                }
                return this.values[property];
            },
            valuesAreOrdinal: false
        };
    }

I haven't used the crossfilter library much before and by looking at the documentation I can't seem to reconcile it with the code (heritage code, to put it that way).

The incoming date format looks like this: "2020-10-22T07:26:00Z"

The typescript model I'm working with is like this:

interface MyModel {
    ...
    CreatedDate?: string;
}

Any idea?


Solution

  • The usual pattern in JavaScript is to loop through the data and do any conversions you need:

    data.forEach(function(d) {
        d.date = new Date(d.date);
        d.number = +d.number;
    });
    
    const cf = crossfilter(data);
    

    However, if this is not allowed due to TS, you can also make the conversions when creating your dimensions and groups:

    const cf = crossfilter(data);
    const dateDim = cf.dimension(d => new Date(d.date));
    const monthGroup = dateDim.group(date => d3.timeMonth(date))
       .reduceSum(d => +d.number);
    

    I find this a little less robust because you have to remember to do this everywhere. It's a little harder to reason about the efficiency since you have to trust that crossfilter uses the accessors sparingly, but I don't recall seeing this be a problem in practice.