@perspective-dev/viewer-datagrid 4.4.0 → 4.5.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.
- package/dist/cdn/perspective-viewer-datagrid.js +4 -22
- package/dist/cdn/perspective-viewer-datagrid.js.map +4 -4
- package/dist/css/perspective-viewer-datagrid-toolbar.css +1 -1
- package/dist/css/perspective-viewer-datagrid.css +1 -1
- package/dist/esm/color_utils.d.ts +22 -0
- package/dist/esm/custom_elements/datagrid.d.ts +16 -21
- package/dist/esm/data_listener/format_cell.d.ts +1 -1
- package/dist/esm/data_listener/formatter_cache.d.ts +1 -1
- package/dist/esm/data_listener/index.d.ts +3 -2
- package/dist/esm/event_handlers/click/edit_click.d.ts +3 -2
- package/dist/esm/event_handlers/click.d.ts +4 -6
- package/dist/esm/event_handlers/dispatch_click.d.ts +3 -2
- package/dist/esm/event_handlers/expand_collapse.d.ts +1 -1
- package/dist/esm/event_handlers/focus.d.ts +4 -5
- package/dist/esm/event_handlers/header_click.d.ts +5 -3
- package/dist/esm/event_handlers/keydown/edit_keydown.d.ts +3 -4
- package/dist/esm/event_handlers/select_region.d.ts +3 -1
- package/dist/esm/event_handlers/sort.d.ts +8 -7
- package/dist/esm/model/create.d.ts +1 -1
- package/dist/esm/model/meta_columns.d.ts +1 -0
- package/dist/esm/perspective-viewer-datagrid.js +3 -3
- package/dist/esm/perspective-viewer-datagrid.js.map +4 -4
- package/dist/esm/plugin/activate.d.ts +1 -1
- package/dist/esm/plugin/column_config_schema.d.ts +31 -0
- package/dist/esm/style_handlers/body.d.ts +3 -3
- package/dist/esm/style_handlers/column_header.d.ts +4 -3
- package/dist/esm/style_handlers/consolidated.d.ts +3 -47
- package/dist/esm/style_handlers/editable.d.ts +3 -2
- package/dist/esm/style_handlers/focus.d.ts +4 -4
- package/dist/esm/style_handlers/group_header.d.ts +1 -1
- package/dist/esm/style_handlers/table_cell/boolean.d.ts +1 -1
- package/dist/esm/style_handlers/table_cell/cell_flash.d.ts +1 -1
- package/dist/esm/style_handlers/table_cell/datetime.d.ts +1 -1
- package/dist/esm/style_handlers/table_cell/numeric.d.ts +1 -1
- package/dist/esm/style_handlers/table_cell/row_header.d.ts +1 -1
- package/dist/esm/style_handlers/table_cell/string.d.ts +1 -1
- package/dist/esm/style_handlers/types.d.ts +0 -4
- package/dist/esm/types.d.ts +10 -17
- package/package.json +2 -4
- package/src/css/regular_table.css +87 -31
- package/src/css/row-hover.css +20 -7
- package/src/css/toolbar.css +11 -0
- package/src/ts/color_utils.ts +181 -16
- package/src/ts/custom_elements/datagrid.ts +70 -56
- package/src/ts/custom_elements/toolbar.ts +4 -5
- package/src/ts/data_listener/format_cell.ts +28 -9
- package/src/ts/data_listener/format_tree_header.ts +2 -2
- package/src/ts/data_listener/formatter_cache.ts +9 -96
- package/src/ts/data_listener/index.ts +13 -11
- package/src/ts/event_handlers/click/edit_click.ts +10 -6
- package/src/ts/event_handlers/click.ts +39 -68
- package/src/ts/event_handlers/dispatch_click.ts +27 -25
- package/src/ts/event_handlers/expand_collapse.ts +11 -8
- package/src/ts/event_handlers/focus.ts +38 -35
- package/src/ts/event_handlers/header_click.ts +107 -62
- package/src/ts/event_handlers/keydown/edit_keydown.ts +60 -54
- package/src/ts/event_handlers/select_region.ts +153 -131
- package/src/ts/event_handlers/sort.ts +20 -25
- package/src/ts/get_cell_config.ts +10 -3
- package/src/ts/model/column_overrides.ts +16 -9
- package/src/ts/model/create.ts +68 -55
- package/src/ts/{event_handlers/deselect_all.ts → model/meta_columns.ts} +33 -14
- package/src/ts/model/toolbar.ts +33 -8
- package/src/ts/plugin/activate.ts +122 -92
- package/src/ts/plugin/column_config_schema.ts +187 -0
- package/src/ts/plugin/draw.ts +1 -0
- package/src/ts/plugin/restore.ts +6 -2
- package/src/ts/plugin/save.ts +2 -5
- package/src/ts/style_handlers/body.ts +48 -51
- package/src/ts/style_handlers/column_header.ts +22 -21
- package/src/ts/style_handlers/consolidated.ts +23 -123
- package/src/ts/style_handlers/editable.ts +16 -10
- package/src/ts/style_handlers/focus.ts +7 -5
- package/src/ts/style_handlers/group_header.ts +13 -6
- package/src/ts/style_handlers/table_cell/boolean.ts +3 -3
- package/src/ts/style_handlers/table_cell/cell_flash.ts +11 -11
- package/src/ts/style_handlers/table_cell/datetime.ts +3 -3
- package/src/ts/style_handlers/table_cell/numeric.ts +24 -25
- package/src/ts/style_handlers/table_cell/row_header.ts +2 -2
- package/src/ts/style_handlers/table_cell/string.ts +20 -18
- package/src/ts/style_handlers/types.ts +0 -10
- package/src/ts/types.ts +28 -20
- package/dist/esm/event_handlers/deselect_all.d.ts +0 -5
- package/dist/esm/event_handlers/row_select_click.d.ts +0 -4
- package/dist/esm/plugin/column_style_controls.d.ts +0 -28
- package/src/ts/event_handlers/row_select_click.ts +0 -92
- package/src/ts/plugin/column_style_controls.ts +0 -76
|
@@ -19,21 +19,23 @@ import { CollectedHeaderRow } from "./types.js";
|
|
|
19
19
|
* Apply styles to group header rows.
|
|
20
20
|
*/
|
|
21
21
|
export function applyGroupHeaderStyles(
|
|
22
|
-
|
|
22
|
+
model: DatagridModel,
|
|
23
23
|
headerRows: CollectedHeaderRow[],
|
|
24
24
|
regularTable: RegularTableElement,
|
|
25
25
|
): void {
|
|
26
|
-
const header_depth =
|
|
26
|
+
const header_depth = model._config.group_by.length;
|
|
27
27
|
const m: boolean[][] = [];
|
|
28
28
|
let marked = new Set<number>();
|
|
29
29
|
|
|
30
30
|
for (let y = 0; y < headerRows.length; y++) {
|
|
31
|
-
const {
|
|
31
|
+
const { cells } = headerRows[y];
|
|
32
32
|
const tops = new Set<number>();
|
|
33
33
|
|
|
34
34
|
for (let x = 0; x < cells.length; x++) {
|
|
35
35
|
const { element: td, metadata } = cells[x];
|
|
36
|
-
if (!metadata)
|
|
36
|
+
if (!metadata) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
37
39
|
|
|
38
40
|
td.style.backgroundColor = "";
|
|
39
41
|
|
|
@@ -54,6 +56,7 @@ export function applyGroupHeaderStyles(
|
|
|
54
56
|
);
|
|
55
57
|
|
|
56
58
|
td.classList.toggle("psp-color-mode-bar", false);
|
|
59
|
+
td.classList.toggle("psp-color-mode-label-bar", false);
|
|
57
60
|
td.classList.toggle("psp-header-sort-asc", false);
|
|
58
61
|
td.classList.toggle("psp-header-sort-desc", false);
|
|
59
62
|
td.classList.toggle("psp-header-sort-col-asc", false);
|
|
@@ -62,13 +65,17 @@ export function applyGroupHeaderStyles(
|
|
|
62
65
|
|
|
63
66
|
// Calculate spanning for psp-is-top
|
|
64
67
|
let xx = x;
|
|
65
|
-
for (; m[y] && m[y][xx]; ++xx)
|
|
68
|
+
for (; m[y] && m[y][xx]; ++xx) {}
|
|
69
|
+
|
|
66
70
|
tops.add(xx);
|
|
67
71
|
|
|
68
72
|
const cell = td;
|
|
69
73
|
for (let tx = xx; tx < xx + cell.colSpan; ++tx) {
|
|
70
74
|
for (let ty = y; ty < y + cell.rowSpan; ++ty) {
|
|
71
|
-
if (!m[ty])
|
|
75
|
+
if (!m[ty]) {
|
|
76
|
+
m[ty] = [];
|
|
77
|
+
}
|
|
78
|
+
|
|
72
79
|
m[ty][tx] = true;
|
|
73
80
|
}
|
|
74
81
|
}
|
|
@@ -14,7 +14,7 @@ import { CellMetadata } from "regular-table/dist/esm/types.js";
|
|
|
14
14
|
import type { DatagridModel, ColumnConfig, ColorRecord } from "../../types.js";
|
|
15
15
|
|
|
16
16
|
export function cell_style_boolean(
|
|
17
|
-
|
|
17
|
+
model: DatagridModel,
|
|
18
18
|
_plugin: ColumnConfig | undefined,
|
|
19
19
|
td: HTMLElement,
|
|
20
20
|
metadata: CellMetadata,
|
|
@@ -26,9 +26,9 @@ export function cell_style_boolean(
|
|
|
26
26
|
} else {
|
|
27
27
|
const [hex]: ColorRecord | [string, number, number, number, string] =
|
|
28
28
|
metadata.user === true
|
|
29
|
-
?
|
|
29
|
+
? model._pos_fg_color
|
|
30
30
|
: metadata.user === false
|
|
31
|
-
?
|
|
31
|
+
? model._neg_fg_color
|
|
32
32
|
: ["", 0, 0, 0, ""];
|
|
33
33
|
td.style.backgroundColor = "";
|
|
34
34
|
td.style.color = hex;
|
|
@@ -14,14 +14,14 @@ import { CellMetadataBody } from "regular-table/dist/esm/types.js";
|
|
|
14
14
|
import type { DatagridModel, ColorRecord } from "../../types.js";
|
|
15
15
|
|
|
16
16
|
export function style_cell_flash(
|
|
17
|
-
|
|
17
|
+
model: DatagridModel,
|
|
18
18
|
metadata: CellMetadataBody,
|
|
19
19
|
td: HTMLElement,
|
|
20
20
|
[, , , , , pos_s, pos_e]: ColorRecord,
|
|
21
21
|
[, , , , , neg_s, neg_e]: ColorRecord,
|
|
22
22
|
is_settings_open: boolean,
|
|
23
23
|
): void {
|
|
24
|
-
const id =
|
|
24
|
+
const id = model._ids?.[metadata.dy ?? 0]?.join("|");
|
|
25
25
|
const metadata_path = (
|
|
26
26
|
is_settings_open
|
|
27
27
|
? (metadata.column_header ?? []).slice(0, -1)
|
|
@@ -29,19 +29,19 @@ export function style_cell_flash(
|
|
|
29
29
|
).join("|");
|
|
30
30
|
|
|
31
31
|
if (
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
model.last_reverse_columns?.has(metadata_path) &&
|
|
33
|
+
model.last_reverse_ids?.has(id)
|
|
34
34
|
) {
|
|
35
|
-
const row_idx =
|
|
36
|
-
const col_idx =
|
|
37
|
-
if (!
|
|
35
|
+
const row_idx = model.last_reverse_ids?.get(id);
|
|
36
|
+
const col_idx = model.last_reverse_columns.get(metadata_path);
|
|
37
|
+
if (!model._is_old_viewport) {
|
|
38
38
|
td.style.animation = "";
|
|
39
39
|
} else if (
|
|
40
40
|
col_idx !== undefined &&
|
|
41
41
|
row_idx !== undefined &&
|
|
42
|
-
(
|
|
42
|
+
(model.last_meta?.[col_idx]?.[row_idx] as number | undefined) !==
|
|
43
43
|
undefined &&
|
|
44
|
-
(
|
|
44
|
+
(model.last_meta![col_idx]![row_idx] as number) >
|
|
45
45
|
((metadata.user ?? 0) as number)
|
|
46
46
|
) {
|
|
47
47
|
td.style.setProperty("--pulse--background-color-start", neg_s);
|
|
@@ -54,9 +54,9 @@ export function style_cell_flash(
|
|
|
54
54
|
} else if (
|
|
55
55
|
col_idx !== undefined &&
|
|
56
56
|
row_idx !== undefined &&
|
|
57
|
-
(
|
|
57
|
+
(model.last_meta?.[col_idx]?.[row_idx] as number | undefined) !==
|
|
58
58
|
undefined &&
|
|
59
|
-
(
|
|
59
|
+
(model.last_meta![col_idx]![row_idx] as number) <
|
|
60
60
|
((metadata.user ?? 0) as number)
|
|
61
61
|
) {
|
|
62
62
|
td.style.setProperty("--pulse--background-color-start", pos_s);
|
|
@@ -22,7 +22,7 @@ interface PluginWithColor extends Omit<ColumnConfig, "color"> {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
export function cell_style_datetime(
|
|
25
|
-
|
|
25
|
+
model: DatagridModel,
|
|
26
26
|
plugin: PluginWithColor,
|
|
27
27
|
td: HTMLElement,
|
|
28
28
|
metadata: CellMetadata,
|
|
@@ -31,7 +31,7 @@ export function cell_style_datetime(
|
|
|
31
31
|
if (plugin?.color !== undefined) {
|
|
32
32
|
return plugin.color;
|
|
33
33
|
} else {
|
|
34
|
-
return
|
|
34
|
+
return model._color;
|
|
35
35
|
}
|
|
36
36
|
})();
|
|
37
37
|
|
|
@@ -51,7 +51,7 @@ export function cell_style_datetime(
|
|
|
51
51
|
plugin?.datetime_color_mode === "background" &&
|
|
52
52
|
metadata.user !== null
|
|
53
53
|
) {
|
|
54
|
-
const source =
|
|
54
|
+
const source = model._plugin_background as [number, number, number];
|
|
55
55
|
const foreground = infer_foreground_from_background(
|
|
56
56
|
rgbaToRgb([r, g, b, 1], source),
|
|
57
57
|
);
|
|
@@ -36,7 +36,7 @@ interface PluginWithColors
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
export function cell_style_numeric(
|
|
39
|
-
|
|
39
|
+
model: DatagridModel,
|
|
40
40
|
plugin: PluginWithColors | undefined,
|
|
41
41
|
td: HTMLElement,
|
|
42
42
|
metadata: CellMetaWithExtras,
|
|
@@ -49,14 +49,14 @@ export function cell_style_numeric(
|
|
|
49
49
|
if (plugin?.pos_bg_color !== undefined) {
|
|
50
50
|
pos_bg_color = plugin.pos_bg_color;
|
|
51
51
|
} else {
|
|
52
|
-
pos_bg_color =
|
|
52
|
+
pos_bg_color = model._pos_bg_color;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
let neg_bg_color: ColorRecord;
|
|
56
56
|
if (plugin?.neg_bg_color !== undefined) {
|
|
57
57
|
neg_bg_color = plugin.neg_bg_color;
|
|
58
58
|
} else {
|
|
59
|
-
neg_bg_color =
|
|
59
|
+
neg_bg_color = model._neg_bg_color;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
const bg_tuple: ColorRecord = is_positive
|
|
@@ -65,9 +65,9 @@ export function cell_style_numeric(
|
|
|
65
65
|
? neg_bg_color
|
|
66
66
|
: [
|
|
67
67
|
"",
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
model._plugin_background[0],
|
|
69
|
+
model._plugin_background[1],
|
|
70
|
+
model._plugin_background[2],
|
|
71
71
|
"",
|
|
72
72
|
"",
|
|
73
73
|
"",
|
|
@@ -91,7 +91,7 @@ export function cell_style_numeric(
|
|
|
91
91
|
Math.abs((metadata.user ?? 0) / (plugin.bg_gradient ?? 1)),
|
|
92
92
|
),
|
|
93
93
|
);
|
|
94
|
-
const source =
|
|
94
|
+
const source = model._plugin_background as [number, number, number];
|
|
95
95
|
const foreground = infer_foreground_from_background(
|
|
96
96
|
rgbaToRgb([r, g, b, a], source),
|
|
97
97
|
);
|
|
@@ -100,8 +100,8 @@ export function cell_style_numeric(
|
|
|
100
100
|
td.style.color = foreground;
|
|
101
101
|
td.style.backgroundColor = `rgba(${r},${g},${b},${a})`;
|
|
102
102
|
} else if (plugin?.number_bg_mode === "pulse") {
|
|
103
|
-
style_cell_flash
|
|
104
|
-
|
|
103
|
+
style_cell_flash(
|
|
104
|
+
model,
|
|
105
105
|
metadata as any,
|
|
106
106
|
td,
|
|
107
107
|
pos_bg_color,
|
|
@@ -129,23 +129,23 @@ export function cell_style_numeric(
|
|
|
129
129
|
? plugin.neg_fg_color!
|
|
130
130
|
: [
|
|
131
131
|
"",
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
132
|
+
model._plugin_background[0],
|
|
133
|
+
model._plugin_background[1],
|
|
134
|
+
model._plugin_background[2],
|
|
135
135
|
"",
|
|
136
136
|
"",
|
|
137
137
|
"",
|
|
138
138
|
];
|
|
139
139
|
} else {
|
|
140
140
|
return is_positive
|
|
141
|
-
?
|
|
141
|
+
? model._pos_fg_color
|
|
142
142
|
: is_negative
|
|
143
|
-
?
|
|
143
|
+
? model._neg_fg_color
|
|
144
144
|
: [
|
|
145
145
|
"",
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
146
|
+
model._plugin_background[0],
|
|
147
|
+
model._plugin_background[1],
|
|
148
|
+
model._plugin_background[2],
|
|
149
149
|
"",
|
|
150
150
|
"",
|
|
151
151
|
"",
|
|
@@ -160,7 +160,7 @@ export function cell_style_numeric(
|
|
|
160
160
|
td.style.color = "";
|
|
161
161
|
} else if (plugin?.number_fg_mode === "disabled") {
|
|
162
162
|
if (plugin?.number_bg_mode === "color") {
|
|
163
|
-
const source =
|
|
163
|
+
const source = model._plugin_background as [number, number, number];
|
|
164
164
|
const foreground = infer_foreground_from_background(
|
|
165
165
|
rgbaToRgb([bg_tuple[1], bg_tuple[2], bg_tuple[3], 1], source),
|
|
166
166
|
);
|
|
@@ -173,13 +173,12 @@ export function cell_style_numeric(
|
|
|
173
173
|
} else if (plugin?.number_fg_mode === "bar") {
|
|
174
174
|
td.style.color = "";
|
|
175
175
|
td.style.position = "relative";
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
)
|
|
181
|
-
|
|
182
|
-
}
|
|
176
|
+
td.style.setProperty("--psp-label-bar-color", gradhex);
|
|
177
|
+
td.style.setProperty("--psp-label-bar-bg", hex);
|
|
178
|
+
} else if (plugin?.number_fg_mode === "label-bar") {
|
|
179
|
+
td.style.color = "";
|
|
180
|
+
td.style.setProperty("--psp-label-bar-color", gradhex);
|
|
181
|
+
td.style.setProperty("--psp-label-bar-bg", hex);
|
|
183
182
|
} else if (plugin?.number_fg_mode === "color" || !plugin?.number_fg_mode) {
|
|
184
183
|
td.style.color = hex;
|
|
185
184
|
}
|
|
@@ -18,7 +18,7 @@ import type { DatagridModel } from "../../types.js";
|
|
|
18
18
|
import { RegularTableElement } from "regular-table";
|
|
19
19
|
|
|
20
20
|
export function cell_style_row_header(
|
|
21
|
-
|
|
21
|
+
model: DatagridModel,
|
|
22
22
|
regularTable: RegularTableElement,
|
|
23
23
|
td: HTMLElement,
|
|
24
24
|
metadata: CellMetadataRowHeader,
|
|
@@ -28,7 +28,7 @@ export function cell_style_row_header(
|
|
|
28
28
|
metadata.value !== null &&
|
|
29
29
|
metadata.value?.toString()?.trim().length > 0;
|
|
30
30
|
const is_leaf =
|
|
31
|
-
(metadata.row_header_x ?? 0) >=
|
|
31
|
+
(metadata.row_header_x ?? 0) >= model._config.group_by.length;
|
|
32
32
|
const next = regularTable.getMeta({
|
|
33
33
|
dx: 0,
|
|
34
34
|
dy: (metadata.y ?? 0) - (metadata.y0 ?? 0) + 1,
|
|
@@ -10,10 +10,13 @@
|
|
|
10
10
|
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
11
11
|
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
12
|
|
|
13
|
-
import chroma from "chroma-js";
|
|
14
13
|
import {
|
|
15
|
-
|
|
14
|
+
hslToRgb,
|
|
16
15
|
infer_foreground_from_background,
|
|
16
|
+
parseColor,
|
|
17
|
+
rgbaToRgb,
|
|
18
|
+
rgbToHex,
|
|
19
|
+
rgbToHsl,
|
|
17
20
|
} from "../../color_utils.js";
|
|
18
21
|
import type { DatagridModel, ColumnConfig, ColorRecord } from "../../types.js";
|
|
19
22
|
|
|
@@ -28,17 +31,17 @@ interface PluginWithColor extends Omit<ColumnConfig, "color"> {
|
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
export function cell_style_string(
|
|
31
|
-
|
|
34
|
+
model: DatagridModel,
|
|
32
35
|
plugin: PluginWithColor | undefined,
|
|
33
36
|
td: HTMLElement,
|
|
34
37
|
metadata: CellMetaWithExtras,
|
|
35
38
|
): void {
|
|
36
|
-
const column_name = metadata.column_header?.[
|
|
39
|
+
const column_name = metadata.column_header?.[model._config.split_by.length];
|
|
37
40
|
const colorRecord: ColorRecord = (() => {
|
|
38
41
|
if (plugin?.color !== undefined) {
|
|
39
42
|
return plugin.color;
|
|
40
43
|
} else {
|
|
41
|
-
return
|
|
44
|
+
return model._color;
|
|
42
45
|
}
|
|
43
46
|
})();
|
|
44
47
|
|
|
@@ -60,7 +63,7 @@ export function cell_style_string(
|
|
|
60
63
|
plugin?.string_color_mode === "background" &&
|
|
61
64
|
metadata.user !== null
|
|
62
65
|
) {
|
|
63
|
-
const source =
|
|
66
|
+
const source = model._plugin_background as [number, number, number];
|
|
64
67
|
const foreground = infer_foreground_from_background(
|
|
65
68
|
rgbaToRgb([r, g, b, 1], source),
|
|
66
69
|
);
|
|
@@ -71,25 +74,24 @@ export function cell_style_string(
|
|
|
71
74
|
metadata.user !== null &&
|
|
72
75
|
column_name
|
|
73
76
|
) {
|
|
74
|
-
if (!
|
|
75
|
-
|
|
76
|
-
|
|
77
|
+
if (!model._series_color_map.has(column_name)) {
|
|
78
|
+
model._series_color_map.set(column_name, new Map());
|
|
79
|
+
model._series_color_seed.set(column_name, 0);
|
|
77
80
|
}
|
|
78
81
|
|
|
79
|
-
const series_map =
|
|
82
|
+
const series_map = model._series_color_map.get(column_name)!;
|
|
80
83
|
if (metadata.user && !series_map.has(metadata.user)) {
|
|
81
|
-
const seed =
|
|
84
|
+
const seed = model._series_color_seed.get(column_name) ?? 0;
|
|
82
85
|
series_map.set(metadata.user, seed);
|
|
83
|
-
|
|
86
|
+
model._series_color_seed.set(column_name, seed + 1);
|
|
84
87
|
}
|
|
85
88
|
|
|
86
89
|
const color_seed = series_map.get(metadata.user!) ?? 0;
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
const
|
|
90
|
-
const
|
|
91
|
-
const
|
|
92
|
-
const source = this._plugin_background as [number, number, number];
|
|
90
|
+
const [h, s, l] = rgbToHsl(parseColor(hex));
|
|
91
|
+
const rotated = hslToRgb([h + ((color_seed * 150) % 360), s, l]);
|
|
92
|
+
const [r2, g2, b2] = rotated;
|
|
93
|
+
const hex2 = rgbToHex(rotated);
|
|
94
|
+
const source = model._plugin_background as [number, number, number];
|
|
93
95
|
const foreground = infer_foreground_from_background(
|
|
94
96
|
rgbaToRgb([r2, g2, b2, 1], source),
|
|
95
97
|
);
|
|
@@ -10,13 +10,11 @@
|
|
|
10
10
|
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
|
|
11
11
|
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
12
12
|
|
|
13
|
-
import { RegularTableElement } from "regular-table";
|
|
14
13
|
import {
|
|
15
14
|
CellMetadata,
|
|
16
15
|
CellMetadataBody,
|
|
17
16
|
CellMetadataRowHeader,
|
|
18
17
|
} from "regular-table/dist/esm/types.js";
|
|
19
|
-
import type { SelectedPosition } from "../types.js";
|
|
20
18
|
|
|
21
19
|
export interface CollectedCell {
|
|
22
20
|
element: HTMLElement;
|
|
@@ -31,11 +29,3 @@ export interface CollectedHeaderRow {
|
|
|
31
29
|
metadata: CellMetadata | undefined;
|
|
32
30
|
}>;
|
|
33
31
|
}
|
|
34
|
-
|
|
35
|
-
// Local types for selection maps - match the actual runtime usage
|
|
36
|
-
// (activate.ts uses `as any` casts when passing these)
|
|
37
|
-
export type LocalSelectedRowsMap = WeakMap<RegularTableElement, unknown[]>;
|
|
38
|
-
export type LocalSelectedPositionMap = WeakMap<
|
|
39
|
-
RegularTableElement,
|
|
40
|
-
SelectedPosition
|
|
41
|
-
>;
|
package/src/ts/types.ts
CHANGED
|
@@ -19,8 +19,12 @@ import type {
|
|
|
19
19
|
ViewWindow,
|
|
20
20
|
ViewConfigUpdate,
|
|
21
21
|
} from "@perspective-dev/client";
|
|
22
|
-
import {
|
|
23
|
-
|
|
22
|
+
import type {
|
|
23
|
+
HTMLPerspectiveViewerElement,
|
|
24
|
+
ViewerConfig,
|
|
25
|
+
} from "@perspective-dev/viewer";
|
|
26
|
+
import type { RegularTableElement } from "regular-table";
|
|
27
|
+
import type { CellMetadata, DataResponse } from "regular-table/dist/esm/types";
|
|
24
28
|
|
|
25
29
|
// Re-export types from regular-table for use throughout the codebase
|
|
26
30
|
export type { RegularTableElement as RegularTable };
|
|
@@ -46,7 +50,8 @@ export type EditMode =
|
|
|
46
50
|
| "EDIT"
|
|
47
51
|
| "SELECT_COLUMN"
|
|
48
52
|
| "SELECT_ROW"
|
|
49
|
-
| "SELECT_REGION"
|
|
53
|
+
| "SELECT_REGION"
|
|
54
|
+
| "SELECT_ROW_TREE";
|
|
50
55
|
|
|
51
56
|
// Color record for styling - tuple returned by make_color_record
|
|
52
57
|
export type ColorRecord = [
|
|
@@ -162,10 +167,11 @@ export interface DatagridModel {
|
|
|
162
167
|
_view: View;
|
|
163
168
|
_table: Table;
|
|
164
169
|
_table_schema: Schema;
|
|
165
|
-
_config:
|
|
170
|
+
_config: ViewerConfig;
|
|
166
171
|
_num_rows: number;
|
|
167
172
|
_num_columns?: number;
|
|
168
173
|
_schema: Schema;
|
|
174
|
+
_theme: string;
|
|
169
175
|
_ids: unknown[][];
|
|
170
176
|
_plugin_background: number[];
|
|
171
177
|
_color: ColorRecord;
|
|
@@ -177,6 +183,8 @@ export interface DatagridModel {
|
|
|
177
183
|
_column_types: ColumnType[];
|
|
178
184
|
_is_editable: boolean[];
|
|
179
185
|
_edit_mode: EditMode;
|
|
186
|
+
_tree_selection_id?: unknown[];
|
|
187
|
+
_last_insert_configs?: ViewConfigUpdate[];
|
|
180
188
|
_selection_state: SelectionState;
|
|
181
189
|
_row_header_types: ColumnType[];
|
|
182
190
|
_series_color_map: Map<string, Map<string, number>>;
|
|
@@ -212,19 +220,6 @@ export type DataListener = (
|
|
|
212
220
|
// Style listener function type
|
|
213
221
|
export type StyleListener = () => void;
|
|
214
222
|
|
|
215
|
-
// Perspective viewer element interface (subset)
|
|
216
|
-
export interface PerspectiveViewerElement extends HTMLElement {
|
|
217
|
-
getView(): Promise<View>;
|
|
218
|
-
getTable(): Promise<Table>;
|
|
219
|
-
getEditPort(): Promise<number>;
|
|
220
|
-
restore(config: Partial<ViewConfig>): Promise<void>;
|
|
221
|
-
toggleColumnSettings(columnName?: string): Promise<void>;
|
|
222
|
-
hasAttribute(name: string): boolean;
|
|
223
|
-
setSelection(viewport?: ViewWindow): void;
|
|
224
|
-
dispatchEvent(event: Event): boolean;
|
|
225
|
-
children: HTMLCollectionOf<HTMLElement>;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
223
|
// Toolbar element interface
|
|
229
224
|
export interface DatagridToolbarElement extends HTMLElement {
|
|
230
225
|
setEditButton(button: HTMLElement): void;
|
|
@@ -255,7 +250,7 @@ export interface PerspectiveClickDetail {
|
|
|
255
250
|
config: Partial<ViewConfig>;
|
|
256
251
|
}
|
|
257
252
|
|
|
258
|
-
export { PerspectiveSelectDetail } from "@perspective-dev/viewer";
|
|
253
|
+
export { PerspectiveSelectDetail } from "@perspective-dev/viewer/src/ts/extensions.js";
|
|
259
254
|
|
|
260
255
|
// Mouse event with handled flag
|
|
261
256
|
export interface HandledMouseEvent extends MouseEvent {
|
|
@@ -281,9 +276,22 @@ export interface DatagridPluginElement extends HTMLElement {
|
|
|
281
276
|
_reset_column_size?: boolean;
|
|
282
277
|
}
|
|
283
278
|
|
|
284
|
-
// Map types for selected
|
|
285
|
-
export type SelectedRowsMap = WeakMap<RegularTableElement, Set<number>>;
|
|
279
|
+
// Map types for selected positions
|
|
286
280
|
export type SelectedPositionMap = WeakMap<
|
|
287
281
|
RegularTableElement,
|
|
288
282
|
SelectedPosition
|
|
289
283
|
>;
|
|
284
|
+
|
|
285
|
+
// Centralized editable mode check - used by style handlers and event handlers
|
|
286
|
+
export function isEditableMode(
|
|
287
|
+
model: DatagridModel,
|
|
288
|
+
viewer: HTMLPerspectiveViewerElement,
|
|
289
|
+
allowed: boolean = false,
|
|
290
|
+
): boolean {
|
|
291
|
+
const has_pivots =
|
|
292
|
+
model._config.group_by.length === 0 &&
|
|
293
|
+
model._config.split_by.length === 0;
|
|
294
|
+
const plugin = viewer.children[0] as DatagridPluginElement | undefined;
|
|
295
|
+
const editable = allowed || plugin?._edit_mode === "EDIT";
|
|
296
|
+
return has_pivots && editable;
|
|
297
|
+
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { RegularTableElement } from "regular-table";
|
|
2
|
-
import type { PerspectiveViewerElement } from "../types.js";
|
|
3
|
-
type SelectedRowsMap = Map<RegularTableElement, unknown[]>;
|
|
4
|
-
export declare function deselect_all_listener(regularTable: RegularTableElement, _viewer: PerspectiveViewerElement, selected_rows_map: SelectedRowsMap): Promise<void>;
|
|
5
|
-
export {};
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { type RegularTable, type DatagridModel, type PerspectiveViewerElement, type HandledMouseEvent } from "../types.js";
|
|
2
|
-
type SelectedRowsMap = Map<RegularTable, unknown[]>;
|
|
3
|
-
export declare function selectionListener(this: DatagridModel, regularTable: RegularTable, viewer: PerspectiveViewerElement, selected_rows_map: SelectedRowsMap, event: HandledMouseEvent): Promise<void>;
|
|
4
|
-
export {};
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { ColumnType } from "@perspective-dev/client";
|
|
2
|
-
import type { DatagridPluginElement } from "../types.js";
|
|
3
|
-
interface NumberStyleOpts {
|
|
4
|
-
datagrid_number_style: {
|
|
5
|
-
fg_gradient: number;
|
|
6
|
-
pos_fg_color: string;
|
|
7
|
-
neg_fg_color: string;
|
|
8
|
-
number_fg_mode: string;
|
|
9
|
-
bg_gradient: number;
|
|
10
|
-
pos_bg_color: string;
|
|
11
|
-
neg_bg_color: string;
|
|
12
|
-
number_bg_mode: string;
|
|
13
|
-
};
|
|
14
|
-
number_string_format: boolean;
|
|
15
|
-
}
|
|
16
|
-
interface DatetimeStyleOpts {
|
|
17
|
-
datagrid_datetime_style?: {
|
|
18
|
-
color: string;
|
|
19
|
-
bg_color: string;
|
|
20
|
-
};
|
|
21
|
-
datagrid_string_style?: {
|
|
22
|
-
color: string;
|
|
23
|
-
bg_color: string;
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
export type ColumnStyleOpts = NumberStyleOpts | DatetimeStyleOpts | null;
|
|
27
|
-
export default function column_style_opts(this: DatagridPluginElement, type: ColumnType, _group: string): ColumnStyleOpts;
|
|
28
|
-
export {};
|
|
@@ -1,92 +0,0 @@
|
|
|
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 getCellConfig from "../get_cell_config.js";
|
|
14
|
-
import {
|
|
15
|
-
type RegularTable,
|
|
16
|
-
type DatagridModel,
|
|
17
|
-
type PerspectiveViewerElement,
|
|
18
|
-
type HandledMouseEvent,
|
|
19
|
-
PerspectiveSelectDetail,
|
|
20
|
-
} from "../types.js";
|
|
21
|
-
|
|
22
|
-
type SelectedRowsMap = Map<RegularTable, unknown[]>;
|
|
23
|
-
|
|
24
|
-
export async function selectionListener(
|
|
25
|
-
this: DatagridModel,
|
|
26
|
-
regularTable: RegularTable,
|
|
27
|
-
viewer: PerspectiveViewerElement,
|
|
28
|
-
selected_rows_map: SelectedRowsMap,
|
|
29
|
-
event: HandledMouseEvent,
|
|
30
|
-
): Promise<void> {
|
|
31
|
-
const meta = regularTable.getMeta(event.target as HTMLElement);
|
|
32
|
-
if (!viewer.hasAttribute("selectable")) return;
|
|
33
|
-
if (event.handled) return;
|
|
34
|
-
if (event.shiftKey) return;
|
|
35
|
-
if (event.button !== 0) {
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
event.stopImmediatePropagation();
|
|
40
|
-
|
|
41
|
-
if (!meta) {
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if ((meta.type === "body" || meta.type === "row_header") && meta.y >= 0) {
|
|
46
|
-
const id = this._ids?.[meta.y - meta.y0];
|
|
47
|
-
const selected = selected_rows_map.get(regularTable);
|
|
48
|
-
const key_match =
|
|
49
|
-
!!selected &&
|
|
50
|
-
selected.reduce<boolean>((agg, x, i) => agg && x === id[i], true);
|
|
51
|
-
|
|
52
|
-
const is_deselect =
|
|
53
|
-
!!selected && id.length === selected.length && key_match;
|
|
54
|
-
|
|
55
|
-
const { row, column_names, config } = await getCellConfig(
|
|
56
|
-
this,
|
|
57
|
-
meta.y,
|
|
58
|
-
meta.type === "body" ? meta.x : 0,
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
let detail: PerspectiveSelectDetail;
|
|
62
|
-
if (is_deselect) {
|
|
63
|
-
selected_rows_map.delete(regularTable);
|
|
64
|
-
detail = new PerspectiveSelectDetail(
|
|
65
|
-
false,
|
|
66
|
-
row,
|
|
67
|
-
[],
|
|
68
|
-
[],
|
|
69
|
-
[{ filter: structuredClone(this._config.filter) }],
|
|
70
|
-
);
|
|
71
|
-
} else {
|
|
72
|
-
selected_rows_map.set(regularTable, id);
|
|
73
|
-
detail = new PerspectiveSelectDetail(
|
|
74
|
-
true,
|
|
75
|
-
row,
|
|
76
|
-
column_names,
|
|
77
|
-
[],
|
|
78
|
-
[config],
|
|
79
|
-
);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
await regularTable.draw({ preserve_width: true });
|
|
83
|
-
event.handled = true;
|
|
84
|
-
viewer.dispatchEvent(
|
|
85
|
-
new CustomEvent<PerspectiveSelectDetail>("perspective-select", {
|
|
86
|
-
bubbles: true,
|
|
87
|
-
composed: true,
|
|
88
|
-
detail,
|
|
89
|
-
}),
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
}
|