Reductio is a library for generating Crossfilter reduce functions and applying them to Crossfilter groups. Crossfilter supports basic count and sum aggregations, but even aggregations as conceptually simple as a group minimum or maximum can be difficult to build correctly and efficiently on a Crossfilter group. Reductio provides helper functions that generate these aggregations in an efficient and composable way, making it easy to use more complex aggregations with Crossfilter and to have more than one aggregation per group without having to worry about designing 2-way reduce functions.
Basic use:
var data = crossfilter([
{ foo: 'one', bar: 1 },
{ foo: 'two', bar: 2 },
{ foo: 'three', bar: 3 },
{ foo: 'one', bar: 4 },
{ foo: 'one', bar: 5 },
{ foo: 'two', bar: 6 },
]);
var dim = data.dimension(function(d) { return d.foo; });
var group = dim.group();
// Equivalent to reductio().avg(function(d) { return d.bar; }), which sets the .sum() and .count() values.
var reducer = reductio()
.count(true)
.sum(function(d) { return d.bar; })
.avg(true);
// Now it should track count, sum, and avg.
reducer(group);
group.top(Infinity);
// [ { key: 'one', value: { count: 3, sum: 10, avg: 3.3333333 },
// { key: 'two', value: { count: 2, sum: 8, avg: 4 },
// { key: 'three', value: { count: 1, sum: 3, avg: 3 } ]
npm install --save-dev reductio
bower install --save-dev reductio
Download from the releases page. Serve the reductio.js or reductio.min.js file in the top-level directory as part of your application.
Reductio is available via cdnjs. You can generate links to different versions of Reductio at: https://cdnjs.com/libraries/reductio
If something doesn't appear to be working or you're having trouble with implementing something, it will usually be best to ask a question on Stackoverflow and tag the question with the reductio tag. When you ask your question, it is best to put together a working example showing the problem you are having. A JSFiddle template is available that already includes the Reductio and Crossfilter libraries, as well as dc.js. Use that template to make an example showing what you are seeing. In your question, reference the example, explain what you are seeing, and explain what you expect or want to see instead.
There is also a Reductio Gitter, which is a good place to check in for help if you have a quick question that doesn't fit into the Stackoverflow format, or if you are looking for a more conceptual discussion.
In most cases when an accessor function is required, Reductio supports the use of the property name to be accessed in the form or a string instead. When appropriate, Reductio will even cast the value of a property to a number for you, though be aware that this will convert nulls and undefined values into 0s.
For example, the following:
reducer = reductio().sum(function(d) { return +d.number; });
reducer(group);
Is equivalent to:
reducer = reductio().sum('number');
reducer(group);
Aggregations that support this syntax with casting to a numeric value: sum, avg, exception sum, histogram value, min, max, median
Aggregations that support this syntax without casting: nest, exception, value list, standard deviation, sum of squares
Aggregations are composable (so you can track more than one aggregation on a given group) and may depend on each other (the 'avg' aggregation requires that 'count' and 'sum' be specified).
Current aggregations supported are shown given the following setup.
var data = crossfilter([...]);
var dim = data.dimension(...);
var group = dim.group();
var reducer;
Works the same way as Crossfilter's standard group.reduceCount().
reducer = reductio().count(true);
reducer(group);
Stored under the 'count' property of groups. The value will be a count of every record that matches the group accessor.
Works the same was as Crossfilter's standard group.reduceSum().
reducer = reductio().sum(function(d) { return +d.number; });
reducer(group);
Stored under the 'sum' property of groups. The value is a sum of accessor(d) for every record d that matches the group accessor. The accessor function must return a number.
reductio().avg(function(d) { return +d.number; })(group);
Stored under the 'avg' property of groups. Boolean variation depends on count and sum aggregations being specified. If an accessor function is provided, that function will be used to create a sum aggregation on the group, and a count aggregation will be created as well. The value on the 'avg' property is equal to sum/count for the group.
reductio().min(function(d) { return +d.number; })
.max(true)
.median(true)(group);
Stored under the 'median', 'min', and 'max' property of groups.
Once you've defined one accessor function for min, max, or median (or if you have explicitly defined a redectio.valueList(value)) it will be used by the others. This avoids warning messages about overwriting the valueList.
reductio().sumOfSq(function(d) { return d.number; })(group);
Stored under the 'sumOfSq' property of the group. Defined as the square of the value returned by the accessor function summed over all records in the group. This is used in the standard deviation aggregation, but can be used on its own as well.
reductio().sumOfSq(function(d) { return d.number; })
.sum(function(d) { return d.number; })
.count(true)
.std(true)(group);
reductio()
.std(function(d) { return d.number; })(group);
Stored under the 'std' property of the group. Defined as the sum-of-squares minus the average of the square of sums for all records in the group. In other words, for group 'g', g.sumOfSq - g.sum*g.sum/g.count.
If sumOfSq, sum, and count are already defined, takes a boolean. Otherwise pass in an accessor function directly.
reductio().histogramBins([0,2,6,10])
.histogramValue(function(d) { return +d.number; })(group)
Histogram of values within grouping, stored on the 'histogram' property of the group. Acts like d3.layout.histogram defined using bins(thresholds).
This grouping should be usable anywhere d3.layout.histogram can be used. May be useful for small-multiples charts, or for use with the dc.js stack mixin.
The property group.histogram is an array. Each element of the array is a sorted array of values returned by histogramValue that fall into that bin. Each element of the array also has properties, x, dx, and y, as defined in the d3.layout.histogram documentation.
Defines the bin thresholds for the histogram. Will result in thresholdArray.length - 1 bins.
Accessor for the value to be binned.
var reducer = reductio();
reducer.value("x").sum(xSumAccessor);
reducer.value("y").count(true).sum(ySumAccessor).avg(true);
reducer(group);
Allows group structures such as
{
x: { sum: 5 }
y: { count: 3, sum: 12, avg: 4 }
}
Used for tracking mul
$ claude mcp add reductio \
-- python -m otcore.mcp_server <graph>