@hisptz/dhis2-analytics 1.0.10 → 1.0.11

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 (154) hide show
  1. package/build/cjs/components/ChartAnalytics/ChartAnalytics.stories.js +1 -1
  2. package/build/cjs/components/CircularProgressDashboard/CircularProgressIndicator.stories.js +1 -1
  3. package/build/cjs/components/Map/Map.stories.js +1 -1
  4. package/build/cjs/components/Map/components/EarthEngineLayerConfiguration/EarthEngineLayerConfigModal.stories.js +1 -1
  5. package/build/cjs/components/Map/components/EarthEngineLayerConfiguration/EarthEngineLayerConfiguration.stories.js +1 -1
  6. package/build/cjs/components/Map/components/MapProvider/components/MapLayerProvider/hooks/index.js +8 -1
  7. package/build/cjs/components/Map/components/ThematicLayerConfiguration/ThematicLayerConfigModal.stories.js +1 -1
  8. package/build/cjs/components/Map/components/ThematicLayerConfiguration/ThematicLayerConfiguration.stories.js +1 -1
  9. package/build/cjs/components/PivotTable/PivotTable.stories.js +277 -0
  10. package/build/cjs/components/PivotTable/components/AssignedCategoriesIcon/index.js +32 -0
  11. package/build/cjs/components/PivotTable/components/PivotTable.js +60 -0
  12. package/build/cjs/components/PivotTable/components/PivotTableBody.js +41 -0
  13. package/build/cjs/components/PivotTable/components/PivotTableCell.js +40 -0
  14. package/build/cjs/components/PivotTable/components/PivotTableClippedAxis.js +26 -0
  15. package/build/cjs/components/PivotTable/components/PivotTableColumnHeaderCell.js +71 -0
  16. package/build/cjs/components/PivotTable/components/PivotTableColumnHeaders.js +60 -0
  17. package/build/cjs/components/PivotTable/components/PivotTableContainer.js +33 -0
  18. package/build/cjs/components/PivotTable/components/PivotTableDimensionLabelCell.js +77 -0
  19. package/build/cjs/components/PivotTable/components/PivotTableEmptyCell.js +22 -0
  20. package/build/cjs/components/PivotTable/components/PivotTableEmptyRow.js +33 -0
  21. package/build/cjs/components/PivotTable/components/PivotTableEngineContext.js +25 -0
  22. package/build/cjs/components/PivotTable/components/PivotTableHead.js +35 -0
  23. package/build/cjs/components/PivotTable/components/PivotTableHeaderCell.js +37 -0
  24. package/build/cjs/components/PivotTable/components/PivotTableRow.js +65 -0
  25. package/build/cjs/components/PivotTable/components/PivotTableRowHeaderCell.js +49 -0
  26. package/build/cjs/components/PivotTable/components/PivotTableTitleRow.js +52 -0
  27. package/build/cjs/components/PivotTable/components/PivotTableTitleRows.js +46 -0
  28. package/build/cjs/components/PivotTable/components/PivotTableValueCell.js +69 -0
  29. package/build/cjs/components/PivotTable/constants/dataTypes.js +129 -0
  30. package/build/cjs/components/PivotTable/constants/pivotTable.js +64 -0
  31. package/build/cjs/components/PivotTable/constants/predefinedDimensions.js +62 -0
  32. package/build/cjs/components/PivotTable/constants/valueTypes.js +55 -0
  33. package/build/cjs/components/PivotTable/data/column-data.json +210 -0
  34. package/build/cjs/components/PivotTable/hooks/useParentSize.js +41 -0
  35. package/build/cjs/components/PivotTable/hooks/useScrollPosition.js +38 -0
  36. package/build/cjs/components/PivotTable/hooks/useSortableColumns.js +34 -0
  37. package/build/cjs/components/PivotTable/hooks/useTableClipping.js +53 -0
  38. package/build/cjs/components/PivotTable/index.js +47 -0
  39. package/build/cjs/components/PivotTable/interfaces/index.js +1 -0
  40. package/build/cjs/components/PivotTable/services/adaptiveClippingController.js +197 -0
  41. package/build/cjs/components/PivotTable/services/engine.js +901 -0
  42. package/build/cjs/components/PivotTable/utils/getOuLevelAndGroupText.js +71 -0
  43. package/build/cjs/components/PivotTable/utils/index.js +322 -0
  44. package/build/cjs/components/PivotTable/utils/isColorBright.js +29 -0
  45. package/build/cjs/components/PivotTable/utils/layout/dimension.js +61 -0
  46. package/build/cjs/components/PivotTable/utils/layout/dimensionGetId.js +12 -0
  47. package/build/cjs/components/PivotTable/utils/layout/dimensionGetItems.js +12 -0
  48. package/build/cjs/components/PivotTable/utils/layout/dimensionIs.js +9 -0
  49. package/build/cjs/components/PivotTable/utils/layout/dimensionIsEmpty.js +9 -0
  50. package/build/cjs/components/PivotTable/utils/layout/dimensionIsValid.js +25 -0
  51. package/build/cjs/components/PivotTable/utils/legend.js +40 -0
  52. package/build/cjs/components/PivotTable/utils/ouIdHelper/index.js +27 -0
  53. package/build/cjs/components/SingleValueContainer/SingleValueContainer.stories.js +1 -1
  54. package/build/cjs/index.js +11 -0
  55. package/build/cjs/locales/en/translations.json +33 -0
  56. package/build/es/components/ChartAnalytics/ChartAnalytics.stories.js +1 -1
  57. package/build/es/components/CircularProgressDashboard/CircularProgressIndicator.stories.js +1 -1
  58. package/build/es/components/Map/Map.stories.js +1 -1
  59. package/build/es/components/Map/components/EarthEngineLayerConfiguration/EarthEngineLayerConfigModal.stories.js +1 -1
  60. package/build/es/components/Map/components/EarthEngineLayerConfiguration/EarthEngineLayerConfiguration.stories.js +1 -1
  61. package/build/es/components/Map/components/MapProvider/components/MapLayerProvider/hooks/index.js +8 -1
  62. package/build/es/components/Map/components/ThematicLayerConfiguration/ThematicLayerConfigModal.stories.js +1 -1
  63. package/build/es/components/Map/components/ThematicLayerConfiguration/ThematicLayerConfiguration.stories.js +1 -1
  64. package/build/es/components/PivotTable/PivotTable.stories.js +268 -0
  65. package/build/es/components/PivotTable/components/AssignedCategoriesIcon/index.js +24 -0
  66. package/build/es/components/PivotTable/components/PivotTable.js +51 -0
  67. package/build/es/components/PivotTable/components/PivotTableBody.js +33 -0
  68. package/build/es/components/PivotTable/components/PivotTableCell.js +32 -0
  69. package/build/es/components/PivotTable/components/PivotTableClippedAxis.js +18 -0
  70. package/build/es/components/PivotTable/components/PivotTableColumnHeaderCell.js +62 -0
  71. package/build/es/components/PivotTable/components/PivotTableColumnHeaders.js +52 -0
  72. package/build/es/components/PivotTable/components/PivotTableContainer.js +25 -0
  73. package/build/es/components/PivotTable/components/PivotTableDimensionLabelCell.js +68 -0
  74. package/build/es/components/PivotTable/components/PivotTableEmptyCell.js +14 -0
  75. package/build/es/components/PivotTable/components/PivotTableEmptyRow.js +25 -0
  76. package/build/es/components/PivotTable/components/PivotTableEngineContext.js +14 -0
  77. package/build/es/components/PivotTable/components/PivotTableHead.js +27 -0
  78. package/build/es/components/PivotTable/components/PivotTableHeaderCell.js +29 -0
  79. package/build/es/components/PivotTable/components/PivotTableRow.js +57 -0
  80. package/build/es/components/PivotTable/components/PivotTableRowHeaderCell.js +41 -0
  81. package/build/es/components/PivotTable/components/PivotTableTitleRow.js +42 -0
  82. package/build/es/components/PivotTable/components/PivotTableTitleRows.js +37 -0
  83. package/build/es/components/PivotTable/components/PivotTableValueCell.js +60 -0
  84. package/build/es/components/PivotTable/constants/dataTypes.js +98 -0
  85. package/build/es/components/PivotTable/constants/pivotTable.js +29 -0
  86. package/build/es/components/PivotTable/constants/predefinedDimensions.js +44 -0
  87. package/build/es/components/PivotTable/constants/valueTypes.js +27 -0
  88. package/build/es/components/PivotTable/data/column-data.json +210 -0
  89. package/build/es/components/PivotTable/hooks/useParentSize.js +33 -0
  90. package/build/es/components/PivotTable/hooks/useScrollPosition.js +30 -0
  91. package/build/es/components/PivotTable/hooks/useSortableColumns.js +27 -0
  92. package/build/es/components/PivotTable/hooks/useTableClipping.js +46 -0
  93. package/build/es/components/PivotTable/index.js +26 -0
  94. package/build/es/components/PivotTable/interfaces/index.js +1 -0
  95. package/build/es/components/PivotTable/services/adaptiveClippingController.js +191 -0
  96. package/build/es/components/PivotTable/services/engine.js +894 -0
  97. package/build/es/components/PivotTable/utils/getOuLevelAndGroupText.js +63 -0
  98. package/build/es/components/PivotTable/utils/index.js +309 -0
  99. package/build/es/components/PivotTable/utils/isColorBright.js +22 -0
  100. package/build/es/components/PivotTable/utils/layout/dimension.js +48 -0
  101. package/build/es/components/PivotTable/utils/layout/dimensionGetId.js +5 -0
  102. package/build/es/components/PivotTable/utils/layout/dimensionGetItems.js +5 -0
  103. package/build/es/components/PivotTable/utils/layout/dimensionIs.js +2 -0
  104. package/build/es/components/PivotTable/utils/layout/dimensionIsEmpty.js +2 -0
  105. package/build/es/components/PivotTable/utils/layout/dimensionIsValid.js +18 -0
  106. package/build/es/components/PivotTable/utils/legend.js +27 -0
  107. package/build/es/components/PivotTable/utils/ouIdHelper/index.js +17 -0
  108. package/build/es/components/SingleValueContainer/SingleValueContainer.stories.js +1 -1
  109. package/build/es/index.js +1 -0
  110. package/build/es/locales/en/translations.json +33 -0
  111. package/build/types/components/PivotTable/components/AssignedCategoriesIcon/index.d.ts +3 -0
  112. package/build/types/components/PivotTable/components/PivotTable.d.ts +12 -0
  113. package/build/types/components/PivotTable/components/PivotTableBody.d.ts +7 -0
  114. package/build/types/components/PivotTable/components/PivotTableCell.d.ts +17 -0
  115. package/build/types/components/PivotTable/components/PivotTableClippedAxis.d.ts +7 -0
  116. package/build/types/components/PivotTable/components/PivotTableColumnHeaderCell.d.ts +13 -0
  117. package/build/types/components/PivotTable/components/PivotTableColumnHeaders.d.ts +11 -0
  118. package/build/types/components/PivotTable/components/PivotTableContainer.d.ts +8 -0
  119. package/build/types/components/PivotTable/components/PivotTableDimensionLabelCell.d.ts +13 -0
  120. package/build/types/components/PivotTable/components/PivotTableEmptyCell.d.ts +7 -0
  121. package/build/types/components/PivotTable/components/PivotTableEmptyRow.d.ts +5 -0
  122. package/build/types/components/PivotTable/components/PivotTableEngineContext.d.ts +8 -0
  123. package/build/types/components/PivotTable/components/PivotTableHead.d.ts +21 -0
  124. package/build/types/components/PivotTable/components/PivotTableHeaderCell.d.ts +22 -0
  125. package/build/types/components/PivotTable/components/PivotTableRow.d.ts +19 -0
  126. package/build/types/components/PivotTable/components/PivotTableRowHeaderCell.d.ts +8 -0
  127. package/build/types/components/PivotTable/components/PivotTableTitleRow.d.ts +21 -0
  128. package/build/types/components/PivotTable/components/PivotTableTitleRows.d.ts +12 -0
  129. package/build/types/components/PivotTable/components/PivotTableValueCell.d.ts +8 -0
  130. package/build/types/components/PivotTable/constants/dataTypes.d.ts +90 -0
  131. package/build/types/components/PivotTable/constants/pivotTable.d.ts +29 -0
  132. package/build/types/components/PivotTable/constants/predefinedDimensions.d.ts +80 -0
  133. package/build/types/components/PivotTable/constants/valueTypes.d.ts +22 -0
  134. package/build/types/components/PivotTable/hooks/useParentSize.d.ts +8 -0
  135. package/build/types/components/PivotTable/hooks/useScrollPosition.d.ts +5 -0
  136. package/build/types/components/PivotTable/hooks/useSortableColumns.d.ts +8 -0
  137. package/build/types/components/PivotTable/hooks/useTableClipping.d.ts +24 -0
  138. package/build/types/components/PivotTable/index.d.ts +26 -0
  139. package/build/types/components/PivotTable/interfaces/index.d.ts +72 -0
  140. package/build/types/components/PivotTable/services/adaptiveClippingController.d.ts +44 -0
  141. package/build/types/components/PivotTable/services/engine.d.ts +252 -0
  142. package/build/types/components/PivotTable/utils/getOuLevelAndGroupText.d.ts +1 -0
  143. package/build/types/components/PivotTable/utils/index.d.ts +38 -0
  144. package/build/types/components/PivotTable/utils/isColorBright.d.ts +1 -0
  145. package/build/types/components/PivotTable/utils/layout/dimension.d.ts +35 -0
  146. package/build/types/components/PivotTable/utils/layout/dimensionGetId.d.ts +3 -0
  147. package/build/types/components/PivotTable/utils/layout/dimensionGetItems.d.ts +3 -0
  148. package/build/types/components/PivotTable/utils/layout/dimensionIs.d.ts +1 -0
  149. package/build/types/components/PivotTable/utils/layout/dimensionIsEmpty.d.ts +3 -0
  150. package/build/types/components/PivotTable/utils/layout/dimensionIsValid.d.ts +5 -0
  151. package/build/types/components/PivotTable/utils/legend.d.ts +11 -0
  152. package/build/types/components/PivotTable/utils/ouIdHelper/index.d.ts +10 -0
  153. package/build/types/index.d.ts +1 -0
  154. package/package.json +6 -3
