UNPKG

@antv/data-wizard

Version:
351 lines (349 loc) 10.8 kB
import { __assign, __read, __spreadArray } from "tslib"; import { assert, isArray, flatten } from '../utils'; import * as cache from './caches'; /** * Return the minimum of the array. * @param array - The array to process */ export function min(array) { var value = cache.get(array, 'min'); if (value !== undefined) { return value; } return cache.set(array, 'min', Math.min.apply(Math, __spreadArray([], __read(array)))); } function minIdx(array) { var min = array[0]; var idx = 0; for (var i = 0; i < array.length; i += 1) { if (array[i] < min) { idx = i; min = array[i]; } } return idx; } /** * Return the minimum index of the array. * @param array - The array to process */ export function minIndex(array) { var value = cache.get(array, 'minIndex'); if (value !== undefined) return value; return cache.set(array, 'minIndex', minIdx(array)); } /** * Return the maximum of the array. * @param array - The array to process */ export function max(array) { var value = cache.get(array, 'max'); if (value !== undefined) return value; return cache.set(array, 'max', Math.max.apply(Math, __spreadArray([], __read(array)))); } function maxIdx(array) { var max = array[0]; var idx = 0; for (var i = 0; i < array.length; i += 1) { if (array[i] > max) { idx = i; max = array[i]; } } return idx; } /** * Return the maximum index of the array. * @param array - The array to process */ export function maxIndex(array) { var value = cache.get(array, 'maxIndex'); if (value !== undefined) return value; return cache.set(array, 'maxIndex', maxIdx(array)); } /** * Return the sum of the array. * @param array - The array to process */ export function sum(array) { var value = cache.get(array, 'sum'); if (value !== undefined) return value; return cache.set(array, 'sum', array.reduce(function (prev, current) { return current + prev; }, 0)); } /** * Return the mean of the array. * @param array - The array to process */ export function mean(array) { return sum(array) / array.length; } /** * Return the geometricMean of the array. * @param array - The array to process */ export function geometricMean(array) { assert(array.some(function (item) { return item > 0; }), 'each item in array must greater than 0'); var value = cache.get(array, 'geometricMean'); if (value !== undefined) return value; return cache.set(array, 'geometricMean', Math.pow(array.reduce(function (prev, curr) { return prev * curr; }, 1), (1 / array.length))); } /** * Return the harmonicMean of the array. * @param array - The array to process */ export function harmonicMean(array) { var base = Math.pow(2, 16); var value = cache.get(array, 'harmonicMean'); if (value !== undefined) return value; return cache.set(array, 'harmonicMean', (base * array.length) / array.reduce(function (prev, curr) { return base / curr + prev; }, 0)); } function sort(array) { return array.sort(function (l, r) { return (l > r ? 1 : -1); }); } /** * Return the median of the array. * @param array - The array to process */ export function median(array, sorted) { if (sorted === void 0) { sorted = false; } var length = array.length; var newArray = sorted ? array : sort(array); if (length % 2 === 1) return newArray[(length - 1) / 2]; return (newArray[length / 2 - 1] + newArray[length / 2]) / 2; } /** * Return the quartile of the array. * @param array - The array to process * @param sorted - Whether it is sorted */ export function quartile(array, sorted) { if (sorted === void 0) { sorted = false; } assert(array.length >= 3, 'array.length cannot be less than 3'); var length = array.length; var newArray = sorted ? array : sort(array); var Q2 = median(newArray, true); var Q1; var Q3; if (length % 2 === 1) { Q1 = median(newArray.slice(0, (length - 1) / 2), true); Q3 = median(newArray.slice((length + 1) / 2), true); } else { Q1 = median(newArray.slice(0, length / 2), true); Q3 = median(newArray.slice(length / 2), true); } return [Q1, Q2, Q3]; } /** * Return the quantile of the array. * @param array - The array to process * @param percent - percent * @param sorted - Whether it is sorted */ export function quantile(array, percent, sorted) { if (sorted === void 0) { sorted = false; } assert(percent > 0 && percent < 100, 'percent cannot be between (0, 100)'); var newArray = sorted ? array : sort(array); var index = Math.ceil((array.length * percent) / 100) - 1; return newArray[index]; } /** * Return the variance of the array. * @param array - The array to process */ export function variance(array) { var m = mean(array); var value = cache.get(array, 'variance'); if (value !== undefined) return value; return cache.set(array, 'variance', array.reduce(function (prev, curr) { return prev + Math.pow((curr - m), 2); }, 0) / array.length); } /** * Return the standard deviation of the array. * @param array - The array to process */ export function standardDeviation(array) { return Math.sqrt(variance(array)); } /** * Return the coefficient of variance of the array. * @param array - The array to process */ export function coefficientOfVariance(array) { var stdev = standardDeviation(array); var arrayMean = mean(array); return stdev / arrayMean; } /** * Return the covariance of the array. * @param array - The array to process */ export function covariance(x, y) { assert(x.length === y.length, 'x and y must has same length'); var exy = mean(x.map(function (item, i) { return item * y[i]; })); return exy - mean(x) * mean(y); } /** * Return the Pearson CorrelationCoefficient of two array. */ export function pearson(x, y) { var cov = covariance(x, y); var dx = standardDeviation(x); var dy = standardDeviation(y); return cov / (dx * dy); } /** * Return the counts of valid value in the array. * @param array - The array to process */ export function valid(array) { var count = 0; for (var i = 0; i < array.length; i += 1) { if (array[i]) count += 1; } return count; } /** * Return the counts of missing value in the array. * @param array - The array to process */ export function missing(array) { return array.length - valid(array); } /** * Return the counts of each distinct value in the array. * @param array - The array to process */ export function valueMap(array) { var data = {}; array.forEach(function (value) { if (data[value]) data[value] += 1; else data[value] = 1; }); return data; } /** * Return the counts of distinct value in the array. * @param array - The array to process */ export function distinct(array) { return Object.keys(valueMap(array)).length; } /** * Return the sum of the array by specific measure. * @param array - The array to process * @param measure - The selected measure */ export function sumBy(array, measure) { return array.map(function (val) { return val[measure]; }).reduce(function (acc, val) { return acc + val; }, 0); } /** * Return the count of the array by specific measure. * @param array - The array to process * @param measure - The selected measure */ export function countBy(array, measure) { return array.filter(function (item) { return measure in item; }).length; } /** * Return the maximum of the array by specific measure. * @param array - The array to process * @param measure - The selected measure */ export function maxBy(array, measure) { return Math.max.apply(Math, __spreadArray([], __read(array.map(function (val) { return val[measure]; })))); } /** * Return the minimum of the array by specific measure. * @param array - The array to process * @param measure - The selected measure */ export function minBy(array, measure) { return Math.min.apply(Math, __spreadArray([], __read(array.map(function (val) { return val[measure]; })))); } /** * Return the mean of the array by specific measure. * @param array - The array to process * @param measure - The selected measure */ export function meanBy(array, measure) { return array.map(function (val) { return val[measure]; }).reduce(function (acc, val) { return acc + val; }, 0) / array.length; } /** * Return the groups of the array. * @param array - The array to process * @param measure - The selected measure */ export function groupBy(array, measure) { var iter = function (_a) { var _b = measure, prop = _a[_b]; return prop; }; var dataArray = isArray(array) ? array : Object.values(array); return dataArray.reduce(function (result, item) { var _a; var id = iter(item); if (!result[id]) { Object.assign(result, (_a = {}, _a[id] = [], _a)); } result[id].push(item); return result; }, {}); } export var AggregatorMap = { SUM: sumBy, COUNT: countBy, MAX: maxBy, MIN: minBy, MEAN: meanBy, }; /** * Aggregate data via different aggregation methods * @param array - The array to process * @param dimensionField - The selected dimensions * @param measure - The selected measure * @param aggMethod - The selected aggregation method * @param seriesField - The selected series * @returns */ export function aggregate(array, dimensionField, measure, aggMethod, seriesField) { if (aggMethod === void 0) { aggMethod = 'SUM'; } var grouped = groupBy(array, dimensionField); var aggregator = AggregatorMap[aggMethod]; if (!seriesField) { return Object.entries(grouped).map(function (_a) { var _b; var _c = __read(_a, 2), value = _c[0], dataGroup = _c[1]; return _b = {}, _b[dimensionField] = value, _b[measure] = aggregator(dataGroup, measure), _b; }); } return flatten(Object.entries(grouped).map(function (_a) { var _b = __read(_a, 2), value = _b[0], dataGroup = _b[1]; var childGrouped = groupBy(dataGroup, seriesField); var part = Object.entries(childGrouped).map(function (_a) { var _b; var _c = __read(_a, 2), childValue = _c[0], childDataGroup = _c[1]; return _b = {}, _b[seriesField] = childValue, _b[measure] = sumBy(childDataGroup, measure), _b; }); return part.map(function (item) { var _a; return __assign(__assign({}, item), (_a = {}, _a[dimensionField] = value, _a)); }); })); }