Search code examples
javascriptd3.jscrossfilterc3.js

Crossfilter producing negative values with positive dataset when sorting data


I am using crossfilter wrong but cannot spot where.

I have a dataset which I am filtering. When I supply a sorting function to sort the data by day of the week, the result displays negative values.

If I skip the sorting, everything works as it should.

The data looks something like this

  dataEg=[{"attr1": "A", "date":" Thu Apr 12 2018 00:00:00 GMT+0100 (BST)", "attr2": "a", "attr3": 25.11, "dayOfWeek": "Thu"},
  {"attr1": "B", "date":" Sun Apr 01 2018 00:00:00 GMT+0100 (BST)", "attr2": "b", "attr3": 6.67, "dayOfWeek": "Sun"}];

I use crossfilter to select by attribute

var crossFilter = (function () {
        var filter = {};
        filter.ndx = crossfilter(dataEg);

        filter.attr2Dim = filter.ndx.dimension(function (d) { return d.attr2; });
        filter.dayOfWeekDim = filter.ndx.dimension(function (d) { return d.dayOfWeek; });
        filter.attr1Dim = filter.ndx.dimension(function (d) { return d.attr1; });

        filter.costPerDayOfWeek = filter.dayOfWeekDim.group().reduceSum(function (d) { return d.attr3; });
        filter.costPerattr2 = filter.attr2Dim.group().reduceSum(function (d) { return d.attr3 });
        filter.costPerattr1 = filter.attr1Dim.group().reduceSum(function (d) { return d.attr3 });

        return filter;
    })();

When filtering for some atteribute

crossFilter.attr1Dim.filter(function (d) {
                        return d === "B";
                    });

everything works unless I sort the date by day first using this filter

function DaySorter (keyLocator) {
        if (keyLocator === undefined) {
            keyLocator = function (item) {
                return item;
            };
        }

        return function (a, b) {
            var order = {
                "Mon": 0, "Tue": 1, "Wed": 2, "Thu": 3, "Fri": 4, "Sat": 5, "Sun": 6
            };

            var aVal = order[keyLocator(a)];
            var bVal = order[keyLocator(b)];

            var comp = 0;
            if (aVal > bVal) {
                comp = 1;
            }
            else if (aVal < bVal) {
                comp = -1;
            }
            return comp;
        };
    }

However, I do not see where I am making a mistake. The filter seems to work correctly and follows the documentation.

A minimal JSFiddle can be found here.


Solution

  • Finally found the problem.

    I was sorting the data in the chart so that it is displayed in the order of the Day of Week. However, this somehow interfered with the interals of CrossFilter.

    Doing a deep copy of the data before sorting it in the chart solved the problem (here using JQuery).

               data =[];
               $.extend(true, data, dataOrg);