@@ -0,0 +1,894 @@
1
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
3
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
4
+ // @ts-nocheck
5
+ import times from 'lodash/times';
6
+ import { DIMENSION_TYPE_DATA, DIMENSION_TYPE_DATA_ELEMENT_GROUP_SET, DIMENSION_TYPE_ORGANISATION_UNIT, DIMENSION_TYPE_PERIOD } from '../constants/dataTypes';
7
+ import { DIMENSION_ID_ORGUNIT } from '../constants/predefinedDimensions.js';
8
+ import { parseValue, renderValue } from '../utils';
9
+ import { VALUE_TYPE_NUMBER, VALUE_TYPE_TEXT } from '../constants/valueTypes.js';
10
+ import { AdaptiveClippingController } from './adaptiveClippingController';
11
+ import { AGGREGATE_TYPE_AVERAGE, AGGREGATE_TYPE_NA, AGGREGATE_TYPE_SUM, CELL_TYPE_SUBTOTAL, CELL_TYPE_TOTAL, CELL_TYPE_VALUE, DISPLAY_DENSITY_OPTION_COMFORTABLE, DISPLAY_DENSITY_OPTION_COMPACT, DISPLAY_DENSITY_OPTION_NORMAL, DISPLAY_DENSITY_PADDING_COMFORTABLE, DISPLAY_DENSITY_PADDING_COMPACT, DISPLAY_DENSITY_PADDING_NORMAL, FONT_SIZE_LARGE, FONT_SIZE_NORMAL, FONT_SIZE_OPTION_LARGE, FONT_SIZE_OPTION_NORMAL, FONT_SIZE_OPTION_SMALL, FONT_SIZE_SMALL, NUMBER_TYPE_COLUMN_PERCENTAGE, NUMBER_TYPE_ROW_PERCENTAGE, NUMBER_TYPE_VALUE, SORT_ORDER_ASCENDING, SORT_ORDER_DESCENDING } from '../constants/pivotTable';
12
+ import { compact } from "lodash";
13
+ const dataFields = ['value', 'numerator', 'denominator', 'factor', 'multiplier', 'divisor'];
14
+ const defaultOptions = {
15
+ hideEmptyColumns: false,
16
+ hideEmptyRows: false,
17
+ showRowTotals: false,
18
+ showColumnTotals: false,
19
+ showRowSubtotals: false,
20
+ showColumnSubtotals: false,
21
+ fixColumnHeaders: false,
22
+ fixRowHeaders: false
23
+ };
24
+ const defaultVisualizationProps = {
25
+ fontSize: FONT_SIZE_OPTION_NORMAL,
26
+ displayDensity: DISPLAY_DENSITY_OPTION_NORMAL
27
+ };
28
+ const isDxDimension = dimensionItem => [DIMENSION_TYPE_DATA, DIMENSION_TYPE_DATA_ELEMENT_GROUP_SET].includes(dimensionItem.dimensionType);
29
+ const countFromDisaggregates = list => {
30
+ let count = 1;
31
+ list.forEach(x => {
32
+ count *= x.items.length;
33
+ });
34
+ return count;
35
+ };
36
+ const addSize = list => {
37
+ const reversedList = list.slice().reverse();
38
+ reversedList.forEach((level, idx) => {
39
+ var _lastLevel$count, _lastLevel$size;
40
+ // Start at the "leaf" disaggregate
41
+ const lastLevel = reversedList[idx - 1];
42
+ level.size = lastLevel ? ((_lastLevel$count = lastLevel === null || lastLevel === void 0 ? void 0 : lastLevel.count) !== null && _lastLevel$count !== void 0 ? _lastLevel$count : 1) * ((_lastLevel$size = lastLevel === null || lastLevel === void 0 ? void 0 : lastLevel.size) !== null && _lastLevel$size !== void 0 ? _lastLevel$size : 1) : 1;
43
+ });
44
+ };
45
+ const listByDimension = list => list.reduce((all, item) => {
46
+ all[item.dimension] = item;
47
+ return all;
48
+ }, {});
49
+ const sortByHierarchy = items => {
50
+ items.sort((a, b) => {
51
+ if (!a.hierarchy || !b.hierarchy) {
52
+ return 0;
53
+ }
54
+ return a.hierarchy.join('/').localeCompare(b.hierarchy.join('/'));
55
+ });
56
+ };
57
+ const buildDimensionLookup = (visualization, metadata, headers) => {
58
+ var _visualization$rows$m;
59
+ if (!metadata) {
60
+ return;
61
+ }
62
+ const rows = (_visualization$rows$m = visualization.rows.map(row => {
63
+ var _metadata$dimensions, _metadata$dimensions2, _metadata$dimensions$, _metadata$dimensions3;
64
+ return {
65
+ dimension: row.dimension,
66
+ meta: metadata.items[row.dimension],
67
+ count: (_metadata$dimensions = metadata.dimensions[row.dimension]) === null || _metadata$dimensions === void 0 ? void 0 : _metadata$dimensions.length,
68
+ itemIds: (_metadata$dimensions2 = metadata.dimensions[row.dimension]) !== null && _metadata$dimensions2 !== void 0 ? _metadata$dimensions2 : [],
69
+ items: (_metadata$dimensions$ = (_metadata$dimensions3 = metadata.dimensions[row.dimension]) === null || _metadata$dimensions3 === void 0 ? void 0 : _metadata$dimensions3.map(item => metadata.items[item])) !== null && _metadata$dimensions$ !== void 0 ? _metadata$dimensions$ : [],
70
+ isDxDimension: isDxDimension(metadata.items[row.dimension]),
71
+ position: 'row'
72
+ };
73
+ })) !== null && _visualization$rows$m !== void 0 ? _visualization$rows$m : [];
74
+ const columns = visualization.columns.map(column => {
75
+ var _metadata$dimensions4, _metadata$dimensions5, _metadata$dimensions$2, _metadata$dimensions6;
76
+ return {
77
+ dimension: column.dimension,
78
+ meta: metadata.items[column.dimension],
79
+ count: (_metadata$dimensions4 = metadata.dimensions[column.dimension]) === null || _metadata$dimensions4 === void 0 ? void 0 : _metadata$dimensions4.length,
80
+ itemIds: (_metadata$dimensions5 = metadata.dimensions[column.dimension]) !== null && _metadata$dimensions5 !== void 0 ? _metadata$dimensions5 : [],
81
+ items: (_metadata$dimensions$2 = (_metadata$dimensions6 = metadata.dimensions[column.dimension]) === null || _metadata$dimensions6 === void 0 ? void 0 : _metadata$dimensions6.map(item => metadata.items[item])) !== null && _metadata$dimensions$2 !== void 0 ? _metadata$dimensions$2 : [],
82
+ isDxDimension: isDxDimension(metadata.items[column.dimension]),
83
+ position: 'column'
84
+ };
85
+ });
86
+ addSize(rows);
87
+ addSize(columns);
88
+ const allByDimension = {
89
+ ...listByDimension(rows),
90
+ ...listByDimension(columns)
91
+ };
92
+ const headerDimensions = compact(headers === null || headers === void 0 ? void 0 : headers.map(header => allByDimension[header.name]));
93
+ const rowHeaders = headerDimensions.map((_, idx) => idx).filter(idx => headerDimensions[idx] && headerDimensions[idx].position === 'row');
94
+ const columnHeaders = headerDimensions.map((_, idx) => idx).filter(idx => headerDimensions[idx] && headerDimensions[idx].position === 'column');
95
+ const dataHeaders = dataFields.reduce((out, field) => {
96
+ out[field] = headers === null || headers === void 0 ? void 0 : headers.findIndex(header => header.name === field);
97
+ return out;
98
+ }, {});
99
+ const ouDimension = allByDimension[DIMENSION_ID_ORGUNIT];
100
+ if (visualization.showHierarchy && metadata.ouNameHierarchy && ouDimension) {
101
+ ouDimension.items.forEach(ou => {
102
+ const hierarchy = metadata.ouNameHierarchy[ou.uid];
103
+ if (hierarchy) {
104
+ ou.hierarchy = hierarchy.split('/').filter(x => x.length);
105
+ }
106
+ });
107
+ sortByHierarchy(ouDimension.items);
108
+ ouDimension.itemIds = ouDimension.items.map(item => item.uid);
109
+ }
110
+ return {
111
+ rows,
112
+ columns,
113
+ allByDimension,
114
+ headerDimensions,
115
+ rowHeaders,
116
+ columnHeaders,
117
+ dataHeaders
118
+ };
119
+ };
120
+ const lookup = (dataRow, dimensionLookup, _ref) => {
121
+ let {
122
+ doColumnSubtotals,
123
+ doRowSubtotals
124
+ } = _ref;
125
+ let row = 0;
126
+ for (const headerIndex of dimensionLookup.rowHeaders) {
127
+ const idx = dimensionLookup.headerDimensions[headerIndex].itemIds.indexOf(dataRow[headerIndex]);
128
+ if (idx === -1) {
129
+ return undefined;
130
+ }
131
+ const size = dimensionLookup.headerDimensions[headerIndex].size;
132
+ row += idx * size;
133
+ }
134
+ if (doColumnSubtotals) {
135
+ row += Math.floor(row / dimensionLookup.rows[0].size);
136
+ }
137
+ let column = 0;
138
+ for (const headerIndex of dimensionLookup.columnHeaders) {
139
+ const idx = dimensionLookup.headerDimensions[headerIndex].itemIds.indexOf(dataRow[headerIndex]);
140
+ if (idx === -1) {
141
+ return undefined;
142
+ }
143
+ const size = dimensionLookup.headerDimensions[headerIndex].size;
144
+ column += idx * size;
145
+ }
146
+ if (doRowSubtotals) {
147
+ column += Math.floor(column / dimensionLookup.columns[0].size);
148
+ }
149
+ return {
150
+ column,
151
+ row
152
+ };
153
+ };
154
+ const applyTotalAggregationType = (_ref2, overrideTotalAggregationType) => {
155
+ let {
156
+ totalAggregationType,
157
+ value,
158
+ numerator,
159
+ denominator,
160
+ multiplier,
161
+ divisor
162
+ } = _ref2;
163
+ switch (overrideTotalAggregationType || totalAggregationType) {
164
+ case AGGREGATE_TYPE_NA:
165
+ return 'N/A';
166
+ case AGGREGATE_TYPE_AVERAGE:
167
+ return (numerator || value) * multiplier / (denominator * divisor || 1);
168
+ case AGGREGATE_TYPE_SUM:
169
+ default:
170
+ return value;
171
+ }
172
+ };
173
+ export class PivotTableEngine {
174
+ constructor(visualization, data) {
175
+ var _this$dimensionLookup, _this$dimensionLookup2, _this$dimensionLookup3, _this$dimensionLookup4, _this$dimensionLookup5, _this$dimensionLookup6, _this$dimensionLookup7, _this$dimensionLookup8, _this$dimensionLookup9;
176
+ let legendSets = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
177
+ _defineProperty(this, "visualization", void 0);
178
+ _defineProperty(this, "rawData", void 0);
179
+ _defineProperty(this, "options", void 0);
180
+ _defineProperty(this, "legendSets", void 0);
181
+ _defineProperty(this, "dimensionLookup", void 0);
182
+ _defineProperty(this, "adaptiveClippingController", void 0);
183
+ _defineProperty(this, "columnDepth", 0);
184
+ _defineProperty(this, "rowDepth", 0);
185
+ _defineProperty(this, "height", 0);
186
+ _defineProperty(this, "width", 0);
187
+ _defineProperty(this, "data", []);
188
+ _defineProperty(this, "rowMap", []);
189
+ _defineProperty(this, "columnMap", []);
190
+ _defineProperty(this, "doRowTotals", false);
191
+ _defineProperty(this, "doColumnTotals", false);
192
+ _defineProperty(this, "doRowSubtotals", false);
193
+ _defineProperty(this, "doColumnSubtotals", false);
194
+ _defineProperty(this, "dataWidth", 0);
195
+ _defineProperty(this, "dataHeight", 0);
196
+ _defineProperty(this, "rawDataHeight", 0);
197
+ this.visualization = Object.assign({}, defaultVisualizationProps, visualization);
198
+ this.legendSets = (legendSets || []).reduce((sets, set) => {
199
+ return {
200
+ ...sets,
201
+ [set.id]: set
202
+ };
203
+ }, {});
204
+ this.rawData = data;
205
+ this.dimensionLookup = buildDimensionLookup(this.visualization, this.rawData.metaData, this.rawData.headers);
206
+ this.options = {
207
+ ...defaultOptions,
208
+ showColumnTotals: visualization.colTotals,
209
+ showRowTotals: visualization.rowTotals,
210
+ showColumnSubtotals: visualization.colSubTotals,
211
+ showRowSubtotals: visualization.rowSubTotals,
212
+ hideEmptyColumns: visualization.hideEmptyColumns,
213
+ hideEmptyRows: visualization.hideEmptyRows,
214
+ title: visualization.hideTitle ? undefined : visualization.title,
215
+ subtitle: visualization.hideSubtitle ? undefined : visualization.subtitle,
216
+ // turn on fixed headers only when there are dimensions
217
+ fixColumnHeaders: (_this$dimensionLookup = this.dimensionLookup) !== null && _this$dimensionLookup !== void 0 && _this$dimensionLookup.columns.length ? visualization.fixColumnHeaders : false,
218
+ fixRowHeaders: (_this$dimensionLookup2 = this.dimensionLookup) !== null && _this$dimensionLookup2 !== void 0 && _this$dimensionLookup2.rows.length ? visualization.fixRowHeaders : false
219
+ };
220
+ this.adaptiveClippingController = new AdaptiveClippingController(this);
221
+ const doColumnSubtotals = this.options.showColumnSubtotals && ((_this$dimensionLookup3 = (_this$dimensionLookup4 = this.dimensionLookup) === null || _this$dimensionLookup4 === void 0 ? void 0 : (_this$dimensionLookup5 = _this$dimensionLookup4.rows) === null || _this$dimensionLookup5 === void 0 ? void 0 : _this$dimensionLookup5.length) !== null && _this$dimensionLookup3 !== void 0 ? _this$dimensionLookup3 : 1) > 1;
222
+ const singularRow = ((_this$dimensionLookup6 = this.dimensionLookup) === null || _this$dimensionLookup6 === void 0 ? void 0 : _this$dimensionLookup6.rows.length) === 1 && ((_this$dimensionLookup7 = this.dimensionLookup) === null || _this$dimensionLookup7 === void 0 ? void 0 : _this$dimensionLookup7.rows[0].count) === 1;
223
+ const firstColumnIsSortable = !doColumnSubtotals && !singularRow;
224
+ this.columnDepth = ((_this$dimensionLookup8 = this.dimensionLookup) === null || _this$dimensionLookup8 === void 0 ? void 0 : _this$dimensionLookup8.columns.length) || (this.visualization.showDimensionLabels || firstColumnIsSortable ? 1 : 0);
225
+ this.rowDepth = ((_this$dimensionLookup9 = this.dimensionLookup) === null || _this$dimensionLookup9 === void 0 ? void 0 : _this$dimensionLookup9.rows.length) || (this.visualization.showDimensionLabels ? 1 : 0);
226
+ this.buildMatrix();
227
+ }
228
+ get cellPadding() {
229
+ switch (this.visualization.displayDensity) {
230
+ case DISPLAY_DENSITY_OPTION_COMPACT:
231
+ return DISPLAY_DENSITY_PADDING_COMPACT;
232
+ case DISPLAY_DENSITY_OPTION_COMFORTABLE:
233
+ return DISPLAY_DENSITY_PADDING_COMFORTABLE;
234
+ case DISPLAY_DENSITY_OPTION_NORMAL:
235
+ default:
236
+ return DISPLAY_DENSITY_PADDING_NORMAL;
237
+ }
238
+ }
239
+ get fontSize() {
240
+ switch (this.visualization.fontSize) {
241
+ case FONT_SIZE_OPTION_SMALL:
242
+ return FONT_SIZE_SMALL;
243
+ case FONT_SIZE_OPTION_LARGE:
244
+ return FONT_SIZE_LARGE;
245
+ case FONT_SIZE_OPTION_NORMAL:
246
+ default:
247
+ return FONT_SIZE_NORMAL;
248
+ }
249
+ }
250
+ get scrollIconBuffer() {
251
+ switch (this.visualization.fontSize) {
252
+ case FONT_SIZE_OPTION_SMALL:
253
+ return 11;
254
+ case FONT_SIZE_OPTION_LARGE:
255
+ return 15;
256
+ case FONT_SIZE_OPTION_NORMAL:
257
+ default:
258
+ return 13;
259
+ }
260
+ }
261
+ getRaw(_ref3) {
262
+ var _headers$find, _headers$find2, _this$dimensionLookup10;
263
+ let {
264
+ row,
265
+ column
266
+ } = _ref3;
267
+ const cellType = this.getRawCellType({
268
+ row,
269
+ column
270
+ });
271
+ const dxDimension = this.getRawCellDxDimension({
272
+ row,
273
+ column
274
+ });
275
+ const headers = [...this.getRawRowHeader(row), ...this.getRawColumnHeader(column)];
276
+ const peId = (_headers$find = headers.find(header => (header === null || header === void 0 ? void 0 : header.dimensionItemType) === DIMENSION_TYPE_PERIOD)) === null || _headers$find === void 0 ? void 0 : _headers$find.uid;
277
+ const ouId = (_headers$find2 = headers.find(header => (header === null || header === void 0 ? void 0 : header.dimensionItemType) === DIMENSION_TYPE_ORGANISATION_UNIT)) === null || _headers$find2 === void 0 ? void 0 : _headers$find2.uid;
278
+ if (!this.data[row] || !this.data[row][column]) {
279
+ return {
280
+ cellType,
281
+ empty: true,
282
+ ouId,
283
+ peId
284
+ };
285
+ }
286
+ const dataRow = this.data[row][column];
287
+ let rawValue = cellType === CELL_TYPE_VALUE ? dataRow[(_this$dimensionLookup10 = this.dimensionLookup) === null || _this$dimensionLookup10 === void 0 ? void 0 : _this$dimensionLookup10.dataHeaders.value] : dataRow.value;
288
+ let renderedValue = rawValue;
289
+ const valueType = (dxDimension === null || dxDimension === void 0 ? void 0 : dxDimension.valueType) || VALUE_TYPE_TEXT;
290
+ if (valueType === VALUE_TYPE_NUMBER) {
291
+ rawValue = parseValue(rawValue);
292
+ switch (this.visualization.numberType) {
293
+ case NUMBER_TYPE_ROW_PERCENTAGE:
294
+ renderedValue = rawValue / this.percentageTotals[row].value;
295
+ break;
296
+ case NUMBER_TYPE_COLUMN_PERCENTAGE:
297
+ renderedValue = rawValue / this.percentageTotals[column].value;
298
+ break;
299
+ default:
300
+ break;
301
+ }
302
+ }
303
+ renderedValue = renderValue(renderedValue, valueType, this.visualization);
304
+ return {
305
+ cellType,
306
+ empty: false,
307
+ valueType,
308
+ rawValue,
309
+ renderedValue,
310
+ dxDimension,
311
+ ouId,
312
+ peId
313
+ };
314
+ }
315
+ get(_ref4) {
316
+ let {
317
+ row,
318
+ column
319
+ } = _ref4;
320
+ const mappedRow = this.rowMap[row],
321
+ mappedColumn = this.columnMap[column];
322
+ if (!mappedRow && mappedRow !== 0 || !mappedColumn && mappedColumn !== 0) {
323
+ return undefined;
324
+ }
325
+ return this.getRaw({
326
+ row: mappedRow,
327
+ column: mappedColumn
328
+ });
329
+ }
330
+ getRawCellType(_ref5) {
331
+ let {
332
+ row,
333
+ column
334
+ } = _ref5;
335
+ const isRowTotal = this.doRowTotals && column === this.dataWidth - 1;
336
+ const isColumnTotal = this.doColumnTotals && row === this.dataHeight - 1;
337
+ if (isRowTotal || isColumnTotal) {
338
+ return CELL_TYPE_TOTAL;
339
+ }
340
+ const isRowSubtotal = this.doRowSubtotals && (column + 1) % (this.dimensionLookup.columns[0].size + 1) === 0;
341
+ const isColumnSubtotal = this.doColumnSubtotals && (row + 1) % (this.dimensionLookup.rows[0].size + 1) === 0;
342
+ if (isRowSubtotal || isColumnSubtotal) {
343
+ return CELL_TYPE_SUBTOTAL;
344
+ }
345
+ return CELL_TYPE_VALUE;
346
+ }
347
+ getCellType(_ref6) {
348
+ let {
349
+ row,
350
+ column
351
+ } = _ref6;
352
+ row = this.rowMap[row];
353
+ column = this.columnMap[column];
354
+ return this.getRawCellType({
355
+ row,
356
+ column
357
+ });
358
+ }
359
+ getDimensionLabel(rowLevel, columnLevel) {
360
+ const lastRowLevel = this.rowDepth - 1;
361
+ const lastColumnLevel = this.columnDepth - 1;
362
+ if (rowLevel !== lastRowLevel && columnLevel !== lastColumnLevel) {
363
+ return null;
364
+ }
365
+ if (rowLevel === lastRowLevel && this.dimensionLookup.rows[lastRowLevel] && columnLevel === lastColumnLevel && this.dimensionLookup.columns[lastColumnLevel]) {
366
+ return `${this.dimensionLookup.rows[lastRowLevel].meta.name} / ${this.dimensionLookup.columns[lastColumnLevel].meta.name}`;
367
+ }
368
+ if (lastRowLevel === -1) {
369
+ return this.dimensionLookup.columns[columnLevel].meta.name;
370
+ }
371
+ if (lastColumnLevel === -1) {
372
+ return this.dimensionLookup.rows[rowLevel].meta.name;
373
+ }
374
+ if (rowLevel === lastRowLevel && this.dimensionLookup.columns[columnLevel]) {
375
+ return this.dimensionLookup.columns[columnLevel].meta.name;
376
+ }
377
+ if (columnLevel === lastColumnLevel && this.dimensionLookup.rows[rowLevel]) {
378
+ return this.dimensionLookup.rows[rowLevel].meta.name;
379
+ }
380
+ }
381
+ getCellDxDimension(_ref7) {
382
+ let {
383
+ row,
384
+ column
385
+ } = _ref7;
386
+ return this.getRawCellDxDimension({
387
+ row: this.rowMap[row],
388
+ column: this.columnMap[column]
389
+ });
390
+ }
391
+ getRawCellDxDimension(_ref8) {
392
+ let {
393
+ row,
394
+ column
395
+ } = _ref8;
396
+ if (!this.data[row]) {
397
+ return undefined;
398
+ }
399
+ const cellValue = this.data[row][column];
400
+ if (!cellValue) {
401
+ return undefined;
402
+ }
403
+ if (!Array.isArray(cellValue)) {
404
+ // This is a total cell
405
+ return {
406
+ valueType: cellValue.valueType,
407
+ totalAggregationType: cellValue.totalAggregationType,
408
+ legendSet: undefined
409
+ };
410
+ }
411
+ const rowHeaders = this.getRawRowHeader(row);
412
+ const columnHeaders = this.getRawColumnHeader(column);
413
+ const dxRowIndex = this.dimensionLookup.rows.findIndex(dim => dim.isDxDimension);
414
+ if (rowHeaders.length && dxRowIndex !== -1) {
415
+ return {
416
+ valueType: rowHeaders[dxRowIndex].valueType,
417
+ totalAggregationType: rowHeaders[dxRowIndex].totalAggregationType,
418
+ legendSet: rowHeaders[dxRowIndex].legendSet
419
+ };
420
+ }
421
+ const dxColumnIndex = this.dimensionLookup.columns.findIndex(dim => dim.isDxDimension);
422
+ if (columnHeaders.length && dxColumnIndex !== -1) {
423
+ return {
424
+ valueType: columnHeaders[dxColumnIndex].valueType,
425
+ totalAggregationType: columnHeaders[dxColumnIndex].totalAggregationType,
426
+ legendSet: columnHeaders[dxColumnIndex].legendSet
427
+ };
428
+ }
429
+
430
+ // Data is in Filter
431
+ // TODO : This assumes the server ignores text types, we should confirm this is the case
432
+ return {
433
+ valueType: VALUE_TYPE_NUMBER,
434
+ totalAggregationType: AGGREGATE_TYPE_SUM
435
+ };
436
+ }
437
+ rowIsEmpty(row) {
438
+ return !this.data[row] || this.data[row].length === 0;
439
+ }
440
+ columnIsEmpty(column) {
441
+ return !this.adaptiveClippingController.columns.sizes[column];
442
+ }
443
+ getRawColumnHeader(column) {
444
+ var _this$dimensionLookup17;
445
+ if (this.doRowTotals && column === this.dataWidth - 1) {
446
+ return times(this.columnDepth - 1, () => undefined).concat([{
447
+ name: 'Total'
448
+ }]);
449
+ }
450
+ if (this.doRowSubtotals) {
451
+ var _this$dimensionLookup11, _this$dimensionLookup12, _this$dimensionLookup13, _this$dimensionLookup14, _this$dimensionLookup15, _this$dimensionLookup16;
452
+ if ((column + 1) % (((_this$dimensionLookup11 = (_this$dimensionLookup12 = this.dimensionLookup) === null || _this$dimensionLookup12 === void 0 ? void 0 : (_this$dimensionLookup13 = _this$dimensionLookup12.columns[0]) === null || _this$dimensionLookup13 === void 0 ? void 0 : _this$dimensionLookup13.size) !== null && _this$dimensionLookup11 !== void 0 ? _this$dimensionLookup11 : 0) + 1) === 0) {
453
+ return times(this.columnDepth - 1, () => undefined).concat([{
454
+ name: 'Subtotal'
455
+ }]);
456
+ }
457
+ column -= Math.floor(column / (((_this$dimensionLookup14 = (_this$dimensionLookup15 = this.dimensionLookup) === null || _this$dimensionLookup15 === void 0 ? void 0 : (_this$dimensionLookup16 = _this$dimensionLookup15.columns[0]) === null || _this$dimensionLookup16 === void 0 ? void 0 : _this$dimensionLookup16.size) !== null && _this$dimensionLookup14 !== void 0 ? _this$dimensionLookup14 : 0) + 1));
458
+ }
459
+ return (_this$dimensionLookup17 = this.dimensionLookup) === null || _this$dimensionLookup17 === void 0 ? void 0 : _this$dimensionLookup17.columns.map(dimension => {
460
+ var _dimension$size, _dimension$count;
461
+ const itemIndex = Math.floor(column / ((_dimension$size = dimension.size) !== null && _dimension$size !== void 0 ? _dimension$size : 1)) % ((_dimension$count = dimension.count) !== null && _dimension$count !== void 0 ? _dimension$count : 1);
462
+ return dimension.items[itemIndex];
463
+ });
464
+ }
465
+ getColumnHeader(column) {
466
+ return this.getRawColumnHeader(this.columnMap[column]);
467
+ }
468
+ getRawRowHeader(row) {
469
+ var _this$dimensionLookup26, _this$dimensionLookup27;
470
+ if (this.doColumnTotals && row === this.dataHeight - 1) {
471
+ return times(this.rowDepth - 1, () => undefined).concat([{
472
+ name: 'Total'
473
+ }]);
474
+ }
475
+ if (this.doColumnSubtotals) {
476
+ var _this$dimensionLookup18, _this$dimensionLookup19, _this$dimensionLookup20, _this$dimensionLookup21, _this$dimensionLookup22, _this$dimensionLookup23, _this$dimensionLookup24, _this$dimensionLookup25;
477
+ if ((row + 1) % (((_this$dimensionLookup18 = (_this$dimensionLookup19 = this.dimensionLookup) === null || _this$dimensionLookup19 === void 0 ? void 0 : (_this$dimensionLookup20 = _this$dimensionLookup19.rows) === null || _this$dimensionLookup20 === void 0 ? void 0 : (_this$dimensionLookup21 = _this$dimensionLookup20[0]) === null || _this$dimensionLookup21 === void 0 ? void 0 : _this$dimensionLookup21.size) !== null && _this$dimensionLookup18 !== void 0 ? _this$dimensionLookup18 : 0) + 1) === 0) {
478
+ return times(this.rowDepth - 1, () => undefined).concat([{
479
+ name: 'Subtotal'
480
+ }]);
481
+ }
482
+ row -= Math.floor(row / (((_this$dimensionLookup22 = (_this$dimensionLookup23 = this.dimensionLookup) === null || _this$dimensionLookup23 === void 0 ? void 0 : (_this$dimensionLookup24 = _this$dimensionLookup23.rows) === null || _this$dimensionLookup24 === void 0 ? void 0 : (_this$dimensionLookup25 = _this$dimensionLookup24[0]) === null || _this$dimensionLookup25 === void 0 ? void 0 : _this$dimensionLookup25.size) !== null && _this$dimensionLookup22 !== void 0 ? _this$dimensionLookup22 : 0) + 1));
483
+ }
484
+ return (_this$dimensionLookup26 = (_this$dimensionLookup27 = this.dimensionLookup) === null || _this$dimensionLookup27 === void 0 ? void 0 : _this$dimensionLookup27.rows.map(dimension => {
485
+ var _dimension$size2, _dimension$count2;
486
+ const itemIndex = Math.floor(row / ((_dimension$size2 = dimension === null || dimension === void 0 ? void 0 : dimension.size) !== null && _dimension$size2 !== void 0 ? _dimension$size2 : 1)) % ((_dimension$count2 = dimension.count) !== null && _dimension$count2 !== void 0 ? _dimension$count2 : 1);
487
+ return dimension.items[itemIndex];
488
+ })) !== null && _this$dimensionLookup26 !== void 0 ? _this$dimensionLookup26 : [];
489
+ }
490
+ getRowHeader(row) {
491
+ return this.getRawRowHeader(this.rowMap[row]);
492
+ }
493
+ getDependantTotalCells(_ref9) {
494
+ var _this$dimensionLookup28, _this$dimensionLookup29, _this$dimensionLookup30, _this$dimensionLookup31, _this$dimensionLookup32, _this$dimensionLookup33;
495
+ let {
496
+ row,
497
+ column
498
+ } = _ref9;
499
+ const rowSubtotalSize = ((_this$dimensionLookup28 = (_this$dimensionLookup29 = this.dimensionLookup) === null || _this$dimensionLookup29 === void 0 ? void 0 : (_this$dimensionLookup30 = _this$dimensionLookup29.columns[0]) === null || _this$dimensionLookup30 === void 0 ? void 0 : _this$dimensionLookup30.size) !== null && _this$dimensionLookup28 !== void 0 ? _this$dimensionLookup28 : 0) + 1;
500
+ const rowSubtotal = rowSubtotalSize && this.doRowSubtotals && {
501
+ row,
502
+ column: Math.ceil((column + 1) / rowSubtotalSize) * rowSubtotalSize - 1,
503
+ size: rowSubtotalSize - 1
504
+ };
505
+ const rowSubtotalColumnTotal = this.doRowSubtotals && this.doColumnTotals && {
506
+ row: this.dataHeight - 1,
507
+ column: rowSubtotal === null || rowSubtotal === void 0 ? void 0 : rowSubtotal.column,
508
+ size: this.rawDataHeight
509
+ };
510
+ const columnSubtotalSize = ((_this$dimensionLookup31 = (_this$dimensionLookup32 = this.dimensionLookup) === null || _this$dimensionLookup32 === void 0 ? void 0 : (_this$dimensionLookup33 = _this$dimensionLookup32.rows[0]) === null || _this$dimensionLookup33 === void 0 ? void 0 : _this$dimensionLookup33.size) !== null && _this$dimensionLookup31 !== void 0 ? _this$dimensionLookup31 : 0) + 1;
511
+ const columnSubtotal = columnSubtotalSize && this.doColumnSubtotals && {
512
+ row: Math.ceil((row + 1) / columnSubtotalSize) * columnSubtotalSize - 1,
513
+ column,
514
+ size: columnSubtotalSize - 1
515
+ };
516
+ const columnSubtotalRowTotal = this.doColumnSubtotals && this.doRowTotals && {
517
+ row: columnSubtotal.row,
518
+ column: this.dataWidth - 1,
519
+ size: this.rawDataWidth
520
+ };
521
+ const combinedSubtotal = rowSubtotalSize && columnSubtotalSize && this.doColumnSubtotals && this.doRowSubtotals && {
522
+ row: columnSubtotal.row,
523
+ column: rowSubtotal.column,
524
+ size: columnSubtotalSize * rowSubtotalSize
525
+ };
526
+ const rowTotal = this.doRowTotals && {
527
+ row,
528
+ column: this.dataWidth - 1,
529
+ size: this.rawDataWidth
530
+ };
531
+ const columnTotal = this.doColumnTotals && {
532
+ row: this.dataHeight - 1,
533
+ column,
534
+ size: this.rawDataHeight
535
+ };
536
+ const combinedTotal = this.doColumnTotals && this.doRowTotals && {
537
+ row: this.dataHeight - 1,
538
+ column: this.dataWidth - 1,
539
+ size: this.rawDataHeight * this.rawDataWidth
540
+ };
541
+ return {
542
+ rowSubtotal,
543
+ rowSubtotalColumnTotal,
544
+ columnSubtotal,
545
+ columnSubtotalRowTotal,
546
+ rowTotal,
547
+ columnTotal,
548
+ combinedSubtotal,
549
+ combinedTotal
550
+ };
551
+ }
552
+ addCellValueToTotals(pos, dataRow) {
553
+ const totals = this.getDependantTotalCells(pos);
554
+ const dxDimension = this.getRawCellDxDimension(pos);
555
+ Object.values(totals).forEach(totalItem => {
556
+ if (!totalItem) {
557
+ return;
558
+ }
559
+ this.data[totalItem.row] = this.data[totalItem.row] || [];
560
+ this.data[totalItem.row][totalItem.column] = this.data[totalItem.row][totalItem.column] || {
561
+ count: 0,
562
+ totalCount: totalItem.size
563
+ };
564
+ const totalCell = this.data[totalItem.row][totalItem.column];
565
+ const currentAggType = dxDimension === null || dxDimension === void 0 ? void 0 : dxDimension.totalAggregationType;
566
+ const previousAggType = totalCell.totalAggregationType || currentAggType;
567
+ if (previousAggType && currentAggType !== previousAggType) {
568
+ totalCell.totalAggregationType = AGGREGATE_TYPE_NA;
569
+ } else {
570
+ totalCell.totalAggregationType = currentAggType;
571
+ }
572
+ const currentValueType = dxDimension === null || dxDimension === void 0 ? void 0 : dxDimension.valueType;
573
+ const previousValueType = totalCell.valueType;
574
+ if (previousValueType && currentValueType !== previousValueType) {
575
+ totalCell.valueType = AGGREGATE_TYPE_NA;
576
+ } else {
577
+ totalCell.valueType = currentValueType;
578
+ }
579
+ if ((dxDimension === null || dxDimension === void 0 ? void 0 : dxDimension.valueType) === VALUE_TYPE_NUMBER) {
580
+ dataFields.forEach(field => {
581
+ const headerIndex = this.dimensionLookup.dataHeaders[field];
582
+ const value = parseValue(dataRow[headerIndex]);
583
+ if (value && !isNaN(value)) {
584
+ totalCell[field] = (totalCell[field] || 0) + value;
585
+ }
586
+ });
587
+ }
588
+ totalCell.count += 1;
589
+ });
590
+ if (this.visualization.numberType === NUMBER_TYPE_ROW_PERCENTAGE) {
591
+ if (!this.percentageTotals[pos.row]) {
592
+ this.percentageTotals[pos.row] = {
593
+ count: 0,
594
+ totalCount: this.rawDataWidth
595
+ };
596
+ }
597
+ const percentageTotal = this.percentageTotals[pos.row];
598
+ dataFields.forEach(field => {
599
+ const headerIndex = this.dimensionLookup.dataHeaders[field];
600
+ const value = parseValue(dataRow[headerIndex]);
601
+ if (value && !isNaN(value)) {
602
+ percentageTotal[field] = (percentageTotal[field] || 0) + value;
603
+ }
604
+ });
605
+ if (totals.columnSubtotal) {
606
+ if (!this.percentageTotals[totals.columnSubtotal.row]) {
607
+ this.percentageTotals[totals.columnSubtotal.row] = {
608
+ count: 0,
609
+ totalCount: this.rawDataWidth
610
+ };
611
+ }
612
+ const percentageTotal = this.percentageTotals[totals.columnSubtotal.row];
613
+ dataFields.forEach(field => {
614
+ const headerIndex = this.dimensionLookup.dataHeaders[field];
615
+ const value = parseValue(dataRow[headerIndex]);
616
+ if (value && !isNaN(value)) {
617
+ percentageTotal[field] = (percentageTotal[field] || 0) + value;
618
+ }
619
+ });
620
+ }
621
+ if (totals.columnTotal) {
622
+ if (!this.percentageTotals[totals.columnTotal.row]) {
623
+ this.percentageTotals[totals.columnTotal.row] = {
624
+ count: 0,
625
+ totalCount: this.rawDataWidth
626
+ };
627
+ }
628
+ const percentageTotal = this.percentageTotals[totals.columnTotal.row];
629
+ dataFields.forEach(field => {
630
+ const headerIndex = this.dimensionLookup.dataHeaders[field];
631
+ const value = parseValue(dataRow[headerIndex]);
632
+ if (value && !isNaN(value)) {
633
+ percentageTotal[field] = (percentageTotal[field] || 0) + value;
634
+ }
635
+ });
636
+ }
637
+ }
638
+ if (this.visualization.numberType === NUMBER_TYPE_COLUMN_PERCENTAGE) {
639
+ if (!this.percentageTotals[pos.column]) {
640
+ this.percentageTotals[pos.column] = {
641
+ count: 0,
642
+ totalCount: this.rawDataHeight
643
+ };
644
+ }
645
+ const percentageTotal = this.percentageTotals[pos.column];
646
+ dataFields.forEach(field => {
647
+ const headerIndex = this.dimensionLookup.dataHeaders[field];
648
+ const value = parseValue(dataRow[headerIndex]);
649
+ if (value && !isNaN(value)) {
650
+ percentageTotal[field] = (percentageTotal[field] || 0) + value;
651
+ }
652
+ });
653
+ if (totals.rowSubtotal) {
654
+ if (!this.percentageTotals[totals.rowSubtotal.column]) {
655
+ this.percentageTotals[totals.rowSubtotal.column] = {
656
+ count: 0,
657
+ totalCount: this.rawDataHeight
658
+ };
659
+ }
660
+ const percentageTotal = this.percentageTotals[totals.rowSubtotal.column];
661
+ dataFields.forEach(field => {
662
+ const headerIndex = this.dimensionLookup.dataHeaders[field];
663
+ const value = parseValue(dataRow[headerIndex]);
664
+ if (value && !isNaN(value)) {
665
+ percentageTotal[field] = (percentageTotal[field] || 0) + value;
666
+ }
667
+ });
668
+ }
669
+ if (totals.rowTotal) {
670
+ if (!this.percentageTotals[totals.rowTotal.column]) {
671
+ this.percentageTotals[totals.rowTotal.column] = {
672
+ count: 0,
673
+ totalCount: this.rawDataHeight
674
+ };
675
+ }
676
+ const percentageTotal = this.percentageTotals[totals.rowTotal.column];
677
+ dataFields.forEach(field => {
678
+ const headerIndex = this.dimensionLookup.dataHeaders[field];
679
+ const value = parseValue(dataRow[headerIndex]);
680
+ if (value && !isNaN(value)) {
681
+ percentageTotal[field] = (percentageTotal[field] || 0) + value;
682
+ }
683
+ });
684
+ }
685
+ }
686
+ }
687
+ finalizeTotal(_ref10) {
688
+ let {
689
+ row,
690
+ column
691
+ } = _ref10;
692
+ if (!this.data[row]) {
693
+ return;
694
+ }
695
+ const totalCell = this.data[row][column];
696
+ if (totalCell && totalCell.count) {
697
+ totalCell.value = applyTotalAggregationType(totalCell, this.visualization.numberType !== NUMBER_TYPE_VALUE && AGGREGATE_TYPE_SUM);
698
+ this.adaptiveClippingController.add({
699
+ row,
700
+ column
701
+ }, renderValue(totalCell.value, totalCell.valueType, this.visualization));
702
+ }
703
+ }
704
+ finalizeTotals() {
705
+ var _this$dimensionLookup34, _this$dimensionLookup35, _this$dimensionLookup36, _this$dimensionLookup37, _this$dimensionLookup38, _this$dimensionLookup39;
706
+ const columnSubtotalSize = ((_this$dimensionLookup34 = (_this$dimensionLookup35 = this.dimensionLookup) === null || _this$dimensionLookup35 === void 0 ? void 0 : (_this$dimensionLookup36 = _this$dimensionLookup35.rows[0]) === null || _this$dimensionLookup36 === void 0 ? void 0 : _this$dimensionLookup36.size) !== null && _this$dimensionLookup34 !== void 0 ? _this$dimensionLookup34 : 0) + 1;
707
+ const rowSubtotalSize = ((_this$dimensionLookup37 = (_this$dimensionLookup38 = this.dimensionLookup) === null || _this$dimensionLookup38 === void 0 ? void 0 : (_this$dimensionLookup39 = _this$dimensionLookup38.columns[0]) === null || _this$dimensionLookup39 === void 0 ? void 0 : _this$dimensionLookup39.size) !== null && _this$dimensionLookup37 !== void 0 ? _this$dimensionLookup37 : 0) + 1;
708
+ if (this.doRowSubtotals && rowSubtotalSize) {
709
+ times(this.dimensionLookup.columns[0].count, n => (n + 1) * rowSubtotalSize - 1).forEach(column => {
710
+ times(this.dataHeight - (this.doColumnTotals ? 1 : 0), n => n).forEach(row => {
711
+ // skip combined subtotal cells
712
+ if (!this.doColumnSubtotals || (row + 1) % columnSubtotalSize !== 0) {
713
+ this.finalizeTotal({
714
+ row,
715
+ column
716
+ });
717
+ }
718
+ });
719
+ });
720
+ }
721
+ if (this.doColumnSubtotals && columnSubtotalSize) {
722
+ times(this.dimensionLookup.rows[0].count, n => (n + 1) * columnSubtotalSize - 1).forEach(row => {
723
+ times(this.dataWidth - (this.doRowTotals ? 1 : 0), n => n).forEach(column => {
724
+ // skip combined subtotal cells
725
+ if (!this.doRowSubtotals || (column + 1) % rowSubtotalSize !== 0) {
726
+ this.finalizeTotal({
727
+ row,
728
+ column
729
+ });
730
+ }
731
+ });
732
+ });
733
+ }
734
+
735
+ // Combined subtotal cells
736
+ if (this.doRowSubtotals && this.doColumnSubtotals && rowSubtotalSize && columnSubtotalSize) {
737
+ times(this.dimensionLookup.rows[0].count, n => (n + 1) * columnSubtotalSize - 1).forEach(row => {
738
+ times(this.dimensionLookup.columns[0].count, n => (n + 1) * rowSubtotalSize - 1).forEach(column => {
739
+ this.finalizeTotal({
740
+ row,
741
+ column
742
+ });
743
+ });
744
+ });
745
+ }
746
+ if (this.doRowTotals) {
747
+ const column = this.dataWidth - 1;
748
+ const rowCount = this.doColumnTotals ? this.dataHeight - 1 : this.dataHeight;
749
+ times(rowCount, n => n).forEach(row => {
750
+ this.finalizeTotal({
751
+ row,
752
+ column
753
+ });
754
+ });
755
+ }
756
+ if (this.doColumnTotals) {
757
+ const row = this.dataHeight - 1;
758
+ const colCount = this.doRowTotals ? this.dataWidth - 1 : this.dataWidth;
759
+ times(colCount, n => n).forEach(column => {
760
+ this.finalizeTotal({
761
+ row,
762
+ column
763
+ });
764
+ });
765
+ }
766
+ if (this.doRowTotals && this.doColumnTotals) {
767
+ this.finalizeTotal({
768
+ row: this.dataHeight - 1,
769
+ column: this.dataWidth - 1
770
+ });
771
+ }
772
+ if (this.percentageTotals) {
773
+ this.percentageTotals.forEach(item => {
774
+ item.value = applyTotalAggregationType(item);
775
+ });
776
+ }
777
+ }
778
+ resetRowMap() {
779
+ this.rowMap = this.options.hideEmptyRows ? times(this.dataHeight, n => n).filter(idx => !!this.data[idx]) : times(this.dataHeight, n => n);
780
+ }
781
+ resetColumnMap() {
782
+ this.columnMap = this.options.hideEmptyColumns ? times(this.dataWidth, n => n).filter(idx => !this.columnIsEmpty(idx)) : times(this.dataWidth, n => n);
783
+ }
784
+ buildMatrix() {
785
+ this.data = [];
786
+ this.adaptiveClippingController.reset();
787
+ this.dataHeight = this.rawDataHeight = countFromDisaggregates(this.dimensionLookup.rows);
788
+ this.dataWidth = this.rawDataWidth = countFromDisaggregates(this.dimensionLookup.columns);
789
+
790
+ // TODO: Check last row/col dimension for size===1, skip redundant sub-totals
791
+ this.doRowSubtotals = this.options.showRowSubtotals && this.columnDepth > 1;
792
+ this.doColumnSubtotals = this.options.showColumnSubtotals && this.rowDepth > 1;
793
+ this.doRowTotals = this.options.showRowTotals && this.dataWidth > 1;
794
+ this.doColumnTotals = this.options.showColumnTotals && this.dataHeight > 1;
795
+ if (this.doRowSubtotals) {
796
+ this.dataWidth += this.dimensionLookup.columns[0].count;
797
+ }
798
+ if (this.doColumnSubtotals) {
799
+ this.dataHeight += this.dimensionLookup.rows[0].count;
800
+ }
801
+ if (this.doRowTotals) {
802
+ this.dataWidth += 1;
803
+ }
804
+ if (this.doColumnTotals) {
805
+ this.dataHeight += 1;
806
+ }
807
+
808
+ // TODO: Use total cell calculation, don't duplicate here
809
+ if (this.visualization.numberType === NUMBER_TYPE_ROW_PERCENTAGE || this.visualization.numberType === NUMBER_TYPE_COLUMN_PERCENTAGE) {
810
+ this.percentageTotals = [];
811
+ }
812
+ this.rawData.rows.forEach(dataRow => {
813
+ const pos = lookup(dataRow, this.dimensionLookup, this);
814
+ if (pos) {
815
+ this.data[pos.row] = this.data[pos.row] || [];
816
+ this.data[pos.row][pos.column] = dataRow;
817
+ this.addCellValueToTotals(pos, dataRow);
818
+ }
819
+ });
820
+ this.finalizeTotals();
821
+ this.rawData.rows.forEach(dataRow => {
822
+ const pos = lookup(dataRow, this.dimensionLookup, this);
823
+ if (pos) {
824
+ this.adaptiveClippingController.add(pos, this.getRaw(pos).renderedValue);
825
+ }
826
+ });
827
+ this.resetRowMap();
828
+ this.resetColumnMap();
829
+ this.height = this.rowMap.length;
830
+ this.width = this.columnMap.length;
831
+ this.adaptiveClippingController.finalize();
832
+ }
833
+ getColumnType(column) {
834
+ column = this.columnMap[column];
835
+ if (!column && column !== 0) {
836
+ return undefined;
837
+ }
838
+ if (this.doRowSubtotals && (column + 1) % (this.dimensionLookup.columns[0].size + 1) === 0) {
839
+ return CELL_TYPE_SUBTOTAL;
840
+ }
841
+ if (this.doRowTotals && column === this.dataWidth - 1) {
842
+ return CELL_TYPE_TOTAL;
843
+ }
844
+ return CELL_TYPE_VALUE;
845
+ }
846
+ isSortable(column) {
847
+ return this.dataHeight > 1 && !this.doColumnSubtotals && this.getColumnType(column) !== undefined;
848
+ }
849
+ sort(column, order) {
850
+ if (order !== SORT_ORDER_ASCENDING && order !== SORT_ORDER_DESCENDING) {
851
+ console.warn(`Invalid sort order ${order}`);
852
+ return;
853
+ }
854
+ if (!this.isSortable(column)) {
855
+ console.warn(`Invalid sort column ${column}`);
856
+ return;
857
+ }
858
+ const mappedColumn = this.columnMap[column];
859
+ this.rowMap.sort((rowA, rowB) => {
860
+ if (this.doColumnTotals && rowA === this.dataHeight - 1) {
861
+ return 1;
862
+ }
863
+ if (this.doColumnTotals && rowB === this.dataHeight - 1) {
864
+ return -1;
865
+ }
866
+ const valueA = this.getRaw({
867
+ row: rowA,
868
+ column: mappedColumn
869
+ });
870
+ const valueB = this.getRaw({
871
+ row: rowB,
872
+ column: mappedColumn
873
+ });
874
+ if ((!valueA || valueA.empty) && (!valueB || valueB.empty)) {
875
+ return 0;
876
+ }
877
+ if (!valueA || valueA.empty) {
878
+ return -1 * order;
879
+ }
880
+ if (!valueB || valueB.empty) {
881
+ return 1 * order;
882
+ }
883
+ if (valueA.valueType === VALUE_TYPE_NUMBER && valueB.valueType === VALUE_TYPE_NUMBER) {
884
+ return (valueA.rawValue - valueB.rawValue) * order;
885
+ }
886
+ return valueA.renderedValue.localeCompare(valueB.renderedValue) * order;
887
+ });
888
+ this.adaptiveClippingController.resetRowPartitions();
889
+ }
890
+ clearSort() {
891
+ this.resetRowMap();
892
+ this.adaptiveClippingController.resetRowPartitions();
893
+ }
894
+ }