crossfilter / reductio

Reductio: Crossfilter grouping
Other
250 stars 42 forks source link

Top alias array errors when defining an alias (ex: 'group.top(1)[0].complete' is undefined) #40

Closed JasonBrannon closed 8 years ago

JasonBrannon commented 8 years ago

Occurs when defining a reductio.alias(mapping) or reductio.aliasProp(mapping), Attempting to return the k records according to the natural order of the dimension by specifying the alias per the API reference.

On the group, we can then call the following function to retrieve the new count value.

group.top(1)[0].newCount();

`//Sample Data var data = [ {"type":"exe","total":24,"handled":0,"nothandled":24}, {"type":"exe","total":1,"handled":0,"nothandled":1}, {"type":"exe","total":1,"handled":0,"nothandled":1}, {"type":"exe","total":1,"handled":0,"nothandled":1}, {"type":"exe","total":1,"handled":0,"nothandled":1} ]

// Set crossfilter var ndx = crossfilter(dirData);

// Dimension var dim = ndx.dimension(function(d) {return "" + d.type;});

// Group
var group = dim.group();

// reductio.alias(mapping) var reducer = reductio().count(true) .sum(function(d) { return +d.handled; })
.aliasProp({ newCount: function(g) { return g.count; }, complete: function(g) { return g.sum * 100 / g.count; } });
reducer(group); //<-- WORKS

// Optimal Result: //object Object = [ // {"key":"dir","value":{"count":5,"sum":28,"newCount":28,"complete":0}} //]

//On the group, attempt to call the following to retrieve the complete value. group.top(1)[0].complete(); //<-- ERROR //group.top(1)[0]; //<-- works

// Suboptimal Result: //TypeError: group.top(1)[0].complete is not a function. (In 'group.top(1)[0].complete()', 'group.top(1)[0].complete' is undefined)`

esjewett commented 8 years ago

Thanks for the report. What version of Reductio are you using? And can you let me know what console.log(group.top(1)[0]) looks like?

esjewett commented 8 years ago

Looks to me like it is working with the latest Reductio. Here is a jsFiddle example: https://jsfiddle.net/esjewett/3p8Lq1ma/1/

Some sample code that appears to me to work:

var ndx = crossfilter([
{"type":"exe","total":24,"handled":0,"nothandled":24},
{"type":"exe","total":1,"handled":0,"nothandled":1},
{"type":"exe","total":1,"handled":0,"nothandled":1},
{"type":"exe","total":1,"handled":0,"nothandled":1},
{"type":"exe","total":1,"handled":0,"nothandled":1}
]);
var dim = ndx.dimension(function(d) {return "" + d.type;})
var group = dim.group();
var reducer = reductio().count(true)
    .sum(function(d) { return +d.handled; })
    .aliasProp({
        newCount: function(g) { return g.count; },
        complete: function(g) { return g.sum * 100 / g.count; }
    });
reducer(group);
console.log(group.top(1)[0]);
console.log(group.top(1)[0].value.complete);

var reducer2 = reductio().count(true)
    .sum(function(d) { return +d.handled; })
    .alias({
        newCount: function(g) { return g.count; },
        complete: function(g) { return g.sum * 100 / g.count; }
    });
reducer2(group);
console.log(group.top(1)[0]);
console.log(group.top(1)[0].value.complete());
JasonBrannon commented 8 years ago

Here's my lib versions: crossfilter - 1.3.12 reductio - 0.6.0

It appears my implementation, when logging complete(), was not quite correct. Your example works in my environment, but I couldn't help but notice you were missing parenthesis in your 1st .value.complete console.log statement:

//Working Version console.log(group.top(1)[0].value.complete); console.log(group.top(1)[0].value.complete());

So I attempted to manipulate the order of when the parenthesis were used, and found these results:

console.log(group.top(1)[0].value.complete()); console.log(group.top(1)[0].value.complete);

console.log(group.top(1)[0].value.complete()); console.log(group.top(1)[0].value.complete());

Both returned: TypeError: group.top(1)[0].value.complete is not a function. (In 'group.top(1)[0].value.complete()', 'group.top(1)[0].value.complete' is 600)

This was interesting to see, but not necessarily the issue reported. I found that my implementation of complete was malformed, this change resolved my issue:

console.log(group.top(1)[0].complete()); //Fails

console.log(group.top(1)[0].value.complete()); //Works

esjewett commented 8 years ago

The first example uses aliasProp, which pre-calculates values, while the second example uses alias, which embeds functions in the group used to calculate values when called. I recommend against using aliasProp, but it is correct that when using it, complete will be a value not a function.

aliasProp documentation here: https://github.com/crossfilter/reductio#reductioaliaspropmapping