@perspective-dev/viewer-datagrid 4.0.1 → 4.1.1

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 (99) hide show
  1. package/dist/cdn/perspective-viewer-datagrid.js +4 -17
  2. package/dist/cdn/perspective-viewer-datagrid.js.map +4 -4
  3. package/dist/css/perspective-viewer-datagrid.css +1 -1
  4. package/dist/esm/color_utils.d.ts +9 -0
  5. package/dist/esm/custom_elements/datagrid.d.ts +52 -0
  6. package/dist/esm/custom_elements/toolbar.d.ts +10 -0
  7. package/dist/esm/data_listener/format_cell.d.ts +8 -0
  8. package/dist/esm/data_listener/format_tree_header.d.ts +13 -0
  9. package/dist/esm/data_listener/formatter_cache.d.ts +16 -0
  10. package/dist/esm/data_listener/index.d.ts +10 -0
  11. package/dist/esm/event_handlers/click/edit_click.d.ts +3 -0
  12. package/dist/esm/event_handlers/click.d.ts +7 -0
  13. package/dist/esm/event_handlers/deselect_all.d.ts +5 -0
  14. package/dist/esm/event_handlers/dispatch_click.d.ts +3 -0
  15. package/dist/esm/event_handlers/expand_collapse.d.ts +2 -0
  16. package/dist/esm/event_handlers/focus.d.ts +5 -0
  17. package/dist/esm/event_handlers/header_click.d.ts +3 -0
  18. package/dist/esm/event_handlers/keydown/edit_keydown.d.ts +4 -0
  19. package/dist/esm/event_handlers/row_select_click.d.ts +4 -0
  20. package/dist/esm/event_handlers/select_region.d.ts +9 -0
  21. package/dist/esm/event_handlers/sort.d.ts +7 -0
  22. package/dist/esm/get_cell_config.d.ts +8 -0
  23. package/dist/esm/index.d.ts +6 -0
  24. package/dist/esm/model/column_overrides.d.ts +23 -0
  25. package/dist/esm/model/create.d.ts +3 -0
  26. package/dist/esm/model/index.d.ts +4 -0
  27. package/dist/esm/model/toolbar.d.ts +4 -0
  28. package/dist/esm/perspective-viewer-datagrid.js +3 -3
  29. package/dist/esm/perspective-viewer-datagrid.js.map +4 -4
  30. package/dist/esm/plugin/activate.d.ts +6 -0
  31. package/dist/esm/plugin/column_style_controls.d.ts +28 -0
  32. package/dist/esm/plugin/draw.d.ts +7 -0
  33. package/dist/esm/plugin/restore.d.ts +10 -0
  34. package/dist/esm/plugin/save.d.ts +2 -0
  35. package/dist/esm/style_handlers/body.d.ts +7 -0
  36. package/dist/esm/style_handlers/column_header.d.ts +13 -0
  37. package/dist/esm/style_handlers/consolidated.d.ts +57 -0
  38. package/dist/esm/style_handlers/editable.d.ts +7 -0
  39. package/dist/esm/style_handlers/focus.d.ts +16 -0
  40. package/dist/esm/style_handlers/group_header.d.ts +7 -0
  41. package/dist/esm/style_handlers/table_cell/boolean.d.ts +7 -0
  42. package/dist/esm/style_handlers/table_cell/cell_flash.d.ts +3 -0
  43. package/dist/esm/style_handlers/table_cell/datetime.d.ts +7 -0
  44. package/dist/esm/style_handlers/table_cell/numeric.d.ts +15 -0
  45. package/dist/esm/style_handlers/table_cell/row_header.d.ts +4 -0
  46. package/dist/esm/style_handlers/table_cell/string.d.ts +11 -0
  47. package/dist/esm/style_handlers/types.d.ts +20 -0
  48. package/dist/esm/types.d.ts +193 -0
  49. package/package.json +10 -5
  50. package/src/less/mitered-headers.less +65 -0
  51. package/src/less/pro.less +196 -0
  52. package/src/less/regular_table.less +509 -0
  53. package/src/less/row-hover.less +88 -0
  54. package/{index.d.ts → src/less/scrollbar.less} +18 -19
  55. package/src/less/sub-cell-scroll.less +82 -0
  56. package/src/less/toolbar.less +201 -0
  57. package/src/ts/color_utils.ts +70 -0
  58. package/src/ts/custom_elements/datagrid.ts +250 -0
  59. package/src/ts/custom_elements/toolbar.ts +75 -0
  60. package/src/ts/data_listener/format_cell.ts +84 -0
  61. package/src/ts/data_listener/format_tree_header.ts +82 -0
  62. package/src/ts/data_listener/formatter_cache.ts +191 -0
  63. package/src/ts/data_listener/index.ts +242 -0
  64. package/src/ts/event_handlers/click/edit_click.ts +73 -0
  65. package/src/ts/event_handlers/click.ts +92 -0
  66. package/src/ts/event_handlers/deselect_all.ts +28 -0
  67. package/src/ts/event_handlers/dispatch_click.ts +44 -0
  68. package/src/ts/event_handlers/expand_collapse.ts +44 -0
  69. package/src/ts/event_handlers/focus.ts +63 -0
  70. package/src/ts/event_handlers/header_click.ts +85 -0
  71. package/src/ts/event_handlers/keydown/edit_keydown.ts +213 -0
  72. package/src/ts/event_handlers/row_select_click.ts +87 -0
  73. package/src/ts/event_handlers/select_region.ts +427 -0
  74. package/src/ts/event_handlers/sort.ts +118 -0
  75. package/src/ts/get_cell_config.ts +68 -0
  76. package/src/ts/index.ts +49 -0
  77. package/src/ts/model/column_overrides.ts +112 -0
  78. package/src/ts/model/create.ts +247 -0
  79. package/src/ts/model/index.ts +19 -0
  80. package/src/ts/model/toolbar.ts +64 -0
  81. package/src/ts/plugin/activate.ts +235 -0
  82. package/src/ts/plugin/column_style_controls.ts +76 -0
  83. package/src/ts/plugin/draw.ts +69 -0
  84. package/src/ts/plugin/restore.ts +110 -0
  85. package/src/ts/plugin/save.ts +45 -0
  86. package/src/ts/style_handlers/body.ts +228 -0
  87. package/src/ts/style_handlers/column_header.ts +183 -0
  88. package/src/ts/style_handlers/consolidated.ts +223 -0
  89. package/src/ts/style_handlers/editable.ts +94 -0
  90. package/src/ts/style_handlers/focus.ts +106 -0
  91. package/src/ts/style_handlers/group_header.ts +78 -0
  92. package/src/ts/style_handlers/table_cell/boolean.ts +39 -0
  93. package/src/ts/style_handlers/table_cell/cell_flash.ts +75 -0
  94. package/src/ts/style_handlers/table_cell/datetime.ts +64 -0
  95. package/src/ts/style_handlers/table_cell/numeric.ts +186 -0
  96. package/src/ts/style_handlers/table_cell/row_header.ts +53 -0
  97. package/src/ts/style_handlers/table_cell/string.ts +102 -0
  98. package/src/ts/style_handlers/types.ts +41 -0
  99. package/src/ts/types.ts +279 -0
@@ -0,0 +1,427 @@
1
+ // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
+ // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
+ // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
+ // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
+ // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
+ // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
+ // ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
+ // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
+ // ┃ This file is part of the Perspective library, distributed under the terms ┃
10
+ // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
+ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
+
13
+ import { RegularTableElement } from "regular-table";
14
+ import type {
15
+ DatagridPluginElement,
16
+ PerspectiveViewerElement,
17
+ SelectionArea,
18
+ } from "../types.js";
19
+ import { ViewWindow } from "@perspective-dev/client";
20
+
21
+ const MOUSE_SELECTED_AREA_CLASS = "mouse-selected-area";
22
+
23
+ interface AddAreaMouseSelectionOptions {
24
+ className?: string;
25
+ selected?: SelectionArea[];
26
+ }
27
+
28
+ export const addAreaMouseSelection = (
29
+ datagrid: DatagridPluginElement,
30
+ table: RegularTableElement,
31
+ {
32
+ className = MOUSE_SELECTED_AREA_CLASS,
33
+ selected = [],
34
+ }: AddAreaMouseSelectionOptions = {},
35
+ ): RegularTableElement => {
36
+ datagrid.model!._selection_state = {
37
+ selected_areas: selected,
38
+ dirty: true,
39
+ };
40
+
41
+ table.addEventListener(
42
+ "mousedown",
43
+ getMousedownListener(datagrid, table, className),
44
+ );
45
+
46
+ table.addEventListener(
47
+ "mouseover",
48
+ getMouseoverListener(datagrid, table, className),
49
+ );
50
+
51
+ table.addEventListener(
52
+ "mouseup",
53
+ getMouseupListener(datagrid, table, className),
54
+ );
55
+
56
+ table.addStyleListener(() =>
57
+ applyMouseAreaSelections(datagrid, table, className),
58
+ );
59
+
60
+ return table;
61
+ };
62
+
63
+ const getMousedownListener =
64
+ (
65
+ datagrid: DatagridPluginElement,
66
+ table: RegularTableElement,
67
+ className: string,
68
+ ) =>
69
+ (event: Event): void => {
70
+ const mouseEvent = event as MouseEvent;
71
+ if (
72
+ mouseEvent.button === 0 &&
73
+ (datagrid.model!._edit_mode === "SELECT_REGION" ||
74
+ datagrid.model!._edit_mode === "SELECT_ROW" ||
75
+ datagrid.model!._edit_mode === "SELECT_COLUMN")
76
+ ) {
77
+ datagrid.model!._selection_state.CURRENT_MOUSEDOWN_COORDINATES = {};
78
+ const meta = table.getMeta(mouseEvent.target as Element);
79
+ if (meta && meta.x !== undefined && meta.y !== undefined) {
80
+ datagrid.model!._selection_state.CURRENT_MOUSEDOWN_COORDINATES =
81
+ {
82
+ x: meta.x,
83
+ y: meta.y,
84
+ };
85
+
86
+ datagrid.model!._selection_state.old_selected_areas =
87
+ datagrid.model!._selection_state.selected_areas;
88
+ datagrid.model!._selection_state.selected_areas = [];
89
+
90
+ const start: SelectionArea = {
91
+ x0: meta.x,
92
+ x1: meta.x,
93
+ y0: meta.y,
94
+ y1: meta.y,
95
+ };
96
+ datagrid.model!._selection_state.potential_selection = start;
97
+ applyMouseAreaSelections(
98
+ datagrid,
99
+ table,
100
+ className,
101
+ datagrid.model!._selection_state.selected_areas.concat([
102
+ start,
103
+ ]),
104
+ );
105
+
106
+ return;
107
+ }
108
+ }
109
+
110
+ datagrid.model!._selection_state.selected_areas = [];
111
+ };
112
+
113
+ const getMouseoverListener =
114
+ (
115
+ datagrid: DatagridPluginElement,
116
+ table: RegularTableElement,
117
+ className: string,
118
+ ) =>
119
+ (event: Event): void => {
120
+ const mouseEvent = event as MouseEvent;
121
+ if (
122
+ datagrid.model!._edit_mode === "SELECT_REGION" ||
123
+ datagrid.model!._edit_mode === "SELECT_ROW" ||
124
+ datagrid.model!._edit_mode === "SELECT_COLUMN"
125
+ ) {
126
+ if (
127
+ datagrid.model!._selection_state
128
+ .CURRENT_MOUSEDOWN_COORDINATES &&
129
+ datagrid.model!._selection_state.CURRENT_MOUSEDOWN_COORDINATES
130
+ .x !== undefined
131
+ ) {
132
+ const meta = table.getMeta(mouseEvent.target as Element);
133
+ if (meta && meta.x !== undefined && meta.y !== undefined) {
134
+ const potentialSelection: SelectionArea = {
135
+ x0: Math.min(
136
+ meta.x,
137
+ datagrid.model!._selection_state
138
+ .CURRENT_MOUSEDOWN_COORDINATES.x!,
139
+ ),
140
+ x1: Math.max(
141
+ meta.x,
142
+ datagrid.model!._selection_state
143
+ .CURRENT_MOUSEDOWN_COORDINATES.x!,
144
+ ),
145
+ y0: Math.min(
146
+ meta.y,
147
+ datagrid.model!._selection_state
148
+ .CURRENT_MOUSEDOWN_COORDINATES.y!,
149
+ ),
150
+ y1: Math.max(
151
+ meta.y,
152
+ datagrid.model!._selection_state
153
+ .CURRENT_MOUSEDOWN_COORDINATES.y!,
154
+ ),
155
+ };
156
+
157
+ datagrid.model!._selection_state.potential_selection =
158
+ potentialSelection;
159
+
160
+ applyMouseAreaSelections(
161
+ datagrid,
162
+ table,
163
+ className,
164
+ datagrid.model!._selection_state.selected_areas.concat([
165
+ potentialSelection,
166
+ ]),
167
+ );
168
+ }
169
+ }
170
+ }
171
+ };
172
+
173
+ const getMouseupListener =
174
+ (
175
+ datagrid: DatagridPluginElement,
176
+ table: RegularTableElement,
177
+ className: string,
178
+ ) =>
179
+ (event: Event): void => {
180
+ const mouseEvent = event as MouseEvent;
181
+ if (
182
+ datagrid.model!._edit_mode === "SELECT_REGION" ||
183
+ datagrid.model!._edit_mode === "SELECT_ROW" ||
184
+ datagrid.model!._edit_mode === "SELECT_COLUMN"
185
+ ) {
186
+ const meta = table.getMeta(mouseEvent.target as Element);
187
+ if (!meta) return;
188
+
189
+ if (
190
+ (datagrid.model!._selection_state.old_selected_areas?.length ??
191
+ 0) > 0
192
+ ) {
193
+ const selected =
194
+ datagrid.model!._selection_state.old_selected_areas![0];
195
+ if (
196
+ selected.x0 === selected.x1 &&
197
+ selected.y0 === selected.y1 &&
198
+ selected.x0 === meta.x &&
199
+ selected.y0 === meta.y
200
+ ) {
201
+ datagrid.model!._selection_state.selected_areas = [];
202
+ datagrid.model!._selection_state.old_selected_areas = [];
203
+ datagrid.model!._selection_state.CURRENT_MOUSEDOWN_COORDINATES =
204
+ {};
205
+ datagrid.model!._selection_state.potential_selection =
206
+ undefined;
207
+ applyMouseAreaSelections(datagrid, table, className, []);
208
+ return;
209
+ }
210
+ }
211
+
212
+ datagrid.model!._selection_state.old_selected_areas = [];
213
+
214
+ if (
215
+ datagrid.model!._selection_state
216
+ .CURRENT_MOUSEDOWN_COORDINATES &&
217
+ datagrid.model!._selection_state.CURRENT_MOUSEDOWN_COORDINATES
218
+ .x !== undefined &&
219
+ meta.x !== undefined &&
220
+ meta.y !== undefined
221
+ ) {
222
+ const selection: SelectionArea = {
223
+ x0: Math.min(
224
+ meta.x,
225
+ datagrid.model!._selection_state
226
+ .CURRENT_MOUSEDOWN_COORDINATES.x!,
227
+ ),
228
+ x1: Math.max(
229
+ meta.x,
230
+ datagrid.model!._selection_state
231
+ .CURRENT_MOUSEDOWN_COORDINATES.x!,
232
+ ),
233
+ y0: Math.min(
234
+ meta.y,
235
+ datagrid.model!._selection_state
236
+ .CURRENT_MOUSEDOWN_COORDINATES.y!,
237
+ ),
238
+ y1: Math.max(
239
+ meta.y,
240
+ datagrid.model!._selection_state
241
+ .CURRENT_MOUSEDOWN_COORDINATES.y!,
242
+ ),
243
+ };
244
+ datagrid.model!._selection_state.selected_areas.push(selection);
245
+ applyMouseAreaSelections(datagrid, table, className);
246
+ }
247
+
248
+ datagrid.model!._selection_state.CURRENT_MOUSEDOWN_COORDINATES = {};
249
+ datagrid.model!._selection_state.potential_selection = undefined;
250
+ }
251
+ };
252
+
253
+ function set_psp_selection(
254
+ viewer: PerspectiveViewerElement,
255
+ datagrid: DatagridPluginElement,
256
+ { x0, x1, y0, y1 }: SelectionArea,
257
+ ): void {
258
+ const viewport: ViewWindow = {};
259
+ const mode = datagrid.model!._edit_mode;
260
+ if (
261
+ x0 !== undefined &&
262
+ ["SELECT_COLUMN", "SELECT_REGION"].indexOf(mode) > -1
263
+ ) {
264
+ viewport.start_col = x0;
265
+ }
266
+
267
+ if (
268
+ x1 !== undefined &&
269
+ ["SELECT_COLUMN", "SELECT_REGION"].indexOf(mode) > -1
270
+ ) {
271
+ viewport.end_col = x1 + 1;
272
+ }
273
+
274
+ if (
275
+ y0 !== undefined &&
276
+ ["SELECT_ROW", "SELECT_REGION"].indexOf(mode) > -1
277
+ ) {
278
+ viewport.start_row = y0;
279
+ }
280
+
281
+ if (
282
+ y1 !== undefined &&
283
+ ["SELECT_ROW", "SELECT_REGION"].indexOf(mode) > -1
284
+ ) {
285
+ viewport.end_row = y1 + 1;
286
+ }
287
+
288
+ viewer.setSelection(viewport);
289
+ }
290
+
291
+ export const applyMouseAreaSelections = (
292
+ datagrid: DatagridPluginElement,
293
+ table: RegularTableElement,
294
+ className: string,
295
+ selected?: SelectionArea[],
296
+ ): void => {
297
+ if (
298
+ datagrid.model!._edit_mode === "SELECT_REGION" ||
299
+ datagrid.model!._edit_mode === "SELECT_ROW" ||
300
+ datagrid.model!._edit_mode === "SELECT_COLUMN"
301
+ ) {
302
+ selected = datagrid.model!._selection_state.selected_areas.slice(0);
303
+ if (datagrid.model!._selection_state.potential_selection) {
304
+ selected.push(datagrid.model!._selection_state.potential_selection);
305
+ }
306
+
307
+ const tds = table.querySelectorAll("tbody td");
308
+
309
+ if (selected.length > 0) {
310
+ set_psp_selection(
311
+ datagrid.parentElement as any,
312
+ datagrid,
313
+ selected[0],
314
+ );
315
+ applyMouseAreaSelection(datagrid, table, selected, className);
316
+ } else {
317
+ (datagrid.parentElement as any).setSelection();
318
+ for (const td of tds) {
319
+ td.classList.remove(className);
320
+ }
321
+ }
322
+ } else if (datagrid.model!._selection_state.dirty) {
323
+ datagrid.model!._selection_state.dirty = false;
324
+ const tds = table.querySelectorAll("tbody td");
325
+ for (const td of tds) {
326
+ td.classList.remove(className);
327
+ }
328
+ }
329
+ };
330
+
331
+ const applyMouseAreaSelection = (
332
+ datagrid: DatagridPluginElement,
333
+ table: RegularTableElement,
334
+ selected: SelectionArea[],
335
+ className: string,
336
+ ): void => {
337
+ if (datagrid.model!._edit_mode === "SELECT_REGION" && selected.length > 0) {
338
+ const tds = table.querySelectorAll("tbody td");
339
+
340
+ for (const td of tds) {
341
+ const meta = table.getMeta(td);
342
+ if (!meta) continue;
343
+ let rendered = false;
344
+ for (const { x0, x1, y0, y1 } of selected) {
345
+ if (
346
+ x0 !== undefined &&
347
+ y0 !== undefined &&
348
+ x1 !== undefined &&
349
+ y1 !== undefined
350
+ ) {
351
+ if (
352
+ x0 <= meta.x &&
353
+ meta.x <= x1 &&
354
+ y0 <= meta.y &&
355
+ meta.y <= y1
356
+ ) {
357
+ rendered = true;
358
+ datagrid.model!._selection_state.dirty = true;
359
+ td.classList.add(className);
360
+ }
361
+ }
362
+ }
363
+
364
+ if (!rendered) {
365
+ td.classList.remove(className);
366
+ }
367
+ }
368
+ } else if (
369
+ datagrid.model!._edit_mode === "SELECT_ROW" &&
370
+ selected.length > 0
371
+ ) {
372
+ const tds = table.querySelectorAll("tbody td");
373
+
374
+ for (const td of tds) {
375
+ const meta = table.getMeta(td);
376
+ if (!meta) continue;
377
+ let rendered = false;
378
+ for (const { x0, x1, y0, y1 } of selected) {
379
+ if (
380
+ x0 !== undefined &&
381
+ y0 !== undefined &&
382
+ x1 !== undefined &&
383
+ y1 !== undefined
384
+ ) {
385
+ if (y0 <= meta.y && meta.y <= y1) {
386
+ datagrid.model!._selection_state.dirty = true;
387
+ rendered = true;
388
+ td.classList.add(className);
389
+ }
390
+ }
391
+ }
392
+
393
+ if (!rendered) {
394
+ td.classList.remove(className);
395
+ }
396
+ }
397
+ } else if (
398
+ datagrid.model!._edit_mode === "SELECT_COLUMN" &&
399
+ selected.length > 0
400
+ ) {
401
+ const tds = table.querySelectorAll("tbody td");
402
+
403
+ for (const td of tds) {
404
+ const meta = table.getMeta(td);
405
+ if (!meta) continue;
406
+ let rendered = false;
407
+ for (const { x0, x1, y0, y1 } of selected) {
408
+ if (
409
+ x0 !== undefined &&
410
+ y0 !== undefined &&
411
+ x1 !== undefined &&
412
+ y1 !== undefined
413
+ ) {
414
+ if (x0 <= meta.x && meta.x <= x1) {
415
+ datagrid.model!._selection_state.dirty = true;
416
+ rendered = true;
417
+ td.classList.add(className);
418
+ }
419
+ }
420
+ }
421
+
422
+ if (!rendered) {
423
+ td.classList.remove(className);
424
+ }
425
+ }
426
+ }
427
+ };
@@ -0,0 +1,118 @@
1
+ // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
+ // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
+ // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
+ // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
+ // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
+ // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
+ // ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
+ // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
+ // ┃ This file is part of the Perspective library, distributed under the terms ┃
10
+ // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
+ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
+
13
+ import { RegularTableElement } from "regular-table";
14
+ import type {
15
+ DatagridModel,
16
+ PerspectiveViewerElement,
17
+ SortRotationOrder,
18
+ SortTerm,
19
+ } from "../types.js";
20
+ import { SortDir } from "@perspective-dev/client";
21
+
22
+ const ROW_SORT_ORDER: SortRotationOrder = {
23
+ desc: "asc",
24
+ asc: undefined,
25
+ "desc abs": "asc abs",
26
+ "asc abs": undefined,
27
+ };
28
+
29
+ const ROW_COL_SORT_ORDER: SortRotationOrder = {
30
+ desc: "asc",
31
+ asc: "col desc",
32
+ "desc abs": "asc abs",
33
+ "asc abs": "col desc abs",
34
+ "col desc": "col asc",
35
+ "col asc": undefined,
36
+ "col desc abs": "col asc abs",
37
+ "col asc abs": undefined,
38
+ };
39
+
40
+ export async function sortHandler(
41
+ this: DatagridModel,
42
+ regularTable: RegularTableElement,
43
+ viewer: PerspectiveViewerElement,
44
+ event: MouseEvent,
45
+ target: HTMLElement,
46
+ ): Promise<void> {
47
+ const meta = regularTable.getMeta(target);
48
+ if (!meta?.column_header) return;
49
+ const column_name = meta.column_header[this._config.split_by.length];
50
+ const sort_method =
51
+ event.ctrlKey ||
52
+ (event as MouseEvent & { metaKet?: boolean }).metaKet ||
53
+ event.altKey
54
+ ? append_sort
55
+ : override_sort;
56
+
57
+ const abs = event.shiftKey;
58
+ const sort = sort_method.call(this, column_name, abs);
59
+ await viewer.restore({ sort });
60
+ }
61
+
62
+ export function append_sort(
63
+ this: DatagridModel,
64
+ column_name: string,
65
+ abs: boolean,
66
+ ): SortTerm[] {
67
+ const sort: SortTerm[] = [];
68
+ let found = false;
69
+ for (const sort_term of this._config.sort) {
70
+ const [_column_name, _sort_dir] = sort_term;
71
+ if (_column_name === column_name) {
72
+ found = true;
73
+ const term = create_sort.call(this, column_name, _sort_dir, abs);
74
+ if (term) {
75
+ sort.push(term);
76
+ }
77
+ } else {
78
+ sort.push(sort_term);
79
+ }
80
+ }
81
+
82
+ if (!found) {
83
+ sort.push([column_name, abs ? "desc abs" : "desc"]);
84
+ }
85
+
86
+ return sort;
87
+ }
88
+
89
+ export function override_sort(
90
+ this: DatagridModel,
91
+ column_name: string,
92
+ abs: boolean,
93
+ ): SortTerm[] {
94
+ for (const [_column_name, _sort_dir] of this._config.sort) {
95
+ if (_column_name === column_name) {
96
+ const sort = create_sort.call(this, column_name, _sort_dir, abs);
97
+ return sort ? [sort] : [];
98
+ }
99
+ }
100
+ return [[column_name, abs ? "desc abs" : "desc"]];
101
+ }
102
+
103
+ export function create_sort(
104
+ this: DatagridModel,
105
+ column_name: string,
106
+ sort_dir: SortDir | undefined,
107
+ _abs: boolean,
108
+ ): SortTerm | undefined {
109
+ const is_col_sortable = this._config.split_by.length > 0;
110
+ const order = is_col_sortable ? ROW_COL_SORT_ORDER : ROW_SORT_ORDER;
111
+ const inc_sort_dir: SortDir | undefined = sort_dir
112
+ ? order[sort_dir]
113
+ : "desc";
114
+ if (inc_sort_dir) {
115
+ return [column_name, inc_sort_dir];
116
+ }
117
+ return undefined;
118
+ }
@@ -0,0 +1,68 @@
1
+ // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
+ // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
+ // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
+ // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
+ // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
+ // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
+ // ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
+ // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
+ // ┃ This file is part of the Perspective library, distributed under the terms ┃
10
+ // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
+ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
+
13
+ import type { View, ViewConfig, Filter, Scalar } from "@perspective-dev/client";
14
+ import type { CellConfigResult } from "./types.js";
15
+
16
+ interface ModelWithViewAndConfig {
17
+ _view: View;
18
+ _config: ViewConfig;
19
+ }
20
+
21
+ interface RowData {
22
+ __ROW_PATH__?: unknown[];
23
+ [key: string]: unknown;
24
+ }
25
+
26
+ export default async function getCellConfig(
27
+ { _view, _config }: ModelWithViewAndConfig,
28
+ row_idx: number,
29
+ col_idx: number,
30
+ ): Promise<CellConfigResult> {
31
+ const group_by = _config.group_by;
32
+ const split_by = _config.split_by;
33
+ const start_row = row_idx >= 0 ? row_idx : 0;
34
+ const end_row = start_row + 1;
35
+ const r = (await _view.to_json({ start_row, end_row })) as RowData[];
36
+ const row_paths = r.map((x) => x.__ROW_PATH__);
37
+ const group_by_values = (row_paths[0] || []) as Scalar[];
38
+ const row_filters = group_by
39
+ .map((pivot, index): Filter | undefined => {
40
+ const pivot_value = group_by_values[index];
41
+ return pivot_value ? [pivot, "==", pivot_value] : undefined;
42
+ })
43
+ .filter((x): x is Filter => x !== undefined);
44
+
45
+ const column_index = group_by.length > 0 ? col_idx + 1 : col_idx;
46
+ const column_paths = Object.keys(r[0])[column_index];
47
+ const result: CellConfigResult = {
48
+ row: r[0] as Record<string, unknown>,
49
+ column_names: [],
50
+ config: { filter: [] },
51
+ };
52
+ let column_filters: Filter[] = [];
53
+ if (column_paths) {
54
+ const split_by_values = column_paths.split("|");
55
+ result.column_names = [split_by_values[split_by.length]];
56
+ column_filters = split_by
57
+ .map((pivot, index): Filter | undefined => {
58
+ const pivot_value = split_by_values[index];
59
+ return pivot_value ? [pivot, "==", pivot_value] : undefined;
60
+ })
61
+ .filter((x): x is Filter => x !== undefined)
62
+ .filter(([, , value]) => value !== "__ROW_PATH__");
63
+ }
64
+
65
+ const filter = _config.filter.concat(row_filters).concat(column_filters);
66
+ result.config = { filter };
67
+ return result;
68
+ }
@@ -0,0 +1,49 @@
1
+ // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2
+ // ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3
+ // ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4
+ // ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5
+ // ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6
+ // ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7
+ // ┃ Copyright (c) 2017, the Perspective Authors. ┃
8
+ // ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9
+ // ┃ This file is part of the Perspective library, distributed under the terms ┃
10
+ // ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11
+ // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12
+
13
+ import "regular-table";
14
+ import { HTMLPerspectiveViewerDatagridPluginElement } from "./custom_elements/datagrid.js";
15
+ import { HTMLPerspectiveViewerDatagridToolbarElement } from "./custom_elements/toolbar.js";
16
+
17
+ /******************************************************************************
18
+ *
19
+ * Main
20
+ *
21
+ */
22
+
23
+ interface PerspectiveViewerConstructor {
24
+ registerPlugin(tagName: string): void;
25
+ }
26
+
27
+ async function _register_element(): Promise<void> {
28
+ customElements.define(
29
+ "perspective-viewer-datagrid-toolbar",
30
+ HTMLPerspectiveViewerDatagridToolbarElement,
31
+ );
32
+
33
+ customElements.define(
34
+ "perspective-viewer-datagrid",
35
+ HTMLPerspectiveViewerDatagridPluginElement,
36
+ );
37
+
38
+ await customElements.whenDefined("perspective-viewer");
39
+ const PerspectiveViewer = customElements.get(
40
+ "perspective-viewer",
41
+ ) as unknown as PerspectiveViewerConstructor;
42
+ PerspectiveViewer.registerPlugin("perspective-viewer-datagrid");
43
+ }
44
+
45
+ _register_element();
46
+
47
+ export { PRIVATE_PLUGIN_SYMBOL } from "./types.js";
48
+ export { HTMLPerspectiveViewerDatagridPluginElement };
49
+ export { HTMLPerspectiveViewerDatagridToolbarElement };