When using Crossfilter (https://github.com/square/crossfilter), I specify functions to use when adding and removing data from a group. It\'s fairly trivial to keep track of a ru
The best solution I came up with, was to keep track of all values in an ordered list and to add elements with a simple quicksort-style insertion function (cp. how to insert a number into a sorted array) and to remove them using indexOf.
Common functions:
function insertElement(element, array) {
array.splice(locationOfElement(element, array) + 1, 0, element);
return array;
}
function removeElement(element, array) {
var index = array.indexOf(element);
if (index >= 0) array.splice(index, 1);
return array;
}
function locationOfElement(element, array, start, end) {
start = start || 0;
end = end || array.length;
var pivot = parseInt(start + (end - start) / 2, 10);
if (array[pivot] === element) return pivot;
if (end - start <= 1)
return array[pivot] > element ? pivot - 1 : pivot;
if (array[pivot] < element) {
return locationOfElement(element, array, pivot, end);
} else {
return locationOfElement(element, array, start, pivot);
}
}
function maxElement(array) {
return (array.length > 0) ?
array[array.length - 1] : null;
}
function minElement(array) {
return (array.length > 0) ?
array[0] : null;
}
Functions to use when adding and removing data from a group to track min / max:
minMaxDimension = cf.dimension(function (d) {
return d.key;
});
var reduceAdd = function(p, v) {
insertElement(v.value, p.elements);
return p;
};
var reduceRemove = function(p, v) {
removeElement(v.value, p.elements);
return p;
};
var reduceInitial = function() {
return {
elements: [],
max: function() { return maxElement(elements); },
min: function() { return minElement(elements); }
}
}
minMaxGroup = minMaxDimension
.group()
.reduce(reduceAdd, reduceRemove, reduceInitial)
.orderNatural()
.top(Infinity);