UNPKG

@adaptabletools/adaptable

Version:

Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements

116 lines (115 loc) 5.87 kB
import { aggregate } from '../ExpressionFunctions/scalarAggregationHelper'; const doOnceFlags = {}; const logOnce = (message, loggingFn) => { if (doOnceFlags[message]) { return; } loggingFn(message); doOnceFlags[message] = true; }; export class AggregatedScalarLiveValue { constructor(source, requestingModule, adaptableApi, getRowNodes) { this.source = source; this.requestingModule = requestingModule; this.adaptableApi = adaptableApi; this.getRowNodes = getRowNodes; if (source.aggregatedScalarExpression) { this.aggregatedScalarExpression = source.aggregatedScalarExpression; } this.expressionEvaluation = source.aggregatedScalarExpression ? this.adaptableApi.internalApi .getQueryLanguageService() .evaluateAggregatedScalarExpression(source.aggregatedScalarExpression, requestingModule, getRowNodes).value : source.aggregatedScalarExpressionEvaluation; // currently we support only one reducer this.aggregationReducerName = Object.keys(this.expressionEvaluation.aggregationParams.reducers)[0]; this.aggregationResult = this.computeAggregatedValue(this.expressionEvaluation); } refresh() { if (this.aggregatedScalarExpression) { this.expressionEvaluation = this.adaptableApi.internalApi .getQueryLanguageService() .evaluateAggregatedScalarExpression(this.aggregatedScalarExpression, this.requestingModule, this.getRowNodes).value; } // currently we support only one reducer this.aggregationReducerName = Object.keys(this.expressionEvaluation.aggregationParams.reducers)[0]; this.aggregationResult = this.computeAggregatedValue(this.expressionEvaluation); } getAggregatedValueForRow(rowNode) { const aggregationValue = this.getAggregationValue(rowNode); if (aggregationValue == undefined) { logOnce(`${this.aggregatedScalarExpression} :: aggregation value is NOT available!`, (message) => { this.adaptableApi.logWarn(message); }); return; } if (this.expressionEvaluation.rowValueGetter) { return this.expressionEvaluation.rowValueGetter(rowNode, aggregationValue); } return aggregationValue; } getAllAggregationValues() { if (this.expressionEvaluation.aggregationParams.groupBy?.length) { const aggregations = this.aggregationResult.deepMap.topDownValues(); return aggregations.map((aggregation) => aggregation.reducerResults[this.aggregationReducerName]); } return [this.getGlobalAggregatedValue()]; } getAggregationValue(rowNode) { if (this.expressionEvaluation.aggregationParams.groupBy?.length) { const groupColumns = this.expressionEvaluation.aggregationParams.groupBy.map((groupByParam) => groupByParam.field); const groupKeys = groupColumns.map((groupColumnName) => this.getRowNodeValueForColumnId(rowNode, groupColumnName)); return this.aggregationResult.deepMap.get(groupKeys)?.reducerResults[this.aggregationReducerName]; } return this.getGlobalAggregatedValue(); } getGlobalAggregatedValue() { return this.aggregationResult.reducerResults[this.aggregationReducerName]; } getRowNodeValueForColumnId(rowNode, columnId) { const rawValue = this.adaptableApi.gridApi.getRawValueFromRowNode(rowNode, columnId); // we need to convert the Date object to a number, otherwise the grouping will not work (each Date instance is unique) return rawValue instanceof Date ? rawValue.getTime() : rawValue; } computeAggregatedValue(expressionEvaluation) { const gridRowNodes = expressionEvaluation.getRowNodes ? expressionEvaluation.getRowNodes() : this.adaptableApi.gridApi.getAllRowNodes({ filterFn: expressionEvaluation.rowFilterFn, }); // we iterate over the RowNode list (we need this to handle complex column values (nested values, valueGetters etc) // so we will map the fieldNames to RowNode.data const mapReducerValueGetter = (columnId) => { return (rowNode) => this.getRowNodeValueForColumnId(rowNode, columnId); }; Object.values(expressionEvaluation.aggregationParams.reducers).forEach((aggregationReducer) => { aggregationReducer.getter = mapReducerValueGetter(aggregationReducer.field); // nullify the field to force the fallback on the getter fn aggregationReducer.field = null; }); const mapGroupByToKey = (columnId) => { return (_unusableProperty, rowNode) => this.getRowNodeValueForColumnId(rowNode, columnId); }; expressionEvaluation.aggregationParams.groupBy?.forEach((groupByDef) => { groupByDef.toKey = mapGroupByToKey(groupByDef.field); }); let aggregatedRowNodes = gridRowNodes; if (expressionEvaluation.sortByColumn) { const sortByColumn = expressionEvaluation.sortByColumn; // currently, we support only ascending sorting aggregatedRowNodes.sort((first, second) => { const firstValue = this.getRowNodeValueForColumnId(first, sortByColumn); const secondValue = this.getRowNodeValueForColumnId(second, sortByColumn); if (firstValue < secondValue) { return -1; } if (firstValue > secondValue) { return 1; } return 0; }); } const result = aggregate(expressionEvaluation.aggregationParams, aggregatedRowNodes); return result; } }