@adaptabletools/adaptable-cjs
Version:
Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
81 lines (80 loc) • 3.56 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.weightedAverage = exports.getNumericValue = void 0;
const tslib_1 = require("tslib");
const toNumber_1 = tslib_1.__importDefault(require("./utils/toNumber"));
const getNumericValue = (input) => {
if (typeof input === 'number') {
return input;
}
const numericValue = (0, toNumber_1.default)(input);
return isNaN(numericValue) ? null : numericValue;
};
exports.getNumericValue = getNumericValue;
/**
* Computes a weighted average aggregation: Σ(value × weight) / Σ(weight)
*
* AG Grid calls agg functions bottom-up through the group hierarchy. For each group:
* - Leaf children contribute their raw value × weight
* - Sub-group children already have partial sums from a previous pass,
* so we combine those directly instead of re-traversing to leaves
*
* The returned object stores partial sums ([columnId] and [weightColumnId])
* so parent groups can combine sub-group results correctly.
*/
const weightedAverage = (params, columnId, weightColumnId) => {
const { api: gridApi, rowNode: groupRowNode, values } = params;
// numerator: Σ(value × weight)
let weightedValueSum = 0;
// denominator: Σ(weight)
let totalWeight = 0;
// params.values already respects suppressAggFilteredOnly.
// We need the matching child nodes only for leaf rows (to look up weight column values).
const childNodes = getMatchingChildNodes(groupRowNode, values.length);
for (let i = 0; i < values.length; i++) {
const value = values[i];
if (value != null && typeof value === 'object') {
// sub-group: partial sums already computed by a previous aggregation pass
weightedValueSum += value[columnId] ?? 0;
totalWeight += value[weightColumnId] ?? 0;
}
else {
// leaf row: compute value × weight from cell data
const childNode = childNodes[i];
if (!childNode) {
continue;
}
// values might be strings during editing
const columnValue = (0, exports.getNumericValue)(value);
const weightValue = (0, exports.getNumericValue)(gridApi.getCellValue({ colKey: weightColumnId, rowNode: childNode }));
if (weightValue !== null) {
totalWeight += weightValue;
}
if (columnValue !== null && weightValue !== null) {
weightedValueSum += columnValue * weightValue;
}
}
}
const result = totalWeight !== 0 ? weightedValueSum / totalWeight : 0;
return {
// toString/toNumber let AG Grid's default cell renderer display and sort the value
toString: () => String(result),
toNumber: () => result,
// partial sums stored so parent groups can combine sub-group results
[columnId]: weightedValueSum,
[weightColumnId]: totalWeight,
};
};
exports.weightedAverage = weightedAverage;
/**
* Returns the child node list that corresponds to params.values.
* When suppressAggFilteredOnly is false, params.values comes from childrenAfterFilter.
* When true, it comes from childrenAfterGroup (all children).
* We match by length to pick the right list without checking the grid option directly.
*/
function getMatchingChildNodes(groupRowNode, valueCount) {
if (groupRowNode.childrenAfterFilter?.length === valueCount) {
return groupRowNode.childrenAfterFilter;
}
return groupRowNode.childrenAfterGroup ?? [];
}