vis-utils
Version:
Utility functions for data visualization
70 lines (58 loc) • 2.59 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = extentLimited;
var _d3Array = require('d3-array');
/**
* Compute the extent (min and max) of an array, limiting the min and the max
* by the specified percentiles. Percentiles are values between 0 and 1.
*
* @param {Array} array The array to iterate over
* @param {Function} [valueAccessor] How to read a value in the array (defaults to identity)
* @param {Number} [minPercentile] If provided, limits the min to this percentile value (between 0 and 1).
* If provided, the data is sorted by taking the difference of the valueAccessor results.
* @param {Number} [maxPercentile] If provided, limits the max to this percentile value (between 0 and 1).
* If provided, the data is sorted by taking the difference of the valueAccessor results.
* @return {Array} the extent, limited by the min/max percentiles
*/
function extentLimited(array) {
var valueAccessor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function (d) {
return d;
};
var minPercentile = arguments[2];
var maxPercentile = arguments[3];
if (!array || !array.length) {
return undefined;
}
// neither limits defined, just use d3 extent.
if (minPercentile == null && maxPercentile == null) {
return (0, _d3Array.extent)(array, valueAccessor);
}
array.sort(function (a, b) {
return valueAccessor(a) - valueAccessor(b);
});
var minValue = array[0];
var maxValue = array[array.length - 1];
var bisectValue = (0, _d3Array.bisector)(valueAccessor).left;
// limit to minPercentile if passed in
if (minPercentile != null) {
// get the value at the percentile
var minQuantileValue = (0, _d3Array.quantile)(array, minPercentile, valueAccessor);
var quantileInsertIndex = Math.max(0, bisectValue(array, minQuantileValue));
// this may not exist in the array, so find the nearest point to it
// and use that.
minValue = valueAccessor(array[quantileInsertIndex]);
}
// limit to maxPercentile if passed in
if (maxPercentile != null) {
var maxQuantileValue = (0, _d3Array.quantile)(array, maxPercentile, valueAccessor);
var _quantileInsertIndex = Math.min(array.length - 1, bisectValue(array, maxQuantileValue));
maxValue = valueAccessor(array[_quantileInsertIndex]);
// ensure we do not get a value bigger than the quantile value
if (maxValue > maxQuantileValue && _quantileInsertIndex > 0) {
maxValue = valueAccessor(array[_quantileInsertIndex - 1]);
}
}
return [minValue, maxValue];
}