@adaptabletools/adaptable 12.1.5 → 12.1.8-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/base.css +11 -49
  2. package/bundle.cjs.js +106 -106
  3. package/index.css +13 -60
  4. package/package.json +1 -1
  5. package/publishTimestamp.d.ts +1 -1
  6. package/publishTimestamp.js +1 -1
  7. package/src/AdaptableInterfaces/IAdaptable.d.ts +12 -4
  8. package/src/AdaptableOptions/ColumnOptions.d.ts +2 -4
  9. package/src/AdaptableOptions/FilterOptions.d.ts +19 -0
  10. package/src/AdaptableOptions/FinancePluginOptions.d.ts +22 -1
  11. package/src/AdaptableOptions/StateOptions.d.ts +25 -12
  12. package/src/AdaptableOptions/UserInterfaceOptions.d.ts +31 -24
  13. package/src/Api/ColumnApi.d.ts +6 -1
  14. package/src/Api/ExportApi.d.ts +5 -0
  15. package/src/Api/FilterApi.d.ts +29 -0
  16. package/src/Api/FlashingCellApi.d.ts +8 -0
  17. package/src/Api/GridApi.d.ts +1 -0
  18. package/src/Api/Implementation/ColumnApiImpl.d.ts +2 -1
  19. package/src/Api/Implementation/ColumnApiImpl.js +7 -2
  20. package/src/Api/Implementation/DataSetApiImpl.js +1 -1
  21. package/src/Api/Implementation/ExportApiImpl.d.ts +3 -1
  22. package/src/Api/Implementation/ExportApiImpl.js +19 -3
  23. package/src/Api/Implementation/FilterApiImpl.d.ts +6 -0
  24. package/src/Api/Implementation/FilterApiImpl.js +42 -4
  25. package/src/Api/Implementation/FlashingCellApiImpl.d.ts +1 -0
  26. package/src/Api/Implementation/FlashingCellApiImpl.js +4 -0
  27. package/src/Api/Implementation/GridApiImpl.d.ts +1 -0
  28. package/src/Api/Implementation/GridApiImpl.js +4 -4
  29. package/src/Api/Implementation/InternalApiImpl.d.ts +0 -1
  30. package/src/Api/Implementation/InternalApiImpl.js +0 -3
  31. package/src/Api/Implementation/LayoutApiImpl.d.ts +1 -1
  32. package/src/Api/Implementation/LayoutApiImpl.js +4 -3
  33. package/src/Api/Implementation/PredicateApiImpl.js +4 -0
  34. package/src/Api/Implementation/QueryApiImpl.js +1 -1
  35. package/src/Api/Implementation/QueryLanguageApiImpl.js +9 -1
  36. package/src/Api/Implementation/TeamSharingApiImpl.js +1 -1
  37. package/src/Api/InternalApi.d.ts +0 -1
  38. package/src/Api/LayoutApi.d.ts +1 -1
  39. package/src/Api/SystemStatusApi.d.ts +1 -1
  40. package/src/Api/ToolPanelApi.d.ts +1 -1
  41. package/src/PredefinedConfig/CalculatedColumnState.d.ts +2 -2
  42. package/src/PredefinedConfig/Common/AdaptableColumn.js +3 -2
  43. package/src/PredefinedConfig/Common/AdaptablePredicate.js +30 -10
  44. package/src/PredefinedConfig/Common/AdaptableQuery.js +1 -1
  45. package/src/PredefinedConfig/Common/AggregationColumns.d.ts +6 -0
  46. package/src/PredefinedConfig/Common/AggregationColumns.js +4 -0
  47. package/src/PredefinedConfig/Common/ColumnFilter.d.ts +2 -2
  48. package/src/PredefinedConfig/Common/Enums.d.ts +0 -15
  49. package/src/PredefinedConfig/Common/Enums.js +1 -18
  50. package/src/PredefinedConfig/Common/SpecialColumnSettings.d.ts +6 -6
  51. package/src/PredefinedConfig/ExportState.d.ts +12 -4
  52. package/src/PredefinedConfig/LayoutState.d.ts +2 -1
  53. package/src/PredefinedConfig/PopupState.d.ts +1 -2
  54. package/src/Redux/ActionsReducers/AlertRedux.d.ts +1 -1
  55. package/src/Redux/ActionsReducers/AlertRedux.js +1 -1
  56. package/src/Redux/ActionsReducers/ConditionalStyleRedux.d.ts +1 -1
  57. package/src/Redux/ActionsReducers/ConditionalStyleRedux.js +1 -1
  58. package/src/Redux/ActionsReducers/CustomSortRedux.d.ts +1 -1
  59. package/src/Redux/ActionsReducers/CustomSortRedux.js +1 -1
  60. package/src/Redux/ActionsReducers/FlashingCellRedux.d.ts +1 -1
  61. package/src/Redux/ActionsReducers/FlashingCellRedux.js +1 -1
  62. package/src/Redux/ActionsReducers/FormatColumnRedux.d.ts +1 -1
  63. package/src/Redux/ActionsReducers/FormatColumnRedux.js +1 -1
  64. package/src/Redux/ActionsReducers/LayoutRedux.d.ts +28 -0
  65. package/src/Redux/ActionsReducers/LayoutRedux.js +80 -2
  66. package/src/Redux/ActionsReducers/PlusMinusRedux.d.ts +1 -1
  67. package/src/Redux/ActionsReducers/PlusMinusRedux.js +1 -1
  68. package/src/Redux/ActionsReducers/PopupRedux.d.ts +0 -2
  69. package/src/Redux/ActionsReducers/PopupRedux.js +1 -28
  70. package/src/Redux/ActionsReducers/ScheduleRedux.d.ts +5 -5
  71. package/src/Redux/ActionsReducers/ScheduleRedux.js +5 -5
  72. package/src/Redux/ActionsReducers/ShortcutRedux.d.ts +1 -1
  73. package/src/Redux/ActionsReducers/ShortcutRedux.js +1 -1
  74. package/src/Redux/ActionsReducers/SystemRedux.d.ts +1 -2
  75. package/src/Redux/ActionsReducers/SystemRedux.js +1 -2
  76. package/src/Redux/Store/AdaptableStore.js +30 -16
  77. package/src/Strategy/AlertModule.d.ts +1 -0
  78. package/src/Strategy/AlertModule.js +20 -0
  79. package/src/Strategy/CalculatedColumnModule.js +2 -2
  80. package/src/Strategy/ExportModule.d.ts +0 -1
  81. package/src/Strategy/ExportModule.js +0 -16
  82. package/src/Strategy/FilterModule.js +6 -0
  83. package/src/Strategy/FlashingCellModule.js +2 -2
  84. package/src/Strategy/Interface/IModule.d.ts +4 -0
  85. package/src/Strategy/LayoutModule.js +20 -20
  86. package/src/Strategy/Utilities/FormatColumn/getFormatColumnStyleViewItems.js +16 -1
  87. package/src/Strategy/Utilities/Layout/getLayoutFilterViewItems.js +15 -11
  88. package/src/Utilities/Constants/DocumentationLinkConstants.d.ts +1 -0
  89. package/src/Utilities/Constants/DocumentationLinkConstants.js +2 -1
  90. package/src/Utilities/Defaults/DefaultAdaptableOptions.js +3 -0
  91. package/src/Utilities/ExpressionFunctions/aggregatedBooleanExpressionFunctions.d.ts +12 -2
  92. package/src/Utilities/ExpressionFunctions/aggregatedBooleanExpressionFunctions.js +30 -66
  93. package/src/Utilities/ExpressionFunctions/aggregatedScalarExpressionFunctions.d.ts +22 -6
  94. package/src/Utilities/ExpressionFunctions/aggregatedScalarExpressionFunctions.js +423 -220
  95. package/src/Utilities/ExpressionFunctions/expressionFunctionUtils.d.ts +7 -1
  96. package/src/Utilities/ExpressionFunctions/expressionFunctionUtils.js +23 -7
  97. package/src/Utilities/ExpressionFunctions/scalarAggregationHelper.d.ts +0 -1
  98. package/src/Utilities/ExpressionFunctions/scalarAggregationHelper.js +6 -54
  99. package/src/Utilities/ExpressionFunctions/scalarExpressionFunctions.js +17 -5
  100. package/src/Utilities/Extensions/ArrayExtensions.js +6 -0
  101. package/src/Utilities/Helpers/CalendarHelper.js +10 -7
  102. package/src/Utilities/Helpers/DateHelper.d.ts +0 -26
  103. package/src/Utilities/Helpers/DateHelper.js +2 -32
  104. package/src/Utilities/Interface/MessagePopups.d.ts +0 -4
  105. package/src/Utilities/ObjectFactory.d.ts +6 -4
  106. package/src/Utilities/ObjectFactory.js +30 -17
  107. package/src/Utilities/Services/AggregatedScalarLiveValue.d.ts +25 -0
  108. package/src/Utilities/Services/AggregatedScalarLiveValue.js +103 -0
  109. package/src/Utilities/Services/AlertService.d.ts +0 -1
  110. package/src/Utilities/Services/AlertService.js +5 -17
  111. package/src/Utilities/Services/CalculatedColumnExpressionService.d.ts +4 -4
  112. package/src/Utilities/Services/CalculatedColumnExpressionService.js +29 -154
  113. package/src/Utilities/Services/Interface/ICalculatedColumnExpressionService.d.ts +2 -2
  114. package/src/Utilities/Services/Interface/IQueryLanguageService.d.ts +6 -3
  115. package/src/Utilities/Services/QueryLanguageService.d.ts +6 -3
  116. package/src/Utilities/Services/QueryLanguageService.js +23 -6
  117. package/src/Utilities/Services/ReportService.js +47 -46
  118. package/src/View/AdaptableView.js +1 -2
  119. package/src/View/CalculatedColumn/Utilities/getCalculatedColumnSettingsTags.d.ts +2 -0
  120. package/src/View/CalculatedColumn/Utilities/{getCalculatedColumnSettingTags.js → getCalculatedColumnSettingsTags.js} +5 -3
  121. package/src/View/CalculatedColumn/Wizard/CalculatedColumnDefinitionWizardSection.d.ts +10 -0
  122. package/src/View/CalculatedColumn/Wizard/CalculatedColumnDefinitionWizardSection.js +80 -0
  123. package/src/View/CalculatedColumn/Wizard/CalculatedColumnExpressionWizardSection.js +21 -15
  124. package/src/View/CalculatedColumn/Wizard/CalculatedColumnSettingsWizardSection.d.ts +1 -2
  125. package/src/View/CalculatedColumn/Wizard/CalculatedColumnSettingsWizardSection.js +10 -53
  126. package/src/View/CalculatedColumn/Wizard/CalculatedColumnWizard.js +14 -3
  127. package/src/View/Components/AdaptableDateInput/index.js +1 -1
  128. package/src/View/Components/AdaptableObjectList/AdaptableObjectCompactList.js +42 -6
  129. package/src/View/Components/AdaptableObjectList/AdaptableObjectList.js +1 -1
  130. package/src/View/Components/EntityRulesEditor/index.js +26 -5
  131. package/src/View/Components/FilterForm/FilterForm.js +10 -5
  132. package/src/View/Components/FilterForm/ListBoxFilterForm.js +1 -0
  133. package/src/View/Components/FilterForm/QuickFilterForm.js +12 -7
  134. package/src/View/Components/PermittedValuesSelector/PermitedValuesSelector.d.ts +9 -0
  135. package/src/View/Components/PermittedValuesSelector/PermitedValuesSelector.js +28 -0
  136. package/src/View/Components/PermittedValuesSelector/index.d.ts +1 -0
  137. package/src/View/Components/PermittedValuesSelector/index.js +5 -0
  138. package/src/View/Components/Popups/AdaptablePopup/Navigation.js +2 -2
  139. package/src/View/Components/Popups/AdaptableToaster.js +2 -7
  140. package/src/View/Components/Popups/WindowPopups/windowFactory.d.ts +0 -1
  141. package/src/View/Components/Popups/WindowPopups/windowFactory.js +1 -4
  142. package/src/View/Export/ExportViewPanel.d.ts +1 -2
  143. package/src/View/Export/ExportViewPanel.js +2 -6
  144. package/src/View/Export/Wizard/ReportColumnTypeWizard.d.ts +1 -2
  145. package/src/View/Export/Wizard/ReportColumnTypeWizard.js +11 -12
  146. package/src/View/Export/Wizard/ReportRowTypeWizard.d.ts +1 -2
  147. package/src/View/Export/Wizard/ReportRowTypeWizard.js +12 -13
  148. package/src/View/Export/Wizard/ReportSettingsWizard.js +1 -2
  149. package/src/View/Filter/FilterViewPanel.js +20 -4
  150. package/src/View/FormatColumn/Wizard/FormatColumnFormatWizardSection.js +1 -1
  151. package/src/View/FreeTextColumn/FreeTextColumnSummary.js +1 -2
  152. package/src/View/FreeTextColumn/Wizard/FreeTextColumnSettingsWizardSection.d.ts +1 -1
  153. package/src/View/FreeTextColumn/Wizard/FreeTextColumnWizard.js +1 -1
  154. package/src/View/Layout/Wizard/{LayoutEditor → Components}/ColumnLabels.d.ts +0 -0
  155. package/src/View/Layout/Wizard/{LayoutEditor → Components}/ColumnLabels.js +0 -0
  156. package/src/View/Layout/Wizard/LayoutWizard.js +1 -0
  157. package/src/View/Layout/Wizard/sections/AggregationsSection.d.ts +1 -0
  158. package/src/View/Layout/Wizard/sections/AggregationsSection.js +69 -8
  159. package/src/View/Layout/Wizard/sections/ColumnsSection.js +1 -1
  160. package/src/View/Query/QueryViewPanel.js +1 -1
  161. package/src/agGrid/Adaptable.d.ts +12 -3
  162. package/src/agGrid/Adaptable.js +225 -152
  163. package/src/agGrid/agGridHelper.d.ts +1 -0
  164. package/src/agGrid/agGridHelper.js +5 -3
  165. package/src/agGrid/agGridMenuHelper.d.ts +1 -0
  166. package/src/agGrid/agGridMenuHelper.js +4 -2
  167. package/src/agGrid/weightedAverage.d.ts +6 -0
  168. package/src/agGrid/weightedAverage.js +66 -0
  169. package/src/components/ExpressionEditor/BaseEditorInput.d.ts +1 -0
  170. package/src/components/ExpressionEditor/BaseEditorInput.js +2 -3
  171. package/src/components/ExpressionEditor/EditorInput.d.ts +1 -1
  172. package/src/components/ExpressionEditor/EditorInput.js +24 -4
  173. package/src/components/ExpressionEditor/{EditorInputReactive.d.ts → EditorInputWithWhereClause.d.ts} +3 -3
  174. package/src/components/ExpressionEditor/{EditorInputReactive.js → EditorInputWithWhereClause.js} +6 -5
  175. package/src/components/ExpressionEditor/editorButtonsAggregatedBoolean.d.ts +2 -0
  176. package/src/components/ExpressionEditor/{editorButtonsReactive.js → editorButtonsAggregatedBoolean.js} +22 -37
  177. package/src/components/ExpressionEditor/editorButtonsAggregatedScalar.js +5 -10
  178. package/src/components/ExpressionEditor/editorButtonsCumulativeAggregatedScalar.d.ts +2 -0
  179. package/src/components/ExpressionEditor/editorButtonsCumulativeAggregatedScalar.js +50 -0
  180. package/src/components/ExpressionEditor/editorButtonsObservable.d.ts +2 -0
  181. package/src/components/ExpressionEditor/editorButtonsObservable.js +40 -0
  182. package/src/components/ExpressionEditor/index.d.ts +1 -1
  183. package/src/components/ExpressionEditor/index.js +26 -5
  184. package/src/components/ProgressIndicator/ProgressIndicator.js +10 -12
  185. package/src/metamodel/adaptable.metamodel.d.ts +129 -7
  186. package/src/metamodel/adaptable.metamodel.js +1 -1
  187. package/src/parser/src/types.d.ts +1 -1
  188. package/src/types.d.ts +4 -4
  189. package/version.d.ts +1 -1
  190. package/version.js +1 -1
  191. package/src/View/CalculatedColumn/Utilities/getCalculatedColumnSettingTags.d.ts +0 -2
  192. package/src/View/Layout/LayoutEditorStandalonePopup.d.ts +0 -3
  193. package/src/View/Layout/LayoutEditorStandalonePopup.js +0 -78
  194. package/src/View/Layout/Wizard/LayoutEditor/ColumnList.d.ts +0 -27
  195. package/src/View/Layout/Wizard/LayoutEditor/ColumnList.js +0 -86
  196. package/src/View/Layout/Wizard/LayoutEditor/ColumnSortList.d.ts +0 -16
  197. package/src/View/Layout/Wizard/LayoutEditor/ColumnSortList.js +0 -89
  198. package/src/View/Layout/Wizard/LayoutEditor/PivotList.d.ts +0 -15
  199. package/src/View/Layout/Wizard/LayoutEditor/PivotList.js +0 -70
  200. package/src/View/Layout/Wizard/LayoutEditor/RowGroupsList.d.ts +0 -15
  201. package/src/View/Layout/Wizard/LayoutEditor/RowGroupsList.js +0 -70
  202. package/src/View/Layout/Wizard/LayoutEditor/droppableIds.d.ts +0 -7
  203. package/src/View/Layout/Wizard/LayoutEditor/droppableIds.js +0 -11
  204. package/src/View/Layout/Wizard/LayoutEditor/getItemStyle.d.ts +0 -6
  205. package/src/View/Layout/Wizard/LayoutEditor/getItemStyle.js +0 -26
  206. package/src/View/Layout/Wizard/LayoutEditor/index.d.ts +0 -9
  207. package/src/View/Layout/Wizard/LayoutEditor/index.js +0 -367
  208. package/src/View/Layout/Wizard/LayoutEditor/reducer.d.ts +0 -28
  209. package/src/View/Layout/Wizard/LayoutEditor/reducer.js +0 -46
  210. package/src/View/Layout/Wizard/LayoutEditor/utils.d.ts +0 -10
  211. package/src/View/Layout/Wizard/LayoutEditor/utils.js +0 -14
  212. package/src/View/Layout/Wizard/LayoutEditorWizard.d.ts +0 -30
  213. package/src/View/Layout/Wizard/LayoutEditorWizard.js +0 -132
  214. package/src/components/ExpressionEditor/editorButtonsReactive.d.ts +0 -2
@@ -1,15 +1,60 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.aggregatedScalarExpressionFunctions = void 0;
3
+ exports.aggregatedScalarExpressionFunctions = exports.aggregatedExpressionFunctions = exports.cumulativeAggregatedExpressionFunctions = void 0;
4
4
  const expressionFunctionUtils_1 = require("./expressionFunctionUtils");
5
5
  const ExpressionEvaluationError_1 = require("../../parser/src/ExpressionEvaluationError");
6
+ exports.cumulativeAggregatedExpressionFunctions = [
7
+ 'CUMUL',
8
+ 'OVER',
9
+ 'SUM',
10
+ 'PERCENTAGE',
11
+ 'MIN',
12
+ 'MAX',
13
+ 'AVG',
14
+ 'WEIGHT',
15
+ 'COL',
16
+ 'GROUP_BY',
17
+ ];
18
+ exports.aggregatedExpressionFunctions = [
19
+ 'SUM',
20
+ 'PERCENTAGE',
21
+ 'MIN',
22
+ 'MAX',
23
+ 'QUANT',
24
+ 'AVG',
25
+ 'WEIGHT',
26
+ 'COL',
27
+ 'GROUP_BY',
28
+ ];
6
29
  exports.aggregatedScalarExpressionFunctions = {
30
+ CUMUL: {
31
+ handler(args, context) {
32
+ const aggregationParameter = expressionFunctionUtils_1.extractParameter('CUMUL', 'aggregationScalar', ['SUM', 'MIN', 'MAX', 'PERCENTAGE', 'AVG', 'PERCENTAGE'], args);
33
+ const overColumnParameter = expressionFunctionUtils_1.extractParameter('CUMUL', 'operand', ['OVER'], args);
34
+ const cumulationExpressionEvaluation = mapAggregationToCumulation(aggregationParameter, overColumnParameter, context);
35
+ const result = {
36
+ name: 'CUMUL',
37
+ type: 'aggregationScalar',
38
+ value: cumulationExpressionEvaluation,
39
+ };
40
+ return result;
41
+ },
42
+ description: 'Performs a cumulative aggregation (running total) with the given aggregation operation over a provided column',
43
+ signatures: ['CUMUL( aggregationOp: SUM|MIN|MAX, OVER( [colNameB] ))'],
44
+ examples: [
45
+ 'CUMUL( SUM([colNameA]), OVER( [colNameB] ))',
46
+ 'CUMUL( MIN([colNameA]), OVER( [colNameB] ))',
47
+ 'CUMUL( MAX([colNameA]), OVER( [colNameB] ))',
48
+ ],
49
+ },
7
50
  SUM: {
8
51
  handler(args, context) {
9
52
  const sumColumnParameter = expressionFunctionUtils_1.extractColumnParameter('SUM', args);
10
53
  const sumColumnName = sumColumnParameter.value;
11
54
  expressionFunctionUtils_1.validateColumnType(sumColumnName, ['Number'], 'SUM', context.adaptableApi);
12
- const groupByParameter = expressionFunctionUtils_1.extractParameter('SUM', 'operand', ['GROUP_BY'], args, true);
55
+ const groupByParameter = expressionFunctionUtils_1.extractParameter('SUM', 'operand', ['GROUP_BY'], args, {
56
+ isOptional: true,
57
+ });
13
58
  const aggregationExpressionEvaluation = {
14
59
  aggregationParams: {
15
60
  reducers: {
@@ -18,20 +63,21 @@ exports.aggregatedScalarExpressionFunctions = {
18
63
  field: sumColumnName,
19
64
  initialValue: 0,
20
65
  reducer: (totalSum, rowValue) => {
21
- if (!rowValue) {
66
+ if (isUndefinedValue(rowValue)) {
22
67
  return totalSum;
23
68
  }
24
- return totalSum + rowValue;
69
+ return totalSum + expressionFunctionUtils_1.getNumericValue(rowValue);
25
70
  },
26
71
  },
27
72
  },
28
73
  },
74
+ rowFilterFn: context.filterFn,
29
75
  columnDependencies: [sumColumnName],
30
76
  };
31
- addGroupByParams(groupByParameter, aggregationExpressionEvaluation);
77
+ addGroupByParams(groupByParameter === null || groupByParameter === void 0 ? void 0 : groupByParameter.value, aggregationExpressionEvaluation);
32
78
  const result = {
33
79
  name: 'SUM',
34
- type: 'aggregation',
80
+ type: 'aggregationScalar',
35
81
  value: aggregationExpressionEvaluation,
36
82
  };
37
83
  return result;
@@ -51,17 +97,21 @@ exports.aggregatedScalarExpressionFunctions = {
51
97
  const percentageColumnParameter = expressionFunctionUtils_1.extractColumnParameter('PERCENTAGE', args);
52
98
  const percentageColumnName = percentageColumnParameter.value;
53
99
  expressionFunctionUtils_1.validateColumnType(percentageColumnName, ['Number'], 'PERCENTAGE', context.adaptableApi);
54
- const sumOperand = expressionFunctionUtils_1.extractParameter('PERCENTAGE', 'aggregation', ['SUM'], args, true);
55
- const groupByOperand = expressionFunctionUtils_1.extractParameter('PERCENTAGE', 'operand', ['GROUP_BY'], args, true);
100
+ const sumOperand = expressionFunctionUtils_1.extractParameter('PERCENTAGE', 'aggregationScalar', ['SUM'], args, {
101
+ isOptional: true,
102
+ });
103
+ const groupByOperand = expressionFunctionUtils_1.extractParameter('PERCENTAGE', 'operand', ['GROUP_BY'], args, {
104
+ isOptional: true,
105
+ });
56
106
  if (sumOperand && groupByOperand) {
57
107
  throw new ExpressionEvaluationError_1.ExpressionEvaluationError('PERCENTAGE', `expects either a SUM or a GROUP_BY argument`);
58
108
  }
59
109
  const sumAggregationColumnName = sumOperand
60
110
  ? sumOperand.value.aggregationParams.reducers['SUM'].field
61
111
  : percentageColumnName;
62
- const groupByColumnName = groupByOperand
63
- ? groupByOperand.value
64
- : (_a = sumOperand === null || sumOperand === void 0 ? void 0 : sumOperand.value.aggregationParams.groupBy) === null || _a === void 0 ? void 0 : _a[0].field;
112
+ const groupByColumnNames = groupByOperand
113
+ ? groupByOperand === null || groupByOperand === void 0 ? void 0 : groupByOperand.value
114
+ : (_a = sumOperand === null || sumOperand === void 0 ? void 0 : sumOperand.value.aggregationParams.groupBy) === null || _a === void 0 ? void 0 : _a.map((param) => param.field);
65
115
  const aggregationExpressionEvaluation = {
66
116
  aggregationParams: {
67
117
  reducers: {
@@ -70,32 +120,26 @@ exports.aggregatedScalarExpressionFunctions = {
70
120
  field: sumAggregationColumnName,
71
121
  initialValue: 0,
72
122
  reducer: (totalSum, rowValue) => {
73
- if (!rowValue) {
123
+ if (isUndefinedValue(rowValue)) {
74
124
  return totalSum;
75
125
  }
76
- return totalSum + rowValue;
126
+ return totalSum + expressionFunctionUtils_1.getNumericValue(rowValue);
77
127
  },
78
128
  },
79
129
  },
80
130
  },
81
131
  rowValueGetter: (rowNode, aggregationValue) => {
82
- return ((context.adaptableApi.gridApi.getRawValueFromRowNode(rowNode, percentageColumnName) /
132
+ return ((expressionFunctionUtils_1.getNumericValue(context.adaptableApi.gridApi.getRawValueFromRowNode(rowNode, percentageColumnName)) /
83
133
  aggregationValue) *
84
134
  100);
85
135
  },
136
+ rowFilterFn: context.filterFn,
86
137
  columnDependencies: [...new Set([percentageColumnName, sumAggregationColumnName])],
87
138
  };
88
- if (groupByColumnName) {
89
- aggregationExpressionEvaluation.aggregationParams.groupBy = [
90
- {
91
- field: groupByColumnName,
92
- },
93
- ];
94
- aggregationExpressionEvaluation.columnDependencies.push(groupByColumnName);
95
- }
139
+ addGroupByParams(groupByColumnNames, aggregationExpressionEvaluation);
96
140
  const result = {
97
141
  name: 'PERCENTAGE',
98
- type: 'aggregation',
142
+ type: 'aggregationScalar',
99
143
  value: aggregationExpressionEvaluation,
100
144
  };
101
145
  return result;
@@ -114,171 +158,67 @@ exports.aggregatedScalarExpressionFunctions = {
114
158
  'PERCENTAGE( [colNameA], SUM ( [colNameB], GROUP_BY( [colNameC] )))',
115
159
  ],
116
160
  },
117
- QUANT: {
118
- handler(args, context) {
119
- var _a, _b, _c;
120
- const quantileColumnParameter = expressionFunctionUtils_1.extractColumnParameter('QUANT', args);
121
- const quantileColumnName = quantileColumnParameter.value;
122
- expressionFunctionUtils_1.validateColumnType(quantileColumnName, ['Number'], 'QUANT', context.adaptableApi);
123
- const qNumber = args.find((arg) => typeof arg === 'number');
124
- if (qNumber == null || qNumber <= 0) {
125
- throw new ExpressionEvaluationError_1.ExpressionEvaluationError('QUANT', 'expects a positive number as argument');
126
- }
127
- const groupByOperand = expressionFunctionUtils_1.extractParameter('QUANT', 'operand', ['GROUP_BY'], args, true);
128
- const groupByColumnName = groupByOperand === null || groupByOperand === void 0 ? void 0 : groupByOperand.value;
129
- let quantReducer;
130
- if (groupByColumnName) {
131
- // do the heavy-lifting in done()
132
- quantReducer = {
133
- initialValue: new WeakMap(),
134
- reducer: (nodeValueMap, rowValue, rowNode, rowIndex) => {
135
- if (!rowValue) {
136
- return nodeValueMap;
137
- }
138
- nodeValueMap.set(rowNode, rowValue);
139
- return nodeValueMap;
140
- },
141
- done: (nodeValueMap, groupItems) => {
142
- var _a, _b;
143
- const populationSize = (_b = (_a = groupItems === null || groupItems === void 0 ? void 0 : groupItems.filter((rowNode) => {
144
- const rowValue = context.adaptableApi.gridApi.getRawValueFromRowNode(rowNode, quantileColumnName);
145
- return rowValue != undefined;
146
- })) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
147
- const bucketsMap = new Map();
148
- for (let step = 1; step <= qNumber; step++) {
149
- bucketsMap.set(step, populationSize * (step / qNumber));
150
- }
151
- const indexBucketMap = new Map();
152
- for (let populationIndex = 0; populationIndex < populationSize; populationIndex++) {
153
- for (let quantIndex = 1; quantIndex <= qNumber; quantIndex++) {
154
- if (bucketsMap.get(quantIndex) < populationIndex + 1) {
155
- continue;
156
- }
157
- else {
158
- indexBucketMap.set(populationIndex, quantIndex);
159
- break;
160
- }
161
- }
162
- }
163
- const groupedRowBucketMap = new Map();
164
- groupItems.forEach((subgroupRowNode, subgroupRowIndex) => {
165
- const subgroupRowValue = nodeValueMap.get(subgroupRowNode);
166
- if (subgroupRowValue) {
167
- groupedRowBucketMap.set(subgroupRowValue, indexBucketMap.get(subgroupRowIndex));
168
- }
169
- });
170
- return groupedRowBucketMap;
171
- },
172
- };
173
- }
174
- else {
175
- // in case of non-grouped quantiles, we are able to calculate the buckets beforehand (which is the most efficient)
176
- const populationSize = (_c = (_b = (_a = context.adaptableApi.gridApi.getAllRowNodes()) === null || _a === void 0 ? void 0 : _a.filter((rowNode) => {
177
- const rowValue = context.adaptableApi.gridApi.getRawValueFromRowNode(rowNode, quantileColumnName);
178
- return rowValue != undefined;
179
- })) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0;
180
- const bucketsMap = new Map();
181
- for (let step = 1; step <= qNumber; step++) {
182
- bucketsMap.set(step, populationSize * (step / qNumber));
183
- }
184
- const indexBucketMap = new Map();
185
- for (let populationIndex = 0; populationIndex < populationSize; populationIndex++) {
186
- for (let quantIndex = 1; quantIndex <= qNumber; quantIndex++) {
187
- if (bucketsMap.get(quantIndex) < populationIndex + 1) {
188
- continue;
189
- }
190
- else {
191
- indexBucketMap.set(populationIndex, quantIndex);
192
- break;
193
- }
194
- }
195
- }
196
- quantReducer = {
197
- initialValue: new Map(),
198
- reducer: (rowBucketMap, rowValue, rowNode, rowIndex) => {
199
- if (!rowValue) {
200
- return rowBucketMap;
201
- }
202
- rowBucketMap.set(rowValue, indexBucketMap.get(rowIndex));
203
- return rowBucketMap;
204
- },
205
- };
206
- }
207
- const aggregationExpressionEvaluation = {
208
- sortByColumn: quantileColumnName,
209
- filterUndefinedValues: true,
210
- aggregationParams: {
211
- reducers: {
212
- QUANT: Object.assign({ name: 'QUANT', field: quantileColumnName }, quantReducer),
213
- },
214
- },
215
- rowValueGetter: (rowNode, rowBucketMap) => {
216
- const rowValue = context.adaptableApi.gridApi.getRawValueFromRowNode(rowNode, quantileColumnName);
217
- if (rowValue == null) {
218
- return;
219
- }
220
- return rowBucketMap.get(rowValue);
221
- },
222
- columnDependencies: [quantileColumnName],
223
- };
224
- if (groupByColumnName) {
225
- aggregationExpressionEvaluation.aggregationParams.groupBy = [
226
- {
227
- field: groupByColumnName,
228
- },
229
- ];
230
- aggregationExpressionEvaluation.columnDependencies.push(groupByColumnName);
231
- }
232
- const result = {
233
- name: 'QUANT',
234
- type: 'aggregation',
235
- value: aggregationExpressionEvaluation,
236
- };
237
- return result;
238
- },
239
- description: 'Calculates the q-Quantiles of the given group and displays which q-quantile the given value is in\nCommon quantiles are 4-quantile or Quartile, 5-quantile or Quintile, 10-quantile or Decile and 100-quantile or Percentile',
240
- signatures: [
241
- 'QUANT( [colName], q: number)',
242
- 'QUANT( COL(name: string), q: number)',
243
- 'QUANT( [colName1], q: number, GROUP_BY([colName2]) )',
244
- ],
245
- examples: [
246
- 'QUANT( [col1], 5)',
247
- `QUANT( COL('col1'), 100))`,
248
- 'QUANT( [col1], 4, GROUP_BY([col2]) )',
249
- ],
250
- },
251
161
  AVG: {
252
162
  handler(args, context) {
253
163
  const avgColumnParameter = expressionFunctionUtils_1.extractColumnParameter('AVG', args);
254
164
  const avgColumnName = avgColumnParameter.value;
255
165
  expressionFunctionUtils_1.validateColumnType(avgColumnName, ['Number'], 'AVG', context.adaptableApi);
256
- const groupByParameter = expressionFunctionUtils_1.extractParameter('AVG', 'operand', ['GROUP_BY'], args, true);
166
+ const groupByParameter = expressionFunctionUtils_1.extractParameter('AVG', 'operand', ['GROUP_BY'], args, {
167
+ isOptional: true,
168
+ });
169
+ const weightParameter = expressionFunctionUtils_1.extractParameter('AVG', 'operand', ['WEIGHT'], args, {
170
+ isOptional: true,
171
+ });
257
172
  const aggregationExpressionEvaluation = {
258
173
  aggregationParams: {
259
174
  reducers: {
260
- SUM: {
175
+ AVG: {
261
176
  name: 'AVG',
262
177
  field: avgColumnName,
263
- initialValue: 0,
264
- reducer: (totalSum, rowValue) => {
265
- if (!rowValue) {
266
- return totalSum;
178
+ initialValue: {
179
+ sumOfValues: 0,
180
+ numberOfValues: 0,
181
+ },
182
+ reducer: (aggregatedValue, rowValue, rowNode) => {
183
+ var _a;
184
+ if (isUndefinedValue(rowValue)) {
185
+ return aggregatedValue;
186
+ }
187
+ const numericRowValue = expressionFunctionUtils_1.getNumericValue(rowValue);
188
+ if (weightParameter) {
189
+ // weighted average
190
+ const weightValue = (_a = expressionFunctionUtils_1.getNumericValue(context.adaptableApi.gridApi.getRawValueFromRowNode(rowNode, weightParameter.value))) !== null && _a !== void 0 ? _a : 0;
191
+ aggregatedValue.sumOfValues =
192
+ aggregatedValue.sumOfValues + numericRowValue * weightValue;
193
+ aggregatedValue.numberOfValues = aggregatedValue.numberOfValues + weightValue;
267
194
  }
268
- return totalSum + rowValue;
195
+ else {
196
+ aggregatedValue.sumOfValues = aggregatedValue.sumOfValues + numericRowValue;
197
+ aggregatedValue.numberOfValues = aggregatedValue.numberOfValues + 1;
198
+ }
199
+ return aggregatedValue;
269
200
  },
270
- done: (value, dataArray) => {
271
- return dataArray.length ? value / dataArray.length : 0;
201
+ done: (aggregatedValue) => {
202
+ if (aggregatedValue.numberOfValues === 0) {
203
+ return 0;
204
+ }
205
+ return aggregatedValue.sumOfValues / aggregatedValue.numberOfValues;
272
206
  },
273
207
  },
274
208
  },
275
209
  },
210
+ rowFilterFn: context.filterFn,
276
211
  columnDependencies: [avgColumnName],
277
212
  };
278
- addGroupByParams(groupByParameter, aggregationExpressionEvaluation);
213
+ addGroupByParams(groupByParameter === null || groupByParameter === void 0 ? void 0 : groupByParameter.value, aggregationExpressionEvaluation);
214
+ if (weightParameter) {
215
+ aggregationExpressionEvaluation.context = {
216
+ weightParam: weightParameter,
217
+ };
218
+ }
279
219
  const result = {
280
220
  name: 'AVG',
281
- type: 'aggregation',
221
+ type: 'aggregationScalar',
282
222
  value: aggregationExpressionEvaluation,
283
223
  };
284
224
  return result;
@@ -297,19 +237,22 @@ exports.aggregatedScalarExpressionFunctions = {
297
237
  const minColumnParameter = expressionFunctionUtils_1.extractColumnParameter('MIN', args);
298
238
  const minColumnName = minColumnParameter.value;
299
239
  expressionFunctionUtils_1.validateColumnType(minColumnName, ['Number'], 'MIN', context.adaptableApi);
300
- const groupByParameter = expressionFunctionUtils_1.extractParameter('MIN', 'operand', ['GROUP_BY'], args, true);
240
+ const groupByParameter = expressionFunctionUtils_1.extractParameter('MIN', 'operand', ['GROUP_BY'], args, {
241
+ isOptional: true,
242
+ });
301
243
  const aggregationExpressionEvaluation = {
302
244
  aggregationParams: {
303
245
  reducers: {
304
- SUM: {
246
+ MIN: {
305
247
  name: 'MIN',
306
248
  field: minColumnName,
307
249
  initialValue: Number.MAX_VALUE,
308
250
  reducer: (minValue, rowValue) => {
309
- if (!rowValue) {
251
+ if (isUndefinedValue(rowValue)) {
310
252
  return minValue;
311
253
  }
312
- return rowValue < minValue ? rowValue : minValue;
254
+ const numericRowValue = expressionFunctionUtils_1.getNumericValue(rowValue);
255
+ return numericRowValue < minValue ? numericRowValue : minValue;
313
256
  },
314
257
  done: (minValue) => {
315
258
  if (minValue !== Number.MAX_VALUE) {
@@ -319,12 +262,13 @@ exports.aggregatedScalarExpressionFunctions = {
319
262
  },
320
263
  },
321
264
  },
265
+ rowFilterFn: context.filterFn,
322
266
  columnDependencies: [minColumnName],
323
267
  };
324
- addGroupByParams(groupByParameter, aggregationExpressionEvaluation);
268
+ addGroupByParams(groupByParameter === null || groupByParameter === void 0 ? void 0 : groupByParameter.value, aggregationExpressionEvaluation);
325
269
  const result = {
326
270
  name: 'MIN',
327
- type: 'aggregation',
271
+ type: 'aggregationScalar',
328
272
  value: aggregationExpressionEvaluation,
329
273
  };
330
274
  return result;
@@ -343,19 +287,22 @@ exports.aggregatedScalarExpressionFunctions = {
343
287
  const maxColumnParameter = expressionFunctionUtils_1.extractColumnParameter('MAX', args);
344
288
  const maxColumnName = maxColumnParameter.value;
345
289
  expressionFunctionUtils_1.validateColumnType(maxColumnName, ['Number'], 'MAX', context.adaptableApi);
346
- const groupByParameter = expressionFunctionUtils_1.extractParameter('MAX', 'operand', ['GROUP_BY'], args, true);
290
+ const groupByParameter = expressionFunctionUtils_1.extractParameter('MAX', 'operand', ['GROUP_BY'], args, {
291
+ isOptional: true,
292
+ });
347
293
  const aggregationExpressionEvaluation = {
348
294
  aggregationParams: {
349
295
  reducers: {
350
- SUM: {
296
+ MAX: {
351
297
  name: 'MAX',
352
298
  field: maxColumnName,
353
299
  initialValue: Number.MIN_VALUE,
354
300
  reducer: (maxValue, rowValue) => {
355
- if (!rowValue) {
301
+ if (isUndefinedValue(rowValue)) {
356
302
  return maxValue;
357
303
  }
358
- return rowValue > maxValue ? rowValue : maxValue;
304
+ const numericRowValue = expressionFunctionUtils_1.getNumericValue(rowValue);
305
+ return numericRowValue > maxValue ? numericRowValue : maxValue;
359
306
  },
360
307
  done: (maxValue) => {
361
308
  if (maxValue !== Number.MIN_VALUE) {
@@ -365,12 +312,13 @@ exports.aggregatedScalarExpressionFunctions = {
365
312
  },
366
313
  },
367
314
  },
315
+ rowFilterFn: context.filterFn,
368
316
  columnDependencies: [maxColumnName],
369
317
  };
370
- addGroupByParams(groupByParameter, aggregationExpressionEvaluation);
318
+ addGroupByParams(groupByParameter === null || groupByParameter === void 0 ? void 0 : groupByParameter.value, aggregationExpressionEvaluation);
371
319
  const result = {
372
320
  name: 'MAX',
373
- type: 'aggregation',
321
+ type: 'aggregationScalar',
374
322
  value: aggregationExpressionEvaluation,
375
323
  };
376
324
  return result;
@@ -384,45 +332,136 @@ exports.aggregatedScalarExpressionFunctions = {
384
332
  ],
385
333
  examples: ['MIN([colA])', 'MIN([colA], GROUP_BY([colB]))'],
386
334
  },
387
- GROUP_BY: {
388
- handler(args, context) {
389
- const columnParameter = expressionFunctionUtils_1.extractColumnParameter('GROUP_BY', args);
390
- const result = {
391
- type: 'operand',
392
- name: 'GROUP_BY',
393
- value: columnParameter.value,
394
- };
395
- return result;
396
- },
397
- description: 'Groups an aggregation operation within the rows that have the same value in the specified column',
398
- signatures: ['GROUP_BY( [colName] )', 'GROUP_BY( COL(name: string))'],
399
- examples: ['GROUP_BY( [colName] )', `GROUP_BY( COL('colName'))`],
400
- },
401
- CUMUL: {
335
+ QUANT: {
402
336
  handler(args, context) {
403
- var _a;
404
- const aggregationParameter = expressionFunctionUtils_1.extractParameter('CUMUL', 'aggregation', ['SUM', 'MIN', 'MAX', 'PERCENTAGE', 'AVG'], args);
405
- if (aggregationParameter.name === 'AVG' || aggregationParameter.name === 'PERCENTAGE') {
406
- throw new ExpressionEvaluationError_1.ExpressionEvaluationError('CUMUL', `supports only following aggregations: SUM, MIN, MAX`);
337
+ var _a, _b, _c;
338
+ const quantileColumnParameter = expressionFunctionUtils_1.extractColumnParameter('QUANT', args);
339
+ const quantileColumnName = quantileColumnParameter.value;
340
+ expressionFunctionUtils_1.validateColumnType(quantileColumnName, ['Number'], 'QUANT', context.adaptableApi);
341
+ const qNumber = args.find((arg) => typeof arg === 'number');
342
+ if (qNumber == null || qNumber <= 0) {
343
+ throw new ExpressionEvaluationError_1.ExpressionEvaluationError('QUANT', 'expects a positive number as argument');
344
+ }
345
+ const groupByOperand = expressionFunctionUtils_1.extractParameter('QUANT', 'operand', ['GROUP_BY'], args, {
346
+ isOptional: true,
347
+ });
348
+ const groupByColumnNames = groupByOperand === null || groupByOperand === void 0 ? void 0 : groupByOperand.value;
349
+ let quantReducer;
350
+ if (groupByColumnNames === null || groupByColumnNames === void 0 ? void 0 : groupByColumnNames.length) {
351
+ // do the heavy-lifting in done()
352
+ quantReducer = {
353
+ initialValue: {},
354
+ reducer: (nodeValueMap, rowValue, rowNode, rowIndex) => {
355
+ if (isUndefinedValue(rowValue)) {
356
+ return nodeValueMap;
357
+ }
358
+ nodeValueMap[rowNode.id] = rowValue;
359
+ return nodeValueMap;
360
+ },
361
+ done: (nodeValueMap, groupItems) => {
362
+ var _a, _b;
363
+ const populationSize = (_b = (_a = groupItems === null || groupItems === void 0 ? void 0 : groupItems.filter((rowNode) => {
364
+ const rowValue = context.adaptableApi.gridApi.getRawValueFromRowNode(rowNode, quantileColumnName);
365
+ return isDefinedValue(rowValue);
366
+ })) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
367
+ const bucketsMap = new Map();
368
+ for (let step = 1; step <= qNumber; step++) {
369
+ bucketsMap.set(step, populationSize * (step / qNumber));
370
+ }
371
+ const indexBucketMap = new Map();
372
+ for (let populationIndex = 0; populationIndex < populationSize; populationIndex++) {
373
+ for (let quantIndex = 1; quantIndex <= qNumber; quantIndex++) {
374
+ if (bucketsMap.get(quantIndex) < populationIndex + 1) {
375
+ continue;
376
+ }
377
+ else {
378
+ indexBucketMap.set(populationIndex, quantIndex);
379
+ break;
380
+ }
381
+ }
382
+ }
383
+ const groupedRowBucketMap = {};
384
+ groupItems.forEach((subgroupRowNode, subgroupRowIndex) => {
385
+ const subgroupRowValue = nodeValueMap[subgroupRowNode.id];
386
+ if (subgroupRowValue) {
387
+ groupedRowBucketMap[subgroupRowValue] = indexBucketMap.get(subgroupRowIndex);
388
+ }
389
+ });
390
+ return groupedRowBucketMap;
391
+ },
392
+ };
407
393
  }
408
- if ((_a = aggregationParameter.value.aggregationParams.groupBy) === null || _a === void 0 ? void 0 : _a.length) {
409
- throw new ExpressionEvaluationError_1.ExpressionEvaluationError('CUMUL', `supports only aggregations without any grouping (GROUP_BY clauses)`);
394
+ else {
395
+ // in case of non-grouped quantiles, we are able to calculate the buckets beforehand (which is the most efficient)
396
+ const populationSize = (_c = (_b = (_a = context.adaptableApi.gridApi.getAllRowNodes()) === null || _a === void 0 ? void 0 : _a.filter((rowNode) => {
397
+ const rowValue = context.adaptableApi.gridApi.getRawValueFromRowNode(rowNode, quantileColumnName);
398
+ return isDefinedValue(rowValue);
399
+ })) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0;
400
+ const bucketsMap = new Map();
401
+ for (let step = 1; step <= qNumber; step++) {
402
+ bucketsMap.set(step, populationSize * (step / qNumber));
403
+ }
404
+ const indexBucketMap = new Map();
405
+ for (let populationIndex = 0; populationIndex < populationSize; populationIndex++) {
406
+ for (let quantIndex = 1; quantIndex <= qNumber; quantIndex++) {
407
+ if (bucketsMap.get(quantIndex) < populationIndex + 1) {
408
+ continue;
409
+ }
410
+ else {
411
+ indexBucketMap.set(populationIndex, quantIndex);
412
+ break;
413
+ }
414
+ }
415
+ }
416
+ quantReducer = {
417
+ initialValue: {},
418
+ reducer: (rowBucketMap, rowValue, rowNode, rowIndex) => {
419
+ if (isUndefinedValue(rowValue)) {
420
+ return rowBucketMap;
421
+ }
422
+ rowBucketMap[rowValue] = indexBucketMap.get(rowIndex);
423
+ return rowBucketMap;
424
+ },
425
+ };
410
426
  }
411
- const overColumnParameter = expressionFunctionUtils_1.extractParameter('CUMUL', 'operand', ['OVER'], args);
412
- aggregationParameter.value.cumulateOver = overColumnParameter.value;
427
+ const aggregationExpressionEvaluation = {
428
+ sortByColumn: quantileColumnName,
429
+ rowFilterFn: (rowNode) => {
430
+ const rowValue = context.adaptableApi.gridApi.getRawValueFromRowNode(rowNode, quantileColumnName);
431
+ return isDefinedValue(rowValue);
432
+ },
433
+ aggregationParams: {
434
+ reducers: {
435
+ QUANT: Object.assign({ name: 'QUANT', field: quantileColumnName }, quantReducer),
436
+ },
437
+ },
438
+ rowValueGetter: (rowNode, rowBucketMap) => {
439
+ const rowValue = context.adaptableApi.gridApi.getRawValueFromRowNode(rowNode, quantileColumnName);
440
+ if (rowValue == null) {
441
+ return;
442
+ }
443
+ return rowBucketMap[rowValue];
444
+ },
445
+ columnDependencies: [quantileColumnName],
446
+ };
447
+ addGroupByParams(groupByOperand === null || groupByOperand === void 0 ? void 0 : groupByOperand.value, aggregationExpressionEvaluation);
413
448
  const result = {
414
- name: 'CUMUL',
415
- type: 'aggregation',
416
- value: aggregationParameter.value,
449
+ name: 'QUANT',
450
+ type: 'aggregationScalar',
451
+ value: aggregationExpressionEvaluation,
417
452
  };
418
453
  return result;
419
454
  },
420
- description: 'Performs a cumulative aggregation (running total) with the given aggregation operation over a provided column',
421
- signatures: ['CUMUL( aggregationOp: SUM|MIN|MAX, OVER( [colNameB] ))'],
455
+ description: 'Calculates the q-Quantiles of the given group and displays which q-quantile the given value is in\nCommon quantiles are 4-quantile or Quartile, 5-quantile or Quintile, 10-quantile or Decile and 100-quantile or Percentile',
456
+ signatures: [
457
+ 'QUANT( [colName], q: number)',
458
+ 'QUANT( COL(name: string), q: number)',
459
+ 'QUANT( [colName1], q: number, GROUP_BY([colName2]) )',
460
+ ],
422
461
  examples: [
423
- 'CUMUL( SUM([colNameA]), OVER( [colNameB] ))',
424
- 'CUMUL( MIN([colNameA]), OVER( [colNameB] ))',
425
- 'CUMUL( MAX([colNameA]), OVER( [colNameB] ))',
462
+ 'QUANT( [col1], 5)',
463
+ `QUANT( COL('col1'), 100))`,
464
+ 'QUANT( [col1], 4, GROUP_BY([col2]) )',
426
465
  ],
427
466
  },
428
467
  OVER: {
@@ -440,6 +479,35 @@ exports.aggregatedScalarExpressionFunctions = {
440
479
  signatures: ['OVER( [colName] )', 'OVER( COL(name: string))'],
441
480
  examples: ['OVER( [colName] )', `OVER( COL('colName'))`],
442
481
  },
482
+ WEIGHT: {
483
+ handler(args, context) {
484
+ const columnParameter = expressionFunctionUtils_1.extractColumnParameter('WEIGHT', args);
485
+ expressionFunctionUtils_1.validateColumnType(columnParameter.value, ['Number'], 'WEIGHT', context.adaptableApi);
486
+ const result = {
487
+ type: 'operand',
488
+ name: 'WEIGHT',
489
+ value: columnParameter.value,
490
+ };
491
+ return result;
492
+ },
493
+ description: 'Defines a weight for the enclosing AVG(Average) aggregation',
494
+ signatures: ['WEIGHT( [colName] )', 'WEIGHT( COL(name: string))'],
495
+ examples: ['WEIGHT( [colName] )', `WEIGHT( COL('colName'))`],
496
+ },
497
+ GROUP_BY: {
498
+ handler(args, context) {
499
+ const columnParameters = expressionFunctionUtils_1.extractColumnParameters('GROUP_BY', args);
500
+ const result = {
501
+ type: 'operand',
502
+ name: 'GROUP_BY',
503
+ value: columnParameters.map((columnParam) => columnParam.value),
504
+ };
505
+ return result;
506
+ },
507
+ description: 'Groups an aggregation operation within the rows that have the same value in the specified column',
508
+ signatures: ['GROUP_BY( [colName] )', 'GROUP_BY( COL(name: string))'],
509
+ examples: ['GROUP_BY( [colName] )', `GROUP_BY( COL('colName'))`],
510
+ },
443
511
  COL: {
444
512
  handler(args, context) {
445
513
  return expressionFunctionUtils_1.handleColumnFunction(args, context);
@@ -449,15 +517,150 @@ exports.aggregatedScalarExpressionFunctions = {
449
517
  examples: ['[col1]', 'COL("col1")'],
450
518
  },
451
519
  };
452
- // !! mutates expressionEvaluation
453
- const addGroupByParams = (groupByParameter, expressionEvaluation) => {
454
- if (groupByParameter) {
455
- const groupByColumnName = groupByParameter.value;
456
- expressionEvaluation.aggregationParams.groupBy = [
457
- {
458
- field: groupByColumnName,
520
+ const mapAggregationToCumulation = (aggregationParameter, overColumnParameter, context) => {
521
+ const aggregationEvaluation = aggregationParameter.value;
522
+ const aggregationReducer = aggregationEvaluation.aggregationParams.reducers[aggregationParameter.name];
523
+ const cumulationAggregationReducer = aggregationParameter.name === 'SUM'
524
+ ? {
525
+ name: 'CUMUL_SUM',
526
+ field: aggregationReducer.field,
527
+ initialValue: {
528
+ currentValue: aggregationReducer.initialValue,
529
+ cumulatedValues: {},
459
530
  },
460
- ];
461
- expressionEvaluation.columnDependencies.push(groupByColumnName);
531
+ reducer: (cumulationBag, rowValue, rowNode) => {
532
+ if (isDefinedValue(rowValue)) {
533
+ cumulationBag.currentValue = cumulationBag.currentValue + rowValue;
534
+ }
535
+ cumulationBag.cumulatedValues[rowNode.id] = cumulationBag.currentValue;
536
+ return cumulationBag;
537
+ },
538
+ }
539
+ : aggregationParameter.name === 'MIN'
540
+ ? {
541
+ name: 'CUMUL_MIN',
542
+ field: aggregationReducer.field,
543
+ initialValue: {
544
+ currentValue: aggregationReducer.initialValue,
545
+ cumulatedValues: {},
546
+ },
547
+ reducer: (cumulationBag, rowValue, rowNode) => {
548
+ if (isDefinedValue(rowValue) && rowValue < cumulationBag.currentValue) {
549
+ cumulationBag.currentValue = rowValue;
550
+ }
551
+ if (cumulationBag.currentValue !== aggregationReducer.initialValue) {
552
+ cumulationBag.cumulatedValues[rowNode.id] = cumulationBag.currentValue;
553
+ }
554
+ return cumulationBag;
555
+ },
556
+ }
557
+ : aggregationParameter.name === 'MAX'
558
+ ? {
559
+ name: 'CUMUL_MAX',
560
+ field: aggregationReducer.field,
561
+ initialValue: {
562
+ currentValue: aggregationReducer.initialValue,
563
+ cumulatedValues: {},
564
+ },
565
+ reducer: (cumulationBag, rowValue, rowNode) => {
566
+ if (isDefinedValue(rowValue) && rowValue > cumulationBag.currentValue) {
567
+ cumulationBag.currentValue = rowValue;
568
+ }
569
+ if (cumulationBag.currentValue !== aggregationReducer.initialValue) {
570
+ cumulationBag.cumulatedValues[rowNode.id] = cumulationBag.currentValue;
571
+ }
572
+ return cumulationBag;
573
+ },
574
+ }
575
+ : aggregationParameter.name === 'AVG'
576
+ ? {
577
+ name: 'CUMUL_AVG',
578
+ field: aggregationReducer.field,
579
+ initialValue: {
580
+ currentValue: 0,
581
+ cumulatedValues: {},
582
+ numberOfCumulatedValues: 0,
583
+ },
584
+ reducer: (cumulationBag, rowValue, rowNode) => {
585
+ var _a, _b;
586
+ if (isDefinedValue(rowValue)) {
587
+ if ((_a = aggregationEvaluation.context) === null || _a === void 0 ? void 0 : _a.weightParam) {
588
+ // weighted average
589
+ const weightValue = (_b = context.adaptableApi.gridApi.getRawValueFromRowNode(rowNode, aggregationEvaluation.context.weightParam.value)) !== null && _b !== void 0 ? _b : 0;
590
+ cumulationBag.currentValue = cumulationBag.currentValue + rowValue * weightValue;
591
+ cumulationBag.numberOfCumulatedValues =
592
+ cumulationBag.numberOfCumulatedValues + weightValue;
593
+ }
594
+ else {
595
+ cumulationBag.currentValue = cumulationBag.currentValue + rowValue;
596
+ cumulationBag.numberOfCumulatedValues = cumulationBag.numberOfCumulatedValues + 1;
597
+ }
598
+ }
599
+ if (cumulationBag.numberOfCumulatedValues !== 0) {
600
+ cumulationBag.cumulatedValues[rowNode.id] =
601
+ cumulationBag.currentValue / cumulationBag.numberOfCumulatedValues;
602
+ }
603
+ return cumulationBag;
604
+ },
605
+ }
606
+ : aggregationParameter.name === 'PERCENTAGE'
607
+ ? {
608
+ name: 'CUMUL_PERCENTAGE',
609
+ field: aggregationReducer.field,
610
+ initialValue: {
611
+ currentValue: aggregationReducer.initialValue,
612
+ cumulatedValues: {},
613
+ },
614
+ reducer: (cumulationBag, rowValue, rowNode) => {
615
+ if (isDefinedValue(rowValue)) {
616
+ cumulationBag.currentValue = cumulationBag.currentValue + rowValue;
617
+ }
618
+ cumulationBag.cumulatedValues[rowNode.id] = cumulationBag.currentValue;
619
+ return cumulationBag;
620
+ },
621
+ done: (cumulationBag) => {
622
+ cumulationBag.totalAggregationValue = cumulationBag.currentValue;
623
+ return cumulationBag;
624
+ },
625
+ }
626
+ : null;
627
+ const rowValueGetter = aggregationParameter.name === 'PERCENTAGE'
628
+ ? (rowNode, cumulationBag) => {
629
+ const cumulatedSum = cumulationBag.cumulatedValues[rowNode.id];
630
+ const totalValue = cumulationBag.totalAggregationValue;
631
+ return (cumulatedSum / totalValue) * 100;
632
+ }
633
+ : (rowNode, aggregatedValue) => {
634
+ return aggregatedValue.cumulatedValues[rowNode.id];
635
+ };
636
+ const cumulationExpressionEvaluation = {
637
+ sortByColumn: overColumnParameter.value,
638
+ aggregationParams: {
639
+ reducers: {
640
+ CUMUL: cumulationAggregationReducer,
641
+ },
642
+ groupBy: aggregationEvaluation.aggregationParams.groupBy,
643
+ },
644
+ rowValueGetter,
645
+ columnDependencies: [
646
+ ...new Set([...aggregationEvaluation.columnDependencies, overColumnParameter.value]),
647
+ ],
648
+ rowFilterFn: aggregationEvaluation.rowFilterFn,
649
+ };
650
+ return cumulationExpressionEvaluation;
651
+ };
652
+ // !! mutates expressionEvaluation
653
+ const addGroupByParams = (groupByColumnNames, expressionEvaluation) => {
654
+ if (groupByColumnNames === null || groupByColumnNames === void 0 ? void 0 : groupByColumnNames.length) {
655
+ expressionEvaluation.aggregationParams.groupBy = groupByColumnNames.map((columnName) => ({
656
+ field: columnName,
657
+ }));
658
+ expressionEvaluation.columnDependencies.push(...groupByColumnNames);
462
659
  }
463
660
  };
661
+ const isUndefinedValue = (input) => {
662
+ return input == undefined || input === '';
663
+ };
664
+ const isDefinedValue = (input) => {
665
+ return !isUndefinedValue(input);
666
+ };