@antv/s2
Version:
effective spreadsheet render core lib
101 lines • 3.25 kB
JavaScript
import Decimal from 'decimal.js';
import { Aggregation } from '../common/interface';
import { CellData } from '../data-set/cell-data';
export const isNotNumber = (value) => {
if (typeof value === 'number') {
return Number.isNaN(value);
}
if (!value) {
return true;
}
if (typeof value === 'string') {
return Number.isNaN(Number(value));
}
return true;
};
export const canConvertToNumber = (a) => !isNotNumber(a);
/**
* 预处理原始数据为 Decimal 对象数组
* 所有不能转为 number 的数据默认为 0
* @param data 原始数据数组
* @param field 值字段
* @param filterIllegalValue 是否过滤非法值?过滤后,包装后的数据数组短于原始数组长度
* @returns 经过 Decimal 包装后的值数组
*/
const processFieldValues = (data, field, filterIllegalValue = false) => {
if (!(data === null || data === void 0 ? void 0 : data.length)) {
return [];
}
return data.reduce((resultArr, item) => {
const fieldValue = CellData.getFieldValue(item, field);
const notNumber = isNotNumber(fieldValue);
if (filterIllegalValue && notNumber) {
// 过滤非法值
return resultArr;
}
const val = notNumber ? 0 : fieldValue;
resultArr.push(new Decimal(val));
return resultArr;
}, []);
};
/**
* 计算数据项的和
* @param data 数据项
* @param field 值字段
* @returns 算术和
*/
export const getDataSumByField = (data, field) => {
const fieldValues = processFieldValues(data, field);
if (!fieldValues.length) {
return 0;
}
return Decimal.sum(...fieldValues).toNumber();
};
/**
* 计算数据项的极值
* @param method 最大值(max)或最小值(min)
* @param data 数据项
* @param field 值字段
* @returns 最值
*/
export const getDataExtremumByField = (method, data, field) => {
// 防止预处理时默认值 0 影响极值结果,处理时需过滤非法值
const fieldValues = processFieldValues(data, field, true);
if (!(fieldValues === null || fieldValues === void 0 ? void 0 : fieldValues.length)) {
return;
}
return Decimal[method](...fieldValues).toNumber();
};
/**
* 计算数据项的平均值
* @param data 数据项
* @param field 值字段
* @returns 算术平均值
*/
export const getDataAvgByField = (data, field) => {
const fieldValues = processFieldValues(data, field);
if (!(fieldValues === null || fieldValues === void 0 ? void 0 : fieldValues.length)) {
return 0;
}
return Decimal.sum(...fieldValues)
.dividedBy(fieldValues.length)
.toNumber();
};
/**
*
* @param data
*/
export const getDataCountByField = (data) => {
return (data === null || data === void 0 ? void 0 : data.length) || 0;
};
/**
* totals 计算方法集合
*/
export const calcActionByType = {
[Aggregation.SUM]: getDataSumByField,
[Aggregation.MIN]: (data, field) => getDataExtremumByField('min', data, field),
[Aggregation.MAX]: (data, field) => getDataExtremumByField('max', data, field),
[Aggregation.AVG]: getDataAvgByField,
[Aggregation.COUNT]: getDataCountByField,
};
//# sourceMappingURL=number-calculate.js.map