@deephaven/grid 0.43.0 → 0.44.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 (115) hide show
  1. package/dist/CellInputField.css +23 -0
  2. package/dist/CellInputField.css.map +1 -0
  3. package/dist/CellInputField.js +174 -0
  4. package/dist/CellInputField.js.map +1 -0
  5. package/dist/CellRenderer.js +64 -0
  6. package/dist/CellRenderer.js.map +1 -0
  7. package/dist/ColumnHeaderGroup.js +2 -0
  8. package/dist/ColumnHeaderGroup.js.map +1 -0
  9. package/dist/DataBarCellRenderer.js +404 -0
  10. package/dist/DataBarCellRenderer.js.map +1 -0
  11. package/dist/DataBarGridModel.js +27 -0
  12. package/dist/DataBarGridModel.js.map +1 -0
  13. package/dist/EditableGridModel.js +14 -0
  14. package/dist/EditableGridModel.js.map +1 -0
  15. package/dist/EventHandlerResult.js +2 -0
  16. package/dist/EventHandlerResult.js.map +1 -0
  17. package/dist/ExpandableGridModel.js +8 -0
  18. package/dist/ExpandableGridModel.js.map +1 -0
  19. package/dist/Grid.css +45 -0
  20. package/dist/Grid.css.map +1 -0
  21. package/dist/Grid.js +1947 -0
  22. package/dist/Grid.js.map +1 -0
  23. package/dist/GridAxisRange.js +17 -0
  24. package/dist/GridAxisRange.js.map +1 -0
  25. package/dist/GridColorUtils.js +146 -0
  26. package/dist/GridColorUtils.js.map +1 -0
  27. package/dist/GridMetricCalculator.js +1500 -0
  28. package/dist/GridMetricCalculator.js.map +1 -0
  29. package/dist/GridMetrics.js +2 -0
  30. package/dist/GridMetrics.js.map +1 -0
  31. package/dist/GridModel.js +193 -0
  32. package/dist/GridModel.js.map +1 -0
  33. package/dist/GridMouseHandler.js +57 -0
  34. package/dist/GridMouseHandler.js.map +1 -0
  35. package/dist/GridRange.js +684 -0
  36. package/dist/GridRange.js.map +1 -0
  37. package/dist/GridRenderer.js +2038 -0
  38. package/dist/GridRenderer.js.map +1 -0
  39. package/dist/GridRendererTypes.js +3 -0
  40. package/dist/GridRendererTypes.js.map +1 -0
  41. package/dist/GridTestUtils.js +16 -0
  42. package/dist/GridTestUtils.js.map +1 -0
  43. package/dist/GridTheme.js +100 -0
  44. package/dist/GridTheme.js.map +1 -0
  45. package/dist/GridUtils.js +1198 -0
  46. package/dist/GridUtils.js.map +1 -0
  47. package/dist/KeyHandler.js +36 -0
  48. package/dist/KeyHandler.js.map +1 -0
  49. package/dist/MockDataBarGridModel.js +119 -0
  50. package/dist/MockDataBarGridModel.js.map +1 -0
  51. package/dist/MockGridData.js +5 -0
  52. package/dist/MockGridData.js.map +1 -0
  53. package/dist/MockGridModel.js +122 -0
  54. package/dist/MockGridModel.js.map +1 -0
  55. package/dist/MockTreeGridModel.js +193 -0
  56. package/dist/MockTreeGridModel.js.map +1 -0
  57. package/dist/StaticDataGridModel.js +40 -0
  58. package/dist/StaticDataGridModel.js.map +1 -0
  59. package/dist/TextCellRenderer.js +210 -0
  60. package/dist/TextCellRenderer.js.map +1 -0
  61. package/dist/ThemeContext.js +4 -0
  62. package/dist/ThemeContext.js.map +1 -0
  63. package/dist/TokenBoxCellRenderer.js +4 -0
  64. package/dist/TokenBoxCellRenderer.js.map +1 -0
  65. package/dist/ViewportDataGridModel.js +43 -0
  66. package/dist/ViewportDataGridModel.js.map +1 -0
  67. package/dist/errors/AssertionError.js +11 -0
  68. package/dist/errors/AssertionError.js.map +1 -0
  69. package/dist/errors/PasteError.js +11 -0
  70. package/dist/errors/PasteError.js.map +1 -0
  71. package/dist/errors/assertIsDefined.js +8 -0
  72. package/dist/errors/assertIsDefined.js.map +1 -0
  73. package/dist/errors/index.js +4 -0
  74. package/dist/errors/index.js.map +1 -0
  75. package/dist/index.js +32 -0
  76. package/dist/index.js.map +1 -0
  77. package/dist/key-handlers/EditKeyHandler.js +46 -0
  78. package/dist/key-handlers/EditKeyHandler.js.map +1 -0
  79. package/dist/key-handlers/PasteKeyHandler.js +124 -0
  80. package/dist/key-handlers/PasteKeyHandler.js.map +1 -0
  81. package/dist/key-handlers/SelectionKeyHandler.js +272 -0
  82. package/dist/key-handlers/SelectionKeyHandler.js.map +1 -0
  83. package/dist/key-handlers/TreeKeyHandler.js +45 -0
  84. package/dist/key-handlers/TreeKeyHandler.js.map +1 -0
  85. package/dist/key-handlers/index.js +5 -0
  86. package/dist/key-handlers/index.js.map +1 -0
  87. package/dist/memoizeClear.js +33 -0
  88. package/dist/memoizeClear.js.map +1 -0
  89. package/dist/mouse-handlers/EditMouseHandler.js +25 -0
  90. package/dist/mouse-handlers/EditMouseHandler.js.map +1 -0
  91. package/dist/mouse-handlers/GridColumnMoveMouseHandler.js +504 -0
  92. package/dist/mouse-handlers/GridColumnMoveMouseHandler.js.map +1 -0
  93. package/dist/mouse-handlers/GridColumnSeparatorMouseHandler.js +67 -0
  94. package/dist/mouse-handlers/GridColumnSeparatorMouseHandler.js.map +1 -0
  95. package/dist/mouse-handlers/GridHorizontalScrollBarMouseHandler.js +164 -0
  96. package/dist/mouse-handlers/GridHorizontalScrollBarMouseHandler.js.map +1 -0
  97. package/dist/mouse-handlers/GridRowMoveMouseHandler.js +139 -0
  98. package/dist/mouse-handlers/GridRowMoveMouseHandler.js.map +1 -0
  99. package/dist/mouse-handlers/GridRowSeparatorMouseHandler.js +54 -0
  100. package/dist/mouse-handlers/GridRowSeparatorMouseHandler.js.map +1 -0
  101. package/dist/mouse-handlers/GridRowTreeMouseHandler.js +58 -0
  102. package/dist/mouse-handlers/GridRowTreeMouseHandler.js.map +1 -0
  103. package/dist/mouse-handlers/GridScrollBarCornerMouseHandler.js +39 -0
  104. package/dist/mouse-handlers/GridScrollBarCornerMouseHandler.js.map +1 -0
  105. package/dist/mouse-handlers/GridSelectionMouseHandler.js +223 -0
  106. package/dist/mouse-handlers/GridSelectionMouseHandler.js.map +1 -0
  107. package/dist/mouse-handlers/GridSeparatorMouseHandler.js +213 -0
  108. package/dist/mouse-handlers/GridSeparatorMouseHandler.js.map +1 -0
  109. package/dist/mouse-handlers/GridTokenMouseHandler.js +161 -0
  110. package/dist/mouse-handlers/GridTokenMouseHandler.js.map +1 -0
  111. package/dist/mouse-handlers/GridVerticalScrollBarMouseHandler.js +165 -0
  112. package/dist/mouse-handlers/GridVerticalScrollBarMouseHandler.js.map +1 -0
  113. package/dist/mouse-handlers/index.js +13 -0
  114. package/dist/mouse-handlers/index.js.map +1 -0
  115. package/package.json +3 -3
@@ -0,0 +1,1500 @@
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
+ import clamp from 'lodash.clamp';
5
+ import { getOrThrow } from '@deephaven/utils';
6
+ import GridUtils from "./GridUtils.js";
7
+ import { isExpandableGridModel } from "./ExpandableGridModel.js";
8
+ export { getOrThrow } from '@deephaven/utils';
9
+ /* eslint class-methods-use-this: "off" */
10
+ /* eslint react/destructuring-assignment: "off" */
11
+
12
+ /**
13
+ * Trim the provided map in place. Trims oldest inserted items down to the target size if the cache size is exceeded.
14
+ * Instead of trimming one item on every tick, we trim half the items so there isn't a cache clear on every new item.
15
+ * @param map The map to trim
16
+ * @param cacheSize The maximum number of elements to cache
17
+ * @param targetSize The number of elements to reduce the cache down to if `cacheSize` is exceeded
18
+ */
19
+ export function trimMap(map) {
20
+ var cacheSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : GridMetricCalculator.CACHE_SIZE;
21
+ var targetSize = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : Math.floor(cacheSize / 2);
22
+ if (map.size > cacheSize) {
23
+ var iter = map.keys();
24
+ while (map.size > targetSize) {
25
+ map.delete(iter.next().value);
26
+ }
27
+ }
28
+ }
29
+
30
+ /**
31
+ * Get the coordinates of floating items in one dimension.
32
+ * Can be used for getting the y coordinates of floating rows, or x coordinates of floating columns, calculated using the `sizeMap` passed in.
33
+ * @param startCount The number of floating items at the start (ie. `floatingTopRowCount` for rows, `floatingLeftColumnCount` for columns)
34
+ * @param endCount The number of floating items at the end (ie. `floatingBottomRowCount` for rows, `floatingRightColumnCount` for columns)
35
+ * @param totalCount Total number of items in this dimension (ie. `rowCount` for rows, `columnCount` for columns)
36
+ * @param max The max coordinate value (ie. `maxY` for rows, `maxX` for columns)
37
+ * @param sizeMap Map from index to size of item (ie. `rowHeightMap` for rows, `columnWidthMap` for columns)
38
+ */
39
+ export function getFloatingCoordinates(startCount, endCount, totalCount, max, sizeMap) {
40
+ var coordinates = new Map();
41
+ var x = 0;
42
+ for (var i = 0; i < startCount && i < totalCount; i += 1) {
43
+ coordinates.set(i, x);
44
+ x += getOrThrow(sizeMap, i);
45
+ }
46
+ x = max;
47
+ for (var _i = 0; _i < endCount && totalCount - _i - 1 >= 0; _i += 1) {
48
+ x -= getOrThrow(sizeMap, totalCount - _i - 1);
49
+ coordinates.set(totalCount - _i - 1, x);
50
+ }
51
+ return coordinates;
52
+ }
53
+
54
+ /**
55
+ * Class to calculate all the metrics for drawing a grid.
56
+ * Call getMetrics() with the state to get the full metrics.
57
+ * Override this class and override the individual methods to provide additional functionality.
58
+ */
59
+ export class GridMetricCalculator {
60
+ /** The size of the caches this calculator stores */
61
+
62
+ /** The maximum column width as a percentage of the full grid */
63
+
64
+ /** The initial row heights if any overrides from the default calculated values */
65
+ // Readonly so it should be safe to make public
66
+
67
+ /** The initial column widths if any overrides from the default calculated values */
68
+ // Readonly so it should be safe to make public
69
+
70
+ /** User set column widths */
71
+
72
+ /** User set row heights */
73
+
74
+ /** Calculated column widths based on cell contents */
75
+
76
+ /** Calculated row heights based on cell contents */
77
+
78
+ /** Cache of fonts to estimated width of one char */
79
+
80
+ /** Map from visible index to model index for rows (e.g. reversing movedRows operations) */
81
+
82
+ /** Map from visible index to model index for columns (e.g. reversing movedColumns operations) */
83
+
84
+ /** List of moved row operations. Need to track the previous value so we know if modelRows needs to be cleared. */
85
+
86
+ /** List of moved column operations. Need to track the previous value so we know if modelColumns needs to be cleared. */
87
+
88
+ constructor() {
89
+ var {
90
+ userColumnWidths = new Map(),
91
+ userRowHeights = new Map(),
92
+ calculatedColumnWidths = new Map(),
93
+ calculatedRowHeights = new Map(),
94
+ fontWidths = new Map(),
95
+ modelRows = new Map(),
96
+ modelColumns = new Map(),
97
+ movedRows = [],
98
+ movedColumns = [],
99
+ initialRowHeights = new Map(),
100
+ initialColumnWidths = new Map()
101
+ } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
102
+ _defineProperty(this, "initialRowHeights", void 0);
103
+ _defineProperty(this, "initialColumnWidths", void 0);
104
+ _defineProperty(this, "userColumnWidths", void 0);
105
+ _defineProperty(this, "userRowHeights", void 0);
106
+ _defineProperty(this, "calculatedColumnWidths", void 0);
107
+ _defineProperty(this, "calculatedRowHeights", void 0);
108
+ _defineProperty(this, "fontWidths", void 0);
109
+ _defineProperty(this, "modelRows", void 0);
110
+ _defineProperty(this, "modelColumns", void 0);
111
+ _defineProperty(this, "movedRows", void 0);
112
+ _defineProperty(this, "movedColumns", void 0);
113
+ this.userColumnWidths = userColumnWidths;
114
+ this.userRowHeights = userRowHeights;
115
+ this.calculatedRowHeights = calculatedRowHeights;
116
+ this.calculatedColumnWidths = calculatedColumnWidths;
117
+ this.fontWidths = fontWidths;
118
+
119
+ // Need to track the last moved rows/columns array so we know if we need to reset our models cache
120
+ this.modelRows = modelRows;
121
+ this.modelColumns = modelColumns;
122
+ this.movedRows = movedRows;
123
+ this.movedColumns = movedColumns;
124
+ this.initialRowHeights = initialRowHeights;
125
+ this.initialColumnWidths = initialColumnWidths;
126
+ }
127
+
128
+ /**
129
+ * Get the metrics for the provided metric state
130
+ * @params state The state to get metrics for
131
+ * @returns The full metrics
132
+ */
133
+ getMetrics(state) {
134
+ var {
135
+ left,
136
+ top,
137
+ leftOffset,
138
+ topOffset,
139
+ width,
140
+ height,
141
+ theme,
142
+ model,
143
+ movedRows,
144
+ movedColumns,
145
+ draggingColumn
146
+ } = state;
147
+ var {
148
+ rowHeight,
149
+ rowHeaderWidth,
150
+ rowFooterWidth,
151
+ columnWidth,
152
+ columnHeaderHeight,
153
+ minScrollHandleSize,
154
+ scrollBarSize
155
+ } = theme;
156
+ if (movedRows !== this.movedRows) {
157
+ this.movedRows = movedRows;
158
+ this.modelRows.clear();
159
+ }
160
+ if (movedColumns !== this.movedColumns) {
161
+ this.movedColumns = movedColumns;
162
+ this.modelColumns.clear();
163
+ }
164
+ var {
165
+ columnCount,
166
+ rowCount,
167
+ floatingTopRowCount,
168
+ floatingBottomRowCount,
169
+ floatingLeftColumnCount,
170
+ floatingRightColumnCount,
171
+ columnHeaderMaxDepth
172
+ } = model;
173
+
174
+ // Get some basic metrics
175
+ var firstRow = this.getFirstRow(state);
176
+ var firstColumn = this.getFirstColumn(state);
177
+ var gridX = this.getGridX(state);
178
+ var gridY = this.getGridY(state);
179
+ var treePaddingX = isExpandableGridModel(model) && model.hasExpandableRows ? this.calculateTreePaddingX(state) : 0;
180
+ var treePaddingY = 0; // We don't support trees on columns (at least not yet)
181
+
182
+ var visibleRowHeights = this.getVisibleRowHeights(state);
183
+ var visibleColumnWidths = this.getVisibleColumnWidths(state, firstColumn, treePaddingX);
184
+
185
+ // Calculate the metrics for the main grid
186
+ var visibleRows = Array.from(visibleRowHeights.keys());
187
+ var visibleColumns = Array.from(visibleColumnWidths.keys());
188
+
189
+ // Add the floating row heights/column widths
190
+ var allRowHeights = new Map([...visibleRowHeights, ...this.getFloatingRowHeights(state)]);
191
+ var allColumnWidths = new Map([...visibleColumnWidths, ...this.getFloatingColumnWidths(state)]);
192
+ var visibleColumnXs = this.getVisibleColumnXs(allColumnWidths, visibleColumns, leftOffset);
193
+ var visibleRowYs = this.getVisibleRowYs(allRowHeights, visibleRows, topOffset);
194
+ var bottom = visibleRows.length > 0 ? visibleRows[visibleRows.length - 1] : top;
195
+ var right = visibleColumns.length > 0 ? visibleColumns[visibleColumns.length - 1] : left;
196
+ var bottomViewport = this.getBottomViewport(state, visibleRows, visibleRowYs, allRowHeights);
197
+ var rightViewport = this.getRightViewport(state, visibleColumns, visibleColumnXs, allColumnWidths);
198
+ var floatingTopHeight = this.getFloatingTopHeight(state, allRowHeights);
199
+ var floatingBottomHeight = this.getFloatingBottomHeight(state, allRowHeights);
200
+ var floatingLeftWidth = this.getFloatingLeftWidth(state, allColumnWidths);
201
+ var floatingRightWidth = this.getFloatingRightWidth(state, allColumnWidths);
202
+ var columnWidthValues = Array.from(allColumnWidths.values());
203
+ var rowHeightValues = Array.from(allRowHeights.values());
204
+ var maxX = columnWidthValues.reduce((x, w) => x + w, 0) - leftOffset;
205
+ var maxY = rowHeightValues.reduce((y, h) => y + h, 0) - topOffset;
206
+
207
+ // How much total space the content will take
208
+ var scrollableContentWidth = leftOffset + maxX + rowFooterWidth;
209
+ var scrollableContentHeight = topOffset + maxY;
210
+
211
+ // Visible space available in the canvas viewport
212
+ var scrollableViewportWidth = width - gridX;
213
+ var scrollableViewportHeight = height - gridY;
214
+ var lastLeftWithoutScroll = this.getLastLeft(state, null, scrollableViewportWidth - rowFooterWidth);
215
+ var lastLeftWithScroll = this.getLastLeft(state, null, scrollableViewportWidth - rowFooterWidth - scrollBarSize);
216
+ var lastTopWithoutScroll = this.getLastTop(state, null, scrollableViewportHeight - floatingBottomHeight);
217
+ var lastTopWithScroll = this.getLastTop(state, null, scrollableViewportHeight - floatingBottomHeight - scrollBarSize);
218
+ var lastLeft = lastLeftWithScroll;
219
+ var lastTop = lastTopWithScroll;
220
+ if (lastLeftWithoutScroll === 0 && lastTopWithoutScroll === 0) {
221
+ // Fully visible without any scroll bars
222
+ lastLeft = 0;
223
+ lastTop = 0;
224
+ }
225
+
226
+ // Calculate some metrics for the scroll bars
227
+ var hasHorizontalBar = lastLeft > 0;
228
+ var horizontalBarHeight = hasHorizontalBar ? scrollBarSize : 0;
229
+ var hasVerticalBar = lastTop > 0;
230
+ var verticalBarWidth = hasVerticalBar ? scrollBarSize : 0;
231
+ var barLeft = gridX;
232
+ var barTop = columnHeaderMaxDepth * columnHeaderHeight;
233
+ var barWidth = width - barLeft - verticalBarWidth;
234
+ var barHeight = height - barTop - horizontalBarHeight;
235
+
236
+ // How big the scroll handle is relative to the bar
237
+ var horizontalHandlePercent = columnCount === 1 ? barWidth / scrollableContentWidth : (columnCount - lastLeft) / columnCount;
238
+ var verticalHandlePercent = rowCount === 1 ? barHeight / scrollableContentHeight : (rowCount - lastTop) / rowCount;
239
+ var handleWidth = hasHorizontalBar ? clamp(barWidth * horizontalHandlePercent, minScrollHandleSize, barWidth - 1) : 0;
240
+ var handleHeight = hasVerticalBar ? clamp(barHeight * verticalHandlePercent, minScrollHandleSize, barHeight - 1) : 0;
241
+ var leftColumnWidth = getOrThrow(allColumnWidths, left, 0);
242
+ var topRowHeight = getOrThrow(allRowHeights, top, 0);
243
+ var leftOffsetPercent = leftColumnWidth > 0 ? leftOffset / leftColumnWidth : 0;
244
+ var topOffsetPercent = topRowHeight > 0 ? topOffset / topRowHeight : 0;
245
+
246
+ // How much of the available space has been scrolled
247
+ var horizontalScrollPercent = columnCount === 1 ? leftOffset / (scrollableContentWidth - scrollableViewportWidth) : (left + leftOffsetPercent) / lastLeft;
248
+ var verticalScrollPercent = rowCount === 1 ? topOffset / (scrollableContentHeight - scrollableViewportHeight) : (top + topOffsetPercent) / lastTop;
249
+ var scrollX = hasHorizontalBar ? horizontalScrollPercent * (barWidth - handleWidth) : 0;
250
+ var scrollY = hasVerticalBar ? verticalScrollPercent * (barHeight - handleHeight) : 0;
251
+
252
+ // Now add the floating sections positions
253
+ var floatingRows = [...Array(floatingTopRowCount).keys(), ...[...Array(floatingBottomRowCount).keys()].map(i => rowCount - i - 1)];
254
+ var allRowYs = new Map([...visibleRowYs, ...this.getFloatingRowYs(state, allRowHeights, Math.floor(height - gridY - horizontalBarHeight))]);
255
+ var floatingColumns = [...Array(floatingLeftColumnCount).keys(), ...[...Array(floatingRightColumnCount).keys()].map(i => columnCount - i - 1)];
256
+ var allColumnXs = new Map([...visibleColumnXs, ...this.getFloatingColumnXs(state, allColumnWidths, Math.floor(width - gridX - verticalBarWidth))]);
257
+ var draggingColumns = [];
258
+ if (draggingColumn) {
259
+ for (var i = draggingColumn.range[0]; i <= draggingColumn.range[1]; i += 1) {
260
+ draggingColumns.push(i);
261
+ if (!allColumnWidths.has(i)) {
262
+ allColumnWidths.set(i, this.getVisibleColumnWidth(i, state));
263
+ }
264
+ if (!allColumnXs.has(i)) {
265
+ allColumnXs.set(i, 0);
266
+ }
267
+ }
268
+ }
269
+ var allRows = visibleRows.concat(floatingRows);
270
+ var allColumns = visibleColumns.concat(floatingColumns).concat(draggingColumns);
271
+ var modelRows = this.getModelRows(allRows, state);
272
+ var modelColumns = this.getModelColumns(allColumns, state);
273
+ var visibleRowTreeBoxes = this.getVisibleRowTreeBoxes(allRowHeights, modelRows, state);
274
+
275
+ // Calculate the visible viewport based on scroll position and floating sections
276
+ var topVisible = this.getTopVisible(state, allRowYs, allRowHeights, visibleRows);
277
+ var leftVisible = this.getLeftVisible(state, allColumnXs, allColumnWidths, visibleColumns);
278
+ var bottomVisible = lastTop > 0 ? this.getBottomVisible(state, allRowYs, allRowHeights, visibleRows, gridY) : bottom;
279
+ var rightVisible = lastLeft > 0 ? this.getRightVisible(state, allColumnXs, allColumnWidths, visibleColumns, gridX) : right;
280
+ var {
281
+ fontWidths,
282
+ userColumnWidths,
283
+ userRowHeights,
284
+ calculatedRowHeights,
285
+ calculatedColumnWidths
286
+ } = this;
287
+ return {
288
+ // Row/Column metrics from model
289
+ rowHeight,
290
+ rowHeaderWidth,
291
+ rowFooterWidth,
292
+ rowCount,
293
+ columnWidth,
294
+ columnCount,
295
+ columnHeaderHeight,
296
+ // Floating row and column counts
297
+ floatingTopRowCount,
298
+ floatingBottomRowCount,
299
+ floatingLeftColumnCount,
300
+ floatingRightColumnCount,
301
+ // The grid offset from the top left
302
+ gridX,
303
+ gridY,
304
+ // Index of non-hidden row/columns
305
+ firstRow,
306
+ firstColumn,
307
+ // The amount of padding for tree (if applicable)
308
+ treePaddingX,
309
+ treePaddingY,
310
+ // What viewport is currently visible, limited by data size
311
+ left,
312
+ top,
313
+ bottom,
314
+ right,
315
+ topOffset,
316
+ leftOffset,
317
+ // Bottom and right that are fully visible, not overlapped by scroll bars or anything
318
+ topVisible,
319
+ leftVisible,
320
+ bottomVisible,
321
+ rightVisible,
322
+ // Bottom and right of the viewport, not limited by data size
323
+ bottomViewport,
324
+ rightViewport,
325
+ // Canvas width/height
326
+ width,
327
+ height,
328
+ // Max x/y coordinate of the grid (does not include headers)
329
+ maxX,
330
+ maxY,
331
+ // Last valid column/row that can be the left/top of the grid
332
+ lastLeft,
333
+ lastTop,
334
+ // Scroll bar metrics
335
+ barHeight,
336
+ barTop,
337
+ barWidth,
338
+ barLeft,
339
+ handleHeight,
340
+ handleWidth,
341
+ hasHorizontalBar,
342
+ hasVerticalBar,
343
+ verticalBarWidth,
344
+ horizontalBarHeight,
345
+ // The vertical x/y scroll amount
346
+ scrollX,
347
+ scrollY,
348
+ scrollableContentWidth,
349
+ scrollableContentHeight,
350
+ scrollableViewportWidth,
351
+ scrollableViewportHeight,
352
+ // Array of visible rows/columns, by grid index
353
+ visibleRows,
354
+ visibleColumns,
355
+ // Map of the height/width of visible rows/columns
356
+ visibleRowHeights,
357
+ visibleColumnWidths,
358
+ // Array of floating rows/columns, by grid index
359
+ floatingRows,
360
+ floatingColumns,
361
+ // Array of all rows/columns, visible and floating, by grid index
362
+ allRows,
363
+ allColumns,
364
+ // Map of the height/width of visible rows/columns
365
+ allRowHeights,
366
+ allColumnWidths,
367
+ // Floating metrics
368
+ floatingTopHeight,
369
+ floatingBottomHeight,
370
+ floatingLeftWidth,
371
+ floatingRightWidth,
372
+ // Map of the X/Y coordinates of the visible rows/columns, from the top left of the grid
373
+ visibleRowYs,
374
+ visibleColumnXs,
375
+ // Map of the X/Y coordinates of all rows/columns, visible and floating, from the top left of the grid
376
+ allRowYs,
377
+ allColumnXs,
378
+ // The boxes user can click on for expanding/collapsing tree rows
379
+ visibleRowTreeBoxes,
380
+ // Mapping from visible row indexes to the model row/columns they pull from
381
+ modelRows,
382
+ modelColumns,
383
+ movedRows,
384
+ movedColumns,
385
+ // Map of the width of the fonts
386
+ fontWidths,
387
+ // Map of user set column/row width/height
388
+ userColumnWidths,
389
+ userRowHeights,
390
+ // Map of calculated row/column height/width
391
+ calculatedRowHeights,
392
+ calculatedColumnWidths,
393
+ columnHeaderMaxDepth
394
+ };
395
+ }
396
+
397
+ /**
398
+ * The x offset of the grid
399
+ * @param state The current grid state
400
+ * @returns x value of the left side of the first cell
401
+ */
402
+ getGridX(state) {
403
+ var {
404
+ theme
405
+ } = state;
406
+ var {
407
+ rowHeaderWidth
408
+ } = theme;
409
+ return rowHeaderWidth;
410
+ }
411
+
412
+ /**
413
+ * The y offset of the grid
414
+ * @param state The current grid state
415
+ * @returns y value of the top side of the first cell
416
+ */
417
+ getGridY(state) {
418
+ var {
419
+ theme,
420
+ model
421
+ } = state;
422
+ var {
423
+ columnHeaderHeight
424
+ } = theme;
425
+ var {
426
+ columnHeaderMaxDepth
427
+ } = model;
428
+ return columnHeaderMaxDepth * columnHeaderHeight;
429
+ }
430
+
431
+ /**
432
+ * The height of the "visible" area (excludes floating areas)
433
+ * @param state The current grid state
434
+ * @param visibleRowHeights All the visible row heights
435
+ * @returns The visible height in pixels
436
+ */
437
+ getVisibleHeight(state) {
438
+ var visibleRowHeights = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getFloatingRowHeights(state);
439
+ var {
440
+ height,
441
+ theme
442
+ } = state;
443
+ var {
444
+ scrollBarSize
445
+ } = theme;
446
+ var gridY = this.getGridY(state);
447
+ var floatingBottomHeight = this.getFloatingBottomHeight(state, visibleRowHeights);
448
+ var floatingTopHeight = this.getFloatingTopHeight(state, visibleRowHeights);
449
+ return height - floatingBottomHeight - floatingTopHeight - gridY - scrollBarSize;
450
+ }
451
+
452
+ /**
453
+ * The width of the "visible" area (excludes floating areas)
454
+ * @param state The current grid state
455
+ * @param visibleColumnWidths All the visible column widths
456
+ * @returns The visible width in pixels
457
+ */
458
+ getVisibleWidth(state) {
459
+ var visibleColumnWidths = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getFloatingColumnWidths(state);
460
+ var {
461
+ width,
462
+ theme
463
+ } = state;
464
+ var {
465
+ scrollBarSize,
466
+ rowFooterWidth
467
+ } = theme;
468
+ var gridX = this.getGridX(state);
469
+ var floatingRightWidth = this.getFloatingRightWidth(state, visibleColumnWidths);
470
+ var floatingLeftWidth = this.getFloatingLeftWidth(state, visibleColumnWidths);
471
+ return width - floatingLeftWidth - floatingRightWidth - gridX - scrollBarSize - rowFooterWidth;
472
+ }
473
+
474
+ /**
475
+ * Retrieve the index of the first non-hidden item
476
+ * @param itemSizes The size of the items in this dimension
477
+ * @param getModelIndex A function to map from the Index to the ModelIndex
478
+ * @param state The current grid state
479
+ * @returns The first item that is not hidden
480
+ */
481
+ getFirstIndex(itemSizes, getModelIndex, state) {
482
+ // We only need to check at the very most the number of items the user has hidden + 1
483
+ var max = itemSizes.size + 1;
484
+ for (var i = 0; i < max; i += 1) {
485
+ var modelIndex = getModelIndex(i, state);
486
+ if (itemSizes.get(modelIndex) !== 0) {
487
+ return i;
488
+ }
489
+ }
490
+ return 0;
491
+ }
492
+
493
+ /**
494
+ * Get the first column index that isn't hidden
495
+ * @param state The current grid state
496
+ * @returns The first column that is not hidden
497
+ */
498
+ getFirstColumn(state) {
499
+ return this.getFirstIndex(this.userColumnWidths, this.getModelColumn.bind(this), state);
500
+ }
501
+
502
+ /**
503
+ * Get the first row index that isn't hidden
504
+ * @param state The current grid state
505
+ * @returns The first row that is not hidden
506
+ */
507
+ getFirstRow(state) {
508
+ return this.getFirstIndex(this.userRowHeights, this.getModelRow.bind(this), state);
509
+ }
510
+
511
+ /**
512
+ * Get the last column that can be the left most column (e.g. scrolled to the right)
513
+ * If no right column is provided, then the last column is used.
514
+ * @param state The current grid state
515
+ * @param right The right-most column to be visible, or null to default to last cell
516
+ * @param visibleWidth The width of the "visible" area (excluding floating items)
517
+ * @returns The index of the last left visible column
518
+ */
519
+ getLastLeft(state, right, visibleWidth) {
520
+ var {
521
+ model
522
+ } = state;
523
+ var {
524
+ columnCount,
525
+ floatingRightColumnCount
526
+ } = model;
527
+ var lastLeft = Math.max(0, columnCount - floatingRightColumnCount - 1);
528
+ if (right != null) {
529
+ lastLeft = right;
530
+ }
531
+ var x = 0;
532
+ while (lastLeft >= 0) {
533
+ var columnWidth = this.getVisibleColumnWidth(lastLeft, state);
534
+ x += columnWidth;
535
+ if (x >= visibleWidth) {
536
+ return clamp(lastLeft + 1, 0, right !== null && right !== void 0 ? right : columnCount - 1);
537
+ }
538
+ lastLeft -= 1;
539
+ }
540
+ return 0;
541
+ }
542
+
543
+ /**
544
+ * The last row that can be the top row (e.g. scrolled to the bottom)
545
+ * If no bottom row is provided, then the last row that is not floating is used
546
+ * @param state The current grid state
547
+ * @param bottom The bottom-most row to be visible, or null to default to last cell
548
+ * @param visibleHeight The height of the "visible" area (excluding floating items)
549
+ * @returns The index of the last top visible row
550
+ */
551
+ getLastTop(state, bottom, visibleHeight) {
552
+ var {
553
+ model
554
+ } = state;
555
+ var {
556
+ rowCount,
557
+ floatingBottomRowCount
558
+ } = model;
559
+ var lastTop = Math.max(0, rowCount - floatingBottomRowCount - 1);
560
+ if (bottom != null) {
561
+ lastTop = bottom;
562
+ }
563
+ var y = 0;
564
+ while (lastTop >= 0) {
565
+ var rowHeight = this.getVisibleRowHeight(lastTop, state);
566
+ y += rowHeight;
567
+ if (y >= visibleHeight) {
568
+ return clamp(lastTop + 1, 0, rowCount - 1);
569
+ }
570
+ lastTop -= 1;
571
+ }
572
+ return 0;
573
+ }
574
+
575
+ /**
576
+ * Retrieve the top row to scroll to so the passed in `topVisible` is completely visible, taking the floating rows into account.
577
+ * The `top` row is at the top underneath any floating rows, whereas `topVisible` is visible below the floating rows.
578
+ * If there are no floating rows, they should be the same value.
579
+ * @param state The grid metric state
580
+ * @param topVisible The top row to be visible
581
+ * @returns The index of the top row to scroll to (under the floating top rows)
582
+ */
583
+ getTopForTopVisible(state, topVisible) {
584
+ var floatingTopHeight = this.getFloatingTopHeight(state);
585
+ var top = topVisible;
586
+ var y = 0;
587
+ while (top > 0 && y < floatingTopHeight) {
588
+ top -= 1;
589
+ y += this.getVisibleRowHeight(top, state);
590
+ }
591
+ return top;
592
+ }
593
+
594
+ /**
595
+ * Retrieve the top row to scroll to so the passed in `bottomVisible` is completely visible
596
+ * at the bottom of the visible viewport, taking the floating rows into account.
597
+ * @param state The grid metric state
598
+ * @param bottomVisible The bottom row to be visible
599
+ * @returns The index of the top row to scroll to (under the floating top rows)
600
+ */
601
+ getTopForBottomVisible(state, bottomVisible) {
602
+ var {
603
+ height
604
+ } = state;
605
+ var gridY = this.getGridY(state);
606
+ var floatingBottomHeight = this.getFloatingBottomHeight(state);
607
+ var availableHeight = height - gridY - floatingBottomHeight;
608
+ return this.getLastTop(state, bottomVisible, availableHeight);
609
+ }
610
+
611
+ /**
612
+ * Retrieve the left column to scroll to so the passed in `leftVisible` is completely visible
613
+ * at the left of the visible viewport, taking the floating columns into account.
614
+ * @param state The grid metric state
615
+ * @param leftVisible The left column to be visible
616
+ * @returns The index of the left column to scroll to (under the floating left columns)
617
+ */
618
+ getLeftForLeftVisible(state, leftVisible) {
619
+ var floatingLeftWidth = this.getFloatingLeftWidth(state);
620
+ var left = leftVisible;
621
+ var x = 0;
622
+ while (left > 0 && x < floatingLeftWidth) {
623
+ left -= 1;
624
+ x += this.getVisibleColumnWidth(left, state);
625
+ }
626
+ return left;
627
+ }
628
+
629
+ /**
630
+ * Retrieve the left column to scroll to so the passed in `rightVisible` is completely visible
631
+ * at the right of the visible viewport, taking the floating columns into account.
632
+ * @param state The grid metric state
633
+ * @param rightVisible The right column to be visible
634
+ * @returns The index of the left column to scroll to (under the floating left columns)
635
+ */
636
+ getLeftForRightVisible(state, rightVisible) {
637
+ var {
638
+ width
639
+ } = state;
640
+ var gridX = this.getGridX(state);
641
+ var floatingRightWidth = this.getFloatingRightWidth(state);
642
+ var availableWidth = width - gridX - floatingRightWidth;
643
+ return this.getLastLeft(state, rightVisible, availableWidth);
644
+ }
645
+
646
+ /**
647
+ * Retrieve a map of the height of each floating row
648
+ * @param state The grid metric state
649
+ * @returns The heights of all the floating rows
650
+ */
651
+ getFloatingRowHeights(state) {
652
+ var {
653
+ model
654
+ } = state;
655
+ var {
656
+ floatingTopRowCount,
657
+ floatingBottomRowCount,
658
+ rowCount
659
+ } = model;
660
+ var rowHeights = new Map();
661
+ for (var i = 0; i < floatingTopRowCount && i < rowCount; i += 1) {
662
+ rowHeights.set(i, this.getVisibleRowHeight(i, state));
663
+ }
664
+ for (var _i2 = 0; _i2 < floatingBottomRowCount && rowCount - _i2 - 1 >= 0; _i2 += 1) {
665
+ var row = rowCount - _i2 - 1;
666
+ rowHeights.set(row, this.getVisibleRowHeight(row, state));
667
+ }
668
+ return rowHeights;
669
+ }
670
+
671
+ /**
672
+ * Retrieve a map of the height of all the visible rows (non-floating)
673
+ * @param state The grid metric state
674
+ * @returns The heights of all the visible rows
675
+ */
676
+ getVisibleRowHeights(state) {
677
+ var {
678
+ top,
679
+ topOffset,
680
+ height,
681
+ model
682
+ } = state;
683
+ var y = 0;
684
+ var row = top;
685
+ var rowHeights = new Map();
686
+ var {
687
+ rowCount
688
+ } = model;
689
+ while (y < height + topOffset && row < rowCount) {
690
+ var rowHeight = this.getVisibleRowHeight(row, state);
691
+ rowHeights.set(row, rowHeight);
692
+ y += rowHeight;
693
+ row += 1;
694
+ }
695
+ return rowHeights;
696
+ }
697
+
698
+ /**
699
+ * Retrieve a map of the width of each floating column
700
+ * @param state The grid metric state
701
+ * @param firstColumn The first non-hidden column
702
+ * @param treePaddingX The amount of padding taken up for the tree expansion buttons
703
+ * @returns The widths of all the floating columns
704
+ */
705
+ getFloatingColumnWidths(state) {
706
+ var firstColumn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getFirstColumn(state);
707
+ var treePaddingX = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.calculateTreePaddingX(state);
708
+ var {
709
+ model
710
+ } = state;
711
+ var {
712
+ columnCount,
713
+ floatingLeftColumnCount,
714
+ floatingRightColumnCount
715
+ } = model;
716
+ var columnWidths = new Map();
717
+ for (var i = 0; i < floatingLeftColumnCount && i < columnCount; i += 1) {
718
+ columnWidths.set(i, this.getVisibleColumnWidth(i, state, firstColumn, treePaddingX));
719
+ }
720
+ for (var _i3 = 0; _i3 < floatingRightColumnCount && columnCount - _i3 - 1 >= 0; _i3 += 1) {
721
+ var column = columnCount - _i3 - 1;
722
+ columnWidths.set(column, this.getVisibleColumnWidth(column, state, firstColumn, treePaddingX));
723
+ }
724
+ return columnWidths;
725
+ }
726
+
727
+ /**
728
+ * Retrieve a map of the width of all the visible columns (non-floating)
729
+ * @param state The grid metric state
730
+ * @returns The widths of all the visible columns
731
+ */
732
+ getVisibleColumnWidths(state) {
733
+ var firstColumn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getFirstColumn(state);
734
+ var treePaddingX = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.calculateTreePaddingX(state);
735
+ var {
736
+ left,
737
+ leftOffset,
738
+ width,
739
+ model
740
+ } = state;
741
+ var x = 0;
742
+ var column = left;
743
+ var columnWidths = new Map();
744
+ var {
745
+ columnCount
746
+ } = model;
747
+ while (x < width + leftOffset && column < columnCount) {
748
+ var columnWidth = this.getVisibleColumnWidth(column, state, firstColumn, treePaddingX);
749
+ columnWidths.set(column, columnWidth);
750
+ x += columnWidth;
751
+ column += 1;
752
+ }
753
+ return columnWidths;
754
+ }
755
+
756
+ /**
757
+ * Retrieve a map of all the floating columns to their x coordinate
758
+ * @param state The grid metric state
759
+ * @param columnWidthMap Map from visible index to column width
760
+ * @param maxX The maximum X size for the grid
761
+ * @returns Map of the x coordinate of all floating columns
762
+ */
763
+ getFloatingColumnXs(state, columnWidthMap, maxX) {
764
+ var {
765
+ model
766
+ } = state;
767
+ var {
768
+ columnCount,
769
+ floatingLeftColumnCount,
770
+ floatingRightColumnCount
771
+ } = model;
772
+ return getFloatingCoordinates(floatingLeftColumnCount, floatingRightColumnCount, columnCount, maxX, columnWidthMap);
773
+ }
774
+
775
+ /**
776
+ * Retrieve a map of all the visible columns to their x coordinate.
777
+ * Starts at leftOffset with the first index in `visibleColumns`, then
778
+ * calculates all the coordinates from there
779
+ * @param visibleColumnWidths Map of visible column index to widths
780
+ * @param visibleColumns All visible columns
781
+ * @param leftOffset The left scroll offset
782
+ * @returns Map of the x coordinate of all visible columns
783
+ */
784
+ getVisibleColumnXs(visibleColumnWidths, visibleColumns, leftOffset) {
785
+ var visibleColumnXs = new Map();
786
+ var x = -leftOffset;
787
+ for (var i = 0; i < visibleColumns.length; i += 1) {
788
+ var column = visibleColumns[i];
789
+ var columnWidth = getOrThrow(visibleColumnWidths, column);
790
+ visibleColumnXs.set(column, x);
791
+ x += columnWidth;
792
+ }
793
+ return visibleColumnXs;
794
+ }
795
+
796
+ /**
797
+ * Retrieve a map of all the floating rows to their y coordinate
798
+ * @param state The grid metric state
799
+ * @param rowHeightMap Map of visible index to row height
800
+ * @param maxY The maximum Y size for the grid
801
+ * @returns Map of the y coordinate of all floating rows
802
+ */
803
+ getFloatingRowYs(state, rowHeightMap, maxY) {
804
+ var {
805
+ model
806
+ } = state;
807
+ var {
808
+ floatingTopRowCount,
809
+ floatingBottomRowCount,
810
+ rowCount
811
+ } = model;
812
+ return getFloatingCoordinates(floatingTopRowCount, floatingBottomRowCount, rowCount, maxY, rowHeightMap);
813
+ }
814
+
815
+ /**
816
+ * Retrieve a map of all the visible rows to their y coordinate.
817
+ * Starts at topOffset with the first index in `visibleRows`, then
818
+ * calculates all the coordinates from there
819
+ * @param visibleRowHeights Map of visible row index to heights
820
+ * @param visibleRows All visible rows
821
+ * @param topOffset The top scroll offset
822
+ * @returns Map of the y coordinate of all visible rows
823
+ */
824
+ getVisibleRowYs(visibleRowHeights, visibleRows, topOffset) {
825
+ var visibleRowYs = new Map();
826
+ var y = -topOffset;
827
+ for (var i = 0; i < visibleRows.length; i += 1) {
828
+ var row = visibleRows[i];
829
+ var rowHeight = getOrThrow(visibleRowHeights, row);
830
+ visibleRowYs.set(row, y);
831
+ y += rowHeight;
832
+ }
833
+ return visibleRowYs;
834
+ }
835
+
836
+ /**
837
+ * Calculates the tree box click areas that are visible. In relation to the columnX/rowY
838
+ * @param visibleRowHeights Map of visible index to row height
839
+ * @param modelRows Map from visible `Index` to `ModelIndex`
840
+ * @param state The grid metric state
841
+ * @returns Coordinates of tree boxes for each row
842
+ */
843
+ getVisibleRowTreeBoxes(visibleRowHeights, modelRows, state) {
844
+ var visibleRowTreeBoxes = new Map();
845
+ var {
846
+ model,
847
+ theme
848
+ } = state;
849
+ var {
850
+ treeDepthIndent,
851
+ treeHorizontalPadding
852
+ } = theme;
853
+ if (isExpandableGridModel(model) && model.hasExpandableRows) {
854
+ visibleRowHeights.forEach((rowHeight, row) => {
855
+ var modelRow = getOrThrow(modelRows, row);
856
+ if (model.isRowExpandable(modelRow)) {
857
+ var depth = model.depthForRow(modelRow);
858
+ var x1 = depth * treeDepthIndent + treeHorizontalPadding;
859
+ var x2 = (depth + 1) * treeDepthIndent + treeHorizontalPadding;
860
+ var y1 = 0;
861
+ var y2 = rowHeight;
862
+ visibleRowTreeBoxes.set(row, {
863
+ x1,
864
+ y1,
865
+ x2,
866
+ y2
867
+ });
868
+ }
869
+ });
870
+ }
871
+ return visibleRowTreeBoxes;
872
+ }
873
+
874
+ /**
875
+ * Get the total width of the floating columns on the left
876
+ * @param state The grid metric state
877
+ * @param columnWidths Map of column index to width
878
+ * @returns The total width of the floating left section
879
+ */
880
+ getFloatingLeftWidth(state) {
881
+ var columnWidths = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getFloatingColumnWidths(state);
882
+ var {
883
+ model
884
+ } = state;
885
+ var {
886
+ floatingLeftColumnCount
887
+ } = model;
888
+ var floatingWidth = 0;
889
+ for (var i = 0; i < floatingLeftColumnCount; i += 1) {
890
+ floatingWidth += getOrThrow(columnWidths, i);
891
+ }
892
+ return floatingWidth;
893
+ }
894
+
895
+ /**
896
+ * Get the total width of the floating columns on the right
897
+ * @param state The grid metric state
898
+ * @param columnWidths Map of column index to width
899
+ * @returns The total width of the floating right section
900
+ */
901
+ getFloatingRightWidth(state) {
902
+ var columnWidths = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getFloatingColumnWidths(state);
903
+ var {
904
+ model
905
+ } = state;
906
+ var {
907
+ floatingRightColumnCount,
908
+ columnCount
909
+ } = model;
910
+ var floatingWidth = 0;
911
+ for (var i = 0; i < floatingRightColumnCount; i += 1) {
912
+ floatingWidth += getOrThrow(columnWidths, columnCount - i - 1);
913
+ }
914
+ return floatingWidth;
915
+ }
916
+
917
+ /**
918
+ * Get the total height of the floating rows on the top
919
+ * @param state The grid metric state
920
+ * @param rowHeights Map of row index to height
921
+ * @returns The total height of the floating top section
922
+ */
923
+ getFloatingTopHeight(state) {
924
+ var rowHeights = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getFloatingRowHeights(state);
925
+ var {
926
+ model
927
+ } = state;
928
+ var {
929
+ floatingTopRowCount
930
+ } = model;
931
+ var floatingHeight = 0;
932
+ for (var i = 0; i < floatingTopRowCount; i += 1) {
933
+ floatingHeight += getOrThrow(rowHeights, i);
934
+ }
935
+ return floatingHeight;
936
+ }
937
+
938
+ /**
939
+ * Get the total height of the floating rows on the bottom
940
+ * @param state The grid metric state
941
+ * @param rowHeights Map of row index to height
942
+ * @returns The total height of the floating bottom section
943
+ */
944
+ getFloatingBottomHeight(state) {
945
+ var rowHeights = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getFloatingRowHeights(state);
946
+ var {
947
+ model
948
+ } = state;
949
+ var {
950
+ floatingBottomRowCount,
951
+ rowCount
952
+ } = model;
953
+ var floatingHeight = 0;
954
+ for (var i = 0; i < floatingBottomRowCount; i += 1) {
955
+ floatingHeight += getOrThrow(rowHeights, rowCount - i - 1);
956
+ }
957
+ return floatingHeight;
958
+ }
959
+
960
+ /**
961
+ * Retrieve the index of the first fully visible row in the "visible" viewport of the grid.
962
+ * E.g. First row visible after the floating rows, provided the visible rows.
963
+ * @param state The grid metric state
964
+ * @param visibleRowYs Map of row index to y coordinate
965
+ * @param visibleRowHeights Map of row index to height
966
+ * @param visibleRows Array of visible row indexes
967
+ * @returns Index of the top visible row
968
+ */
969
+ getTopVisible(state, visibleRowYs, visibleRowHeights, visibleRows) {
970
+ var floatingHeight = this.getFloatingTopHeight(state, visibleRowHeights);
971
+ for (var i = 0; i < visibleRows.length; i += 1) {
972
+ var row = visibleRows[i];
973
+ var y = getOrThrow(visibleRowYs, row);
974
+ if (y >= floatingHeight) {
975
+ return row;
976
+ }
977
+ }
978
+ return 0;
979
+ }
980
+
981
+ /**
982
+ * Retrieve the index of the first fully visible column in the "visible" viewport of the grid.
983
+ * E.g. First column visible after the floating columns, provided the visible columns.
984
+ * @param state The grid metric state
985
+ * @param visibleColumnXs Map of column index to x coordinate
986
+ * @param visibleColumnWidths Map of column index to widths
987
+ * @param visibleColumns Array of visible row indexes
988
+ * @returns Index of the left visible column
989
+ */
990
+ getLeftVisible(state, visibleColumnXs, visibleColumnWidths, visibleColumns) {
991
+ var floatingWidth = this.getFloatingLeftWidth(state, visibleColumnWidths);
992
+ for (var i = 0; i < visibleColumns.length; i += 1) {
993
+ var column = visibleColumns[i];
994
+ var x = getOrThrow(visibleColumnXs, column);
995
+ if (x >= floatingWidth) {
996
+ return column;
997
+ }
998
+ }
999
+ return 0;
1000
+ }
1001
+
1002
+ /**
1003
+ * Retrieve the index of the last fully visible row in the "visible" viewport of the grid.
1004
+ * E.g. Last row visible before the bottom floating rows, provided the visible rows.
1005
+ * @param state The grid metric state
1006
+ * @param visibleRowYs Map of row index to y coordinate
1007
+ * @param visibleRowHeights Map of row index to height
1008
+ * @param visibleRows Array of visible row indexes
1009
+ * @param gridY The starting y coordinate of the grid
1010
+ * @returns Index of the bottom visible row
1011
+ */
1012
+ getBottomVisible(state, visibleRowYs, visibleRowHeights, visibleRows, gridY) {
1013
+ var {
1014
+ height,
1015
+ theme
1016
+ } = state;
1017
+ var {
1018
+ scrollBarSize
1019
+ } = theme;
1020
+ var floatingHeight = this.getFloatingBottomHeight(state, visibleRowHeights);
1021
+ var visibleHeight = height - gridY - scrollBarSize - floatingHeight;
1022
+ for (var i = visibleRows.length - 1; i >= 0; i -= 1) {
1023
+ var row = visibleRows[i];
1024
+ var rowY = getOrThrow(visibleRowYs, row);
1025
+ var rowHeight = getOrThrow(visibleRowHeights, row);
1026
+ if (rowY + rowHeight <= visibleHeight) {
1027
+ return row;
1028
+ }
1029
+ }
1030
+ return 0;
1031
+ }
1032
+
1033
+ /**
1034
+ * Retrieve the index of the last fully visible column in the "visible" viewport of the grid.
1035
+ * E.g. Last column visible before the floating columns, provided the visible columns.
1036
+ * @param state The grid metric state
1037
+ * @param visibleColumnXs Map of column index to x coordinate
1038
+ * @param visibleColumnWidths Map of column index to widths
1039
+ * @param visibleColumns Array of visible column indexes
1040
+ * @returns Index of the right visible column
1041
+ */
1042
+ getRightVisible(state, visibleColumnXs, visibleColumnWidths, visibleColumns, gridX) {
1043
+ var {
1044
+ width,
1045
+ theme
1046
+ } = state;
1047
+ var {
1048
+ scrollBarSize
1049
+ } = theme;
1050
+ var floatingWidth = this.getFloatingRightWidth(state, visibleColumnWidths);
1051
+ var visibleWidth = width - gridX - scrollBarSize - floatingWidth;
1052
+ for (var i = visibleColumns.length - 1; i >= 0; i -= 1) {
1053
+ var column = visibleColumns[i];
1054
+ var columnX = getOrThrow(visibleColumnXs, column);
1055
+ var columnWidth = getOrThrow(visibleColumnWidths, column);
1056
+ if (columnX + columnWidth <= visibleWidth) {
1057
+ return column;
1058
+ }
1059
+ }
1060
+ return 0;
1061
+ }
1062
+
1063
+ /**
1064
+ * Retrieve the possible bottom of the visible viewport (not limited by data size)
1065
+ * @param state The grid metric state
1066
+ * @param visibleRows Array of visible row indexes
1067
+ * @param visibleRowYs Map of row index to y coordinate
1068
+ * @param visibleRowHeights Map of row index to height
1069
+ * @returns The index of the bottom viewport possible
1070
+ */
1071
+ getBottomViewport(state, visibleRows, visibleRowYs, visibleRowHeights) {
1072
+ var {
1073
+ height,
1074
+ theme
1075
+ } = state;
1076
+ var {
1077
+ rowHeight
1078
+ } = theme;
1079
+ return this.getLastIndexViewport(visibleRows, visibleRowYs, visibleRowHeights, height, rowHeight);
1080
+ }
1081
+
1082
+ /**
1083
+ * Retrieve the possible right of the visible viewport (not limited by data size)
1084
+ * @param state The grid metric state
1085
+ * @param visibleColumns Array of visible column indexes
1086
+ * @param visibleColumnXs Map of column index to x coordinate
1087
+ * @param visibleColumnWidths Map of column index to width
1088
+ * @returns The index of the right viewport possible
1089
+ */
1090
+ getRightViewport(state, visibleColumns, visibleColumnXs, visibleColumnWidths) {
1091
+ var {
1092
+ width,
1093
+ theme
1094
+ } = state;
1095
+ var {
1096
+ columnWidth
1097
+ } = theme;
1098
+ return this.getLastIndexViewport(visibleColumns, visibleColumnXs, visibleColumnWidths, width, columnWidth);
1099
+ }
1100
+
1101
+ /**
1102
+ * Get the Index of the of the last index visible
1103
+ * @param items Array of visible item indexes
1104
+ * @param itemXs Map of index to coordinate
1105
+ * @param itemSizes Map of index to size
1106
+ * @param maxSize Full size of the grid
1107
+ * @param defaultItemSize Default size of an item
1108
+ * @returns The Index of the last index visible
1109
+ */
1110
+ getLastIndexViewport(items, itemXs, itemSizes, maxSize, defaultItemSize) {
1111
+ var lastIndex = 0;
1112
+ var dataSize = 0;
1113
+ if (items.length > 0) {
1114
+ lastIndex = items[items.length - 1];
1115
+ dataSize = getOrThrow(itemXs, lastIndex) + getOrThrow(itemSizes, lastIndex);
1116
+ }
1117
+ if (dataSize < maxSize) {
1118
+ lastIndex += Math.ceil((maxSize - dataSize) / defaultItemSize);
1119
+ }
1120
+ return lastIndex;
1121
+ }
1122
+
1123
+ /**
1124
+ * Get the size from the provided size map of the specified item
1125
+ * @param modelIndex The model index to get the size for
1126
+ * @param userSizes The user set sizes
1127
+ * @param getDefaultSize Method to get the default size for this item
1128
+ * @returns The size from the provided size map of the specified item
1129
+ */
1130
+ getVisibleItemSize(modelIndex, userSizes, getDefaultSize) {
1131
+ var _userSizes$get;
1132
+ return (_userSizes$get = userSizes.get(modelIndex)) !== null && _userSizes$get !== void 0 ? _userSizes$get : getDefaultSize();
1133
+ }
1134
+
1135
+ /**
1136
+ * Get the height of the specified row
1137
+ * @param row Index of the row to get the height of
1138
+ * @param state The grid metric state
1139
+ * @returns The height of the row specified
1140
+ */
1141
+ getVisibleRowHeight(row, state) {
1142
+ var modelRow = this.getModelRow(row, state);
1143
+ var calculatedHeight = this.calculateRowHeight(row, modelRow, state); // Need to call this so calculated map is always populated
1144
+
1145
+ return this.getVisibleItemSize(modelRow, this.userRowHeights, () => {
1146
+ var initialHeight = this.initialRowHeights.get(modelRow);
1147
+ if (initialHeight !== undefined) {
1148
+ return initialHeight;
1149
+ }
1150
+ return calculatedHeight;
1151
+ });
1152
+ }
1153
+
1154
+ /**
1155
+ * Get the width of the specified column
1156
+ * @param column Index of the column to get the width of
1157
+ * @param state The grid metric state
1158
+ * @param firstColumn Index of first visible column
1159
+ * @param treePaddingX The amount of tree padding to add to the first visible column
1160
+ * @returns The width of the column
1161
+ */
1162
+ getVisibleColumnWidth(column, state) {
1163
+ var firstColumn = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getFirstColumn(state);
1164
+ var treePaddingX = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : this.calculateTreePaddingX(state);
1165
+ var modelColumn = this.getModelColumn(column, state);
1166
+
1167
+ // Need to call this so calculated map is always populated
1168
+ var calculatedWidth = this.calculateColumnWidth(column, modelColumn, state, firstColumn, treePaddingX);
1169
+ return this.getVisibleItemSize(modelColumn, this.userColumnWidths, () => {
1170
+ var initialWidth = this.initialColumnWidths.get(modelColumn);
1171
+ if (initialWidth !== undefined) {
1172
+ return initialWidth;
1173
+ }
1174
+ return calculatedWidth;
1175
+ });
1176
+ }
1177
+
1178
+ /**
1179
+ * Get a map of VisibleIndex to ModelIndex
1180
+ * @param visibleRows Array of visible row indexes
1181
+ * @param state The grid metric state
1182
+ * @returns Map of VisibleIndex to ModelIndex
1183
+ */
1184
+ getModelRows(visibleRows, state) {
1185
+ var modelRows = new Map();
1186
+ for (var i = 0; i < visibleRows.length; i += 1) {
1187
+ var visibleRow = visibleRows[i];
1188
+ var modelRow = this.getModelRow(visibleRow, state);
1189
+ modelRows.set(visibleRow, modelRow);
1190
+ }
1191
+ return modelRows;
1192
+ }
1193
+
1194
+ /**
1195
+ * Get the ModelIndex of the specified row
1196
+ * @param visibleRow Index of the row
1197
+ * @param state The grid metric state
1198
+ * @returns ModelIndex of the row
1199
+ */
1200
+ getModelRow(visibleRow, state) {
1201
+ if (this.modelRows.has(visibleRow)) {
1202
+ return getOrThrow(this.modelRows, visibleRow);
1203
+ }
1204
+ var {
1205
+ movedRows
1206
+ } = state;
1207
+ var modelRow = GridUtils.getModelIndex(visibleRow, movedRows);
1208
+ this.modelRows.set(visibleRow, modelRow);
1209
+ return modelRow;
1210
+ }
1211
+
1212
+ /**
1213
+ * Get a map of Index to ModelIndex. Applies the move operations to get the transformation.
1214
+ * @param visibleColumns Array of visible column indexes
1215
+ * @param state The grid metric state
1216
+ * @returns Map of Index to ModelIndex
1217
+ */
1218
+ getModelColumns(visibleColumns, state) {
1219
+ var modelColumns = new Map();
1220
+ for (var i = 0; i < visibleColumns.length; i += 1) {
1221
+ var visibleColumn = visibleColumns[i];
1222
+ var modelColumn = this.getModelColumn(visibleColumn, state);
1223
+ modelColumns.set(visibleColumn, modelColumn);
1224
+ }
1225
+ return modelColumns;
1226
+ }
1227
+
1228
+ /**
1229
+ * Get the ModelIndex of the specified column
1230
+ * @param visibleColumn Index of the column
1231
+ * @param state The grid metric state
1232
+ * @returns ModelIndex of the column
1233
+ */
1234
+ getModelColumn(visibleColumn, state) {
1235
+ var hasVisibleColumn = this.modelColumns.has(visibleColumn);
1236
+ if (hasVisibleColumn) {
1237
+ return getOrThrow(this.modelColumns, visibleColumn);
1238
+ }
1239
+ var {
1240
+ movedColumns
1241
+ } = state;
1242
+ var modelColumn = GridUtils.getModelIndex(visibleColumn, movedColumns);
1243
+ this.modelColumns.set(visibleColumn, modelColumn);
1244
+ return modelColumn;
1245
+ }
1246
+
1247
+ /**
1248
+ * Calculate the height of the row specified.
1249
+ * @param row Index of the row to calculate the height for
1250
+ * @param modelRow ModelIndex of the row to calculate the height
1251
+ * @param state The grid metric state
1252
+ * @returns The height of the row
1253
+ */
1254
+ calculateRowHeight(row, modelRow, state) {
1255
+ var {
1256
+ theme
1257
+ } = state;
1258
+ var {
1259
+ autoSizeRows,
1260
+ rowHeight
1261
+ } = theme;
1262
+ if (!autoSizeRows) {
1263
+ return rowHeight;
1264
+ }
1265
+ var cachedValue = this.calculatedRowHeights.get(modelRow);
1266
+ if (cachedValue != null) {
1267
+ return cachedValue;
1268
+ }
1269
+
1270
+ // Not sure how to accurately get the height of text. For now just return the theme height.
1271
+ this.calculatedRowHeights.set(modelRow, Math.ceil(rowHeight));
1272
+ trimMap(this.calculatedRowHeights);
1273
+ return rowHeight;
1274
+ }
1275
+
1276
+ /**
1277
+ * Calculates the column width based on the provided column model index
1278
+ * @param column Index of the column to calculate the width for
1279
+ * @param modelColumn ModelIndex of the column to calculate the width
1280
+ * @param state The grid metric state
1281
+ * @param firstColumn The first visible column
1282
+ * @param treePaddingX Tree padding offset for expandable rows
1283
+ * @returns The width of the column
1284
+ */
1285
+ calculateColumnWidth(column, modelColumn, state) {
1286
+ var firstColumn = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : this.getFirstColumn(state);
1287
+ var treePaddingX = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : this.calculateTreePaddingX(state);
1288
+ var {
1289
+ theme
1290
+ } = state;
1291
+ var {
1292
+ autoSizeColumns,
1293
+ minColumnWidth
1294
+ } = theme;
1295
+ if (!autoSizeColumns) {
1296
+ var {
1297
+ columnWidth: _columnWidth
1298
+ } = theme;
1299
+ return _columnWidth;
1300
+ }
1301
+ var headerWidth = this.calculateColumnHeaderWidth(modelColumn, state);
1302
+ var dataWidth = this.calculateColumnDataWidth(modelColumn, state);
1303
+ var cachedValue = this.calculatedColumnWidths.get(modelColumn);
1304
+ var columnWidth = Math.ceil(Math.max(headerWidth, dataWidth));
1305
+ columnWidth = Math.max(minColumnWidth, columnWidth);
1306
+ if (cachedValue != null && cachedValue > columnWidth) {
1307
+ columnWidth = cachedValue;
1308
+ } else {
1309
+ this.calculatedColumnWidths.set(modelColumn, columnWidth);
1310
+ trimMap(this.calculatedColumnWidths);
1311
+ }
1312
+ if (column === firstColumn) {
1313
+ columnWidth += treePaddingX;
1314
+ }
1315
+ return columnWidth;
1316
+ }
1317
+
1318
+ /**
1319
+ * Calculate the width of the specified column's header
1320
+ * @param modelColumn ModelIndex of the column to get the header width for
1321
+ * @param state The grid metric state
1322
+ * @returns The calculated width of the column header
1323
+ */
1324
+ calculateColumnHeaderWidth(modelColumn, state) {
1325
+ var {
1326
+ model,
1327
+ theme
1328
+ } = state;
1329
+ var {
1330
+ headerFont,
1331
+ headerHorizontalPadding
1332
+ } = theme;
1333
+ var headerText = model.textForColumnHeader(modelColumn, 0);
1334
+ if (headerText !== undefined && headerText !== '') {
1335
+ var headerFontWidth = this.getWidthForFont(headerFont, state);
1336
+ return headerText.length * headerFontWidth + headerHorizontalPadding * 2;
1337
+ }
1338
+ return headerHorizontalPadding * 2;
1339
+ }
1340
+
1341
+ /**
1342
+ * Calculate the width of the specified column's data
1343
+ * @param modelColumn ModelIndex of the column to get the data width for
1344
+ * @param state The grid metric state
1345
+ * @returns The calculated width of the column data
1346
+ */
1347
+ calculateColumnDataWidth(modelColumn, state) {
1348
+ var {
1349
+ top,
1350
+ height,
1351
+ width,
1352
+ model,
1353
+ theme
1354
+ } = state;
1355
+ var {
1356
+ floatingTopRowCount,
1357
+ floatingBottomRowCount,
1358
+ rowCount
1359
+ } = model;
1360
+ var {
1361
+ font,
1362
+ cellHorizontalPadding,
1363
+ rowHeight,
1364
+ rowHeaderWidth,
1365
+ rowFooterWidth,
1366
+ scrollBarSize,
1367
+ dataBarHorizontalPadding
1368
+ } = theme;
1369
+ var columnWidth = 0;
1370
+ var fontWidth = this.getWidthForFont(font, state);
1371
+ var rowsPerPage = height / rowHeight;
1372
+ var bottom = Math.ceil(top + rowsPerPage);
1373
+ GridUtils.iterateAllItems(top, bottom, floatingTopRowCount, floatingBottomRowCount, rowCount, row => {
1374
+ var modelRow = this.getModelRow(row, state);
1375
+ var text = model.textForCell(modelColumn, modelRow);
1376
+ var cellRenderType = model.renderTypeForCell(modelColumn, modelRow);
1377
+ var cellWidth = 0;
1378
+ if (text) {
1379
+ var cellPadding = cellHorizontalPadding * 2;
1380
+ cellWidth = text.length * fontWidth + cellPadding;
1381
+ }
1382
+ if (cellRenderType === 'dataBar') {
1383
+ cellWidth += dataBarHorizontalPadding;
1384
+ }
1385
+ columnWidth = Math.max(columnWidth, cellWidth);
1386
+ });
1387
+ columnWidth = Math.max(Math.min(columnWidth, (width - rowHeaderWidth - scrollBarSize - rowFooterWidth) * GridMetricCalculator.MAX_COLUMN_WIDTH), cellHorizontalPadding * 2);
1388
+ return columnWidth;
1389
+ }
1390
+
1391
+ /**
1392
+ * The coordinate for where the tree padding should be drawn
1393
+ * @param state The grid metric state
1394
+ * @returns The coordinate for tree padding
1395
+ */
1396
+ calculateTreePaddingX(state) {
1397
+ var {
1398
+ top,
1399
+ height,
1400
+ model,
1401
+ theme
1402
+ } = state;
1403
+ var {
1404
+ rowHeight,
1405
+ treeDepthIndent
1406
+ } = theme;
1407
+ if (!isExpandableGridModel(model) || !model.hasExpandableRows) {
1408
+ return 0;
1409
+ }
1410
+ var treePadding = 0;
1411
+ var rowsPerPage = height / rowHeight;
1412
+ var bottom = Math.ceil(top + rowsPerPage);
1413
+ for (var row = top; row <= bottom; row += 1) {
1414
+ var modelRow = this.getModelRow(row, state);
1415
+ var depth = model.depthForRow(modelRow);
1416
+ treePadding = Math.max(treePadding, treeDepthIndent * (depth + 1));
1417
+ }
1418
+ return treePadding;
1419
+ }
1420
+
1421
+ /**
1422
+ * Get the width of the provided font. Exploits the fact that we're
1423
+ * using tabular figures so every character is same width
1424
+ * @param font The font to get the width for
1425
+ * @param state The grid metric state
1426
+ * @returns Width of the char `8` for the specified font
1427
+ */
1428
+ getWidthForFont(font, state) {
1429
+ if (this.fontWidths.has(font)) {
1430
+ return getOrThrow(this.fontWidths, font);
1431
+ }
1432
+ var {
1433
+ context
1434
+ } = state;
1435
+ context.font = font;
1436
+ var textMetrics = context.measureText('8');
1437
+ var {
1438
+ width
1439
+ } = textMetrics;
1440
+
1441
+ // context.font changes the string a little bit, e.g. '10px Arial, sans serif' => '10px Arial, "sans serif"'
1442
+ // Rather than require checking with the correct font def (theme, or context font), just key it to both
1443
+ this.fontWidths.set(font, width);
1444
+ this.fontWidths.set(context.font, width);
1445
+ return width;
1446
+ }
1447
+
1448
+ /**
1449
+ * Sets the width for the specified column
1450
+ * @param column The column model index to set
1451
+ * @param size The size to set it to
1452
+ */
1453
+ setColumnWidth(column, size) {
1454
+ // Always use a new instance of the map so any consumer of the metrics knows there has been a change
1455
+ var userColumnWidths = new Map(this.userColumnWidths);
1456
+ userColumnWidths.set(column, Math.ceil(size));
1457
+ trimMap(userColumnWidths);
1458
+ this.userColumnWidths = userColumnWidths;
1459
+ }
1460
+
1461
+ /**
1462
+ * Resets the column width for the specified column to the calculated width
1463
+ * @param column The column model index to reset
1464
+ */
1465
+ resetColumnWidth(column) {
1466
+ // Always use a new instance of the map so any consumer of the metrics knows there has been a change
1467
+ var userColumnWidths = new Map(this.userColumnWidths);
1468
+ userColumnWidths.delete(column);
1469
+ this.userColumnWidths = userColumnWidths;
1470
+ }
1471
+
1472
+ /**
1473
+ * Sets the width for the specified row
1474
+ * @param row The row model index to set
1475
+ * @param size The size to set it to
1476
+ */
1477
+ setRowHeight(row, size) {
1478
+ // Always use a new instance of the map so any consumer of the metrics knows there has been a change
1479
+ var userRowHeights = new Map(this.userRowHeights);
1480
+ userRowHeights.set(row, Math.ceil(size));
1481
+ trimMap(userRowHeights);
1482
+ this.userRowHeights = userRowHeights;
1483
+ }
1484
+
1485
+ /**
1486
+ * Resets the row height for the specified row to the calculated height
1487
+ * @param row The row model index to reset
1488
+ */
1489
+ resetRowHeight(row) {
1490
+ // Always use a new instance of the map so any consumer of the metrics knows there has been a change
1491
+ var userRowHeights = new Map(this.userRowHeights);
1492
+ userRowHeights.delete(row);
1493
+ this.userRowHeights = userRowHeights;
1494
+ this.calculatedRowHeights.delete(row);
1495
+ }
1496
+ }
1497
+ _defineProperty(GridMetricCalculator, "CACHE_SIZE", 10000);
1498
+ _defineProperty(GridMetricCalculator, "MAX_COLUMN_WIDTH", 0.8);
1499
+ export default GridMetricCalculator;
1500
+ //# sourceMappingURL=GridMetricCalculator.js.map