@deephaven/js-plugin-pivot 0.1.0 → 0.2.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/index.js +397 -421
- package/package.json +8 -9
package/dist/index.js
CHANGED
|
@@ -10,8 +10,8 @@ const plugin = require("@deephaven/plugin");
|
|
|
10
10
|
const icons = require("@deephaven/icons");
|
|
11
11
|
const React = require("react");
|
|
12
12
|
const irisGrid = require("@deephaven/iris-grid");
|
|
13
|
-
const jsapiBootstrap = require("@deephaven/jsapi-bootstrap");
|
|
14
13
|
const components = require("@deephaven/components");
|
|
14
|
+
const jsapiBootstrap = require("@deephaven/jsapi-bootstrap");
|
|
15
15
|
const Log = require("@deephaven/log");
|
|
16
16
|
const jsapiUtils = require("@deephaven/jsapi-utils");
|
|
17
17
|
const dashboardCorePlugins = require("@deephaven/dashboard-core-plugins");
|
|
@@ -499,9 +499,6 @@ function isEditableGridModel(model) {
|
|
|
499
499
|
function isExpandableGridModel(model) {
|
|
500
500
|
return (model === null || model === void 0 ? void 0 : model.hasExpandableRows) !== void 0;
|
|
501
501
|
}
|
|
502
|
-
function isExpandableColumnGridModel(model) {
|
|
503
|
-
return (model === null || model === void 0 ? void 0 : model.hasExpandableColumns) !== void 0;
|
|
504
|
-
}
|
|
505
502
|
var NAN = 0 / 0;
|
|
506
503
|
var symbolTag = "[object Symbol]";
|
|
507
504
|
var reTrim = /^\s+|\s+$/g;
|
|
@@ -7311,20 +7308,20 @@ class GridColumnSeparatorMouseHandler extends GridSeparatorMouseHandler$1 {
|
|
|
7311
7308
|
var {
|
|
7312
7309
|
x,
|
|
7313
7310
|
y,
|
|
7314
|
-
columnHeaderDepth
|
|
7311
|
+
columnHeaderDepth: depth
|
|
7315
7312
|
} = gridPoint;
|
|
7316
7313
|
var {
|
|
7317
7314
|
modelColumns
|
|
7318
7315
|
} = metrics;
|
|
7319
7316
|
var separatorIndex = GridUtils.getColumnSeparatorIndex(x, y, metrics, theme);
|
|
7320
|
-
if (separatorIndex == null ||
|
|
7317
|
+
if (separatorIndex == null || depth == null) {
|
|
7321
7318
|
return null;
|
|
7322
7319
|
}
|
|
7323
7320
|
var columnIndex = modelColumns.get(separatorIndex);
|
|
7324
7321
|
if (columnIndex != null) {
|
|
7325
7322
|
return {
|
|
7326
7323
|
index: separatorIndex,
|
|
7327
|
-
depth
|
|
7324
|
+
depth
|
|
7328
7325
|
};
|
|
7329
7326
|
}
|
|
7330
7327
|
return null;
|
|
@@ -9978,7 +9975,14 @@ function makeColumn({
|
|
|
9978
9975
|
isSortable = false,
|
|
9979
9976
|
depth = ROOT_DEPTH,
|
|
9980
9977
|
hasChildren = false,
|
|
9981
|
-
isExpanded = false
|
|
9978
|
+
isExpanded = false,
|
|
9979
|
+
isProxy = false,
|
|
9980
|
+
filter = () => {
|
|
9981
|
+
throw new Error("Filter not implemented for virtual column");
|
|
9982
|
+
},
|
|
9983
|
+
sort = () => {
|
|
9984
|
+
throw new Error("Sort not implemented for virtual column");
|
|
9985
|
+
}
|
|
9982
9986
|
}) {
|
|
9983
9987
|
return {
|
|
9984
9988
|
name,
|
|
@@ -9986,18 +9990,14 @@ function makeColumn({
|
|
|
9986
9990
|
type,
|
|
9987
9991
|
isPartitionColumn: false,
|
|
9988
9992
|
isSortable,
|
|
9989
|
-
isProxy
|
|
9993
|
+
isProxy,
|
|
9990
9994
|
description,
|
|
9991
9995
|
index,
|
|
9992
9996
|
depth,
|
|
9993
9997
|
hasChildren,
|
|
9994
9998
|
isExpanded,
|
|
9995
|
-
filter
|
|
9996
|
-
|
|
9997
|
-
},
|
|
9998
|
-
sort: () => {
|
|
9999
|
-
throw new Error("Sort not implemented for virtual column");
|
|
10000
|
-
},
|
|
9999
|
+
filter,
|
|
10000
|
+
sort,
|
|
10001
10001
|
formatColor: () => {
|
|
10002
10002
|
throw new Error("Color not implemented for virtual column");
|
|
10003
10003
|
},
|
|
@@ -10030,7 +10030,7 @@ function makeColumnGroupName(keys2, columnSources, depth) {
|
|
|
10030
10030
|
function makeValueSourceColumnName(columnName, valueSource) {
|
|
10031
10031
|
return `${columnName}/${valueSource.name}`;
|
|
10032
10032
|
}
|
|
10033
|
-
function
|
|
10033
|
+
function makeColumnFromSnapshot(snapshotDim, valueSource, originalIndex, offset) {
|
|
10034
10034
|
const keys2 = snapshotDim.getKeys(originalIndex);
|
|
10035
10035
|
const depth = snapshotDim.getDepth(originalIndex);
|
|
10036
10036
|
const hasChildren = snapshotDim.hasChildren(originalIndex);
|
|
@@ -10052,7 +10052,7 @@ function makeExpandableDisplayColumn(snapshotDim, valueSource, originalIndex, of
|
|
|
10052
10052
|
hasChildren
|
|
10053
10053
|
});
|
|
10054
10054
|
}
|
|
10055
|
-
function
|
|
10055
|
+
function makePlaceholderColumn(valueSource, originalIndex, offset) {
|
|
10056
10056
|
return makeColumn({
|
|
10057
10057
|
name: makePlaceholderColumnName(originalIndex, valueSource),
|
|
10058
10058
|
displayName: "",
|
|
@@ -10063,21 +10063,30 @@ function makePlaceholderDisplayColumn(valueSource, originalIndex, offset) {
|
|
|
10063
10063
|
hasChildren: false
|
|
10064
10064
|
});
|
|
10065
10065
|
}
|
|
10066
|
-
function
|
|
10066
|
+
function makeColumnFromSource(source, index) {
|
|
10067
10067
|
const { name, type, isSortable, description } = source;
|
|
10068
|
-
return makeColumn({
|
|
10068
|
+
return makeColumn({
|
|
10069
|
+
name,
|
|
10070
|
+
type,
|
|
10071
|
+
index,
|
|
10072
|
+
isSortable,
|
|
10073
|
+
description,
|
|
10074
|
+
filter: source.filter.bind(source),
|
|
10075
|
+
sort: source.sort.bind(source)
|
|
10076
|
+
});
|
|
10069
10077
|
}
|
|
10070
10078
|
function checkColumnsChanged(prevColumns, newColumns) {
|
|
10071
10079
|
return prevColumns.length !== newColumns.length || prevColumns.some((col, i) => col.name !== newColumns[i].name);
|
|
10072
10080
|
}
|
|
10073
|
-
function
|
|
10081
|
+
function makeKeyColumnGroups(columnSources, rowSources, includeGroupColumn) {
|
|
10082
|
+
const groupName = includeGroupColumn ? ["__GROUP__"] : [];
|
|
10074
10083
|
const groups = columnSources.length === 0 ? [
|
|
10075
10084
|
new PivotColumnHeaderGroup({
|
|
10076
10085
|
name: "/",
|
|
10077
10086
|
displayName: "",
|
|
10078
10087
|
// For empty row sources we will render a "dead column"
|
|
10079
10088
|
// or a Groups column, depending on the table settings
|
|
10080
|
-
children: rowSources.map((c) => c.name),
|
|
10089
|
+
children: [...groupName, ...rowSources.map((c) => c.name)],
|
|
10081
10090
|
childIndexes: [],
|
|
10082
10091
|
isKeyColumnGroup: true,
|
|
10083
10092
|
depth: 1,
|
|
@@ -10087,7 +10096,7 @@ function getKeyColumnGroups(columnSources, rowSources) {
|
|
|
10087
10096
|
(source, i) => new PivotColumnHeaderGroup({
|
|
10088
10097
|
name: source.name,
|
|
10089
10098
|
displayName: source.name,
|
|
10090
|
-
children: i === columnSources.length - 1 ? rowSources.map((c) => c.name) : [columnSources[i + 1].name],
|
|
10099
|
+
children: i === columnSources.length - 1 ? [...groupName, ...rowSources.map((c) => c.name)] : [columnSources[i + 1].name],
|
|
10091
10100
|
childIndexes: [],
|
|
10092
10101
|
isKeyColumnGroup: true,
|
|
10093
10102
|
depth: columnSources.length - i,
|
|
@@ -10099,7 +10108,7 @@ function getKeyColumnGroups(columnSources, rowSources) {
|
|
|
10099
10108
|
[]
|
|
10100
10109
|
) : groups;
|
|
10101
10110
|
}
|
|
10102
|
-
function
|
|
10111
|
+
function makeTotalsColumnGroups(columnSources, valueSources, isRootColumnExpanded) {
|
|
10103
10112
|
const groupName = pluralize(valueSources.length, GRAND_TOTALS_GROUP_NAME);
|
|
10104
10113
|
return columnSources.length === 0 ? [
|
|
10105
10114
|
new PivotColumnHeaderGroup({
|
|
@@ -10123,7 +10132,7 @@ function getTotalsColumnGroups(columnSources, valueSources, isRootColumnExpanded
|
|
|
10123
10132
|
})
|
|
10124
10133
|
);
|
|
10125
10134
|
}
|
|
10126
|
-
function
|
|
10135
|
+
function makeSnapshotColumnGroups(snapshotColumns, columnSources, valueSources, formatValue) {
|
|
10127
10136
|
const maxDepth = Math.max(columnSources.length, 1);
|
|
10128
10137
|
const groupMap = /* @__PURE__ */ new Map();
|
|
10129
10138
|
const groupName = pluralize(valueSources.length, TOTALS_GROUP_NAME);
|
|
@@ -10163,16 +10172,20 @@ function getSnapshotColumnGroups(snapshotColumns, columnSources, valueSources, f
|
|
|
10163
10172
|
}
|
|
10164
10173
|
return [...groupMap.values()];
|
|
10165
10174
|
}
|
|
10166
|
-
function
|
|
10175
|
+
function makeColumnGroups(pivotTable, snapshotColumns, isRootColumnExpanded = true, includeGroupColumn = false, formatValue = (v, t) => String(v)) {
|
|
10167
10176
|
const virtualColumnGroups = [
|
|
10168
|
-
...
|
|
10169
|
-
|
|
10177
|
+
...makeKeyColumnGroups(
|
|
10178
|
+
pivotTable.columnSources,
|
|
10179
|
+
pivotTable.rowSources,
|
|
10180
|
+
includeGroupColumn
|
|
10181
|
+
),
|
|
10182
|
+
...makeTotalsColumnGroups(
|
|
10170
10183
|
pivotTable.columnSources,
|
|
10171
10184
|
pivotTable.valueSources,
|
|
10172
10185
|
isRootColumnExpanded
|
|
10173
10186
|
)
|
|
10174
10187
|
];
|
|
10175
|
-
const snapshotColumnGroups = snapshotColumns == null ? [] :
|
|
10188
|
+
const snapshotColumnGroups = snapshotColumns == null ? [] : makeSnapshotColumnGroups(
|
|
10176
10189
|
snapshotColumns,
|
|
10177
10190
|
pivotTable.columnSources,
|
|
10178
10191
|
pivotTable.valueSources
|
|
@@ -10184,6 +10197,16 @@ const SET_VIEWPORT_THROTTLE = 150;
|
|
|
10184
10197
|
const APPLY_VIEWPORT_THROTTLE = 0;
|
|
10185
10198
|
const ROW_BUFFER_PAGES = 1;
|
|
10186
10199
|
const COLUMN_BUFFER_PAGES = 1;
|
|
10200
|
+
const VirtualGroupColumn = Object.freeze(
|
|
10201
|
+
makeColumn({
|
|
10202
|
+
name: "__GROUP__",
|
|
10203
|
+
displayName: "Group",
|
|
10204
|
+
type: "java.lang.String",
|
|
10205
|
+
index: 0,
|
|
10206
|
+
depth: 2,
|
|
10207
|
+
isProxy: true
|
|
10208
|
+
})
|
|
10209
|
+
);
|
|
10187
10210
|
function isIrisGridPivotModel(model) {
|
|
10188
10211
|
return typeof model === "object" && model !== null && "pivotTable" in model && "keyColumns" in model && "expandAll" in model && "collapseAll" in model && "hasExpandableRows" in model && "hasExpandableColumns" in model;
|
|
10189
10212
|
}
|
|
@@ -10194,13 +10217,9 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
|
|
|
10194
10217
|
}
|
|
10195
10218
|
super(dh);
|
|
10196
10219
|
__publicField(this, "pivotTable");
|
|
10197
|
-
__publicField(this, "
|
|
10220
|
+
__publicField(this, "showExtraGroupCol", true);
|
|
10198
10221
|
__publicField(this, "_layoutHints");
|
|
10199
|
-
__publicField(this, "
|
|
10200
|
-
__publicField(this, "columnHeaderParentMap", /* @__PURE__ */ new Map());
|
|
10201
|
-
__publicField(this, "_columnHeaderMaxDepth", null);
|
|
10202
|
-
__publicField(this, "_columnHeaderGroups", []);
|
|
10203
|
-
__publicField(this, "_isColumnHeaderGroupsInitialized", false);
|
|
10222
|
+
__publicField(this, "_sorts", EMPTY_ARRAY);
|
|
10204
10223
|
__publicField(this, "viewportData", null);
|
|
10205
10224
|
__publicField(this, "formattedStringData", []);
|
|
10206
10225
|
__publicField(this, "snapshotColumns", null);
|
|
@@ -10217,73 +10236,80 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
|
|
|
10217
10236
|
__publicField(this, "dh");
|
|
10218
10237
|
__publicField(this, "getCachedColumns", memoizeOne(
|
|
10219
10238
|
(snapshotColumns, virtualColumns, valueSources) => {
|
|
10239
|
+
const columns = [];
|
|
10240
|
+
this.pivotTable.columnSources.forEach((source, col) => {
|
|
10241
|
+
const index = -this.pivotTable.columnSources.length + col;
|
|
10242
|
+
columns[index] = makeColumnFromSource(source, index);
|
|
10243
|
+
});
|
|
10244
|
+
columns.push(...virtualColumns);
|
|
10220
10245
|
if (snapshotColumns == null) {
|
|
10221
|
-
|
|
10222
|
-
snapshotColumns,
|
|
10223
|
-
valueSources
|
|
10224
|
-
});
|
|
10225
|
-
return virtualColumns;
|
|
10246
|
+
return columns;
|
|
10226
10247
|
}
|
|
10227
|
-
const columns = [...virtualColumns];
|
|
10228
10248
|
for (let i = 0; i < snapshotColumns.totalCount; i += 1) {
|
|
10229
10249
|
const isColumnInViewport = i >= snapshotColumns.offset && i < snapshotColumns.offset + snapshotColumns.count;
|
|
10230
10250
|
for (let v = 0; v < valueSources.length; v += 1) {
|
|
10231
10251
|
columns.push(
|
|
10232
|
-
isColumnInViewport ?
|
|
10252
|
+
isColumnInViewport ? makeColumnFromSnapshot(
|
|
10233
10253
|
snapshotColumns,
|
|
10234
10254
|
valueSources[v],
|
|
10235
10255
|
i,
|
|
10236
10256
|
virtualColumns.length
|
|
10237
|
-
) :
|
|
10238
|
-
valueSources[v],
|
|
10239
|
-
i,
|
|
10240
|
-
virtualColumns.length
|
|
10241
|
-
)
|
|
10257
|
+
) : makePlaceholderColumn(valueSources[v], i, virtualColumns.length)
|
|
10242
10258
|
);
|
|
10243
10259
|
}
|
|
10244
10260
|
}
|
|
10245
|
-
log$3.debug2("getCachedColumns", {
|
|
10246
|
-
snapshotColumns,
|
|
10247
|
-
valueSources,
|
|
10248
|
-
columns: columns.map(({ name }) => name)
|
|
10249
|
-
});
|
|
10250
10261
|
return columns;
|
|
10251
10262
|
}
|
|
10252
10263
|
));
|
|
10253
10264
|
__publicField(this, "getCachedTotalsColumns", memoizeOne(
|
|
10254
|
-
(pivotTable, valueSources) => valueSources.map(
|
|
10265
|
+
(pivotTable, valueSources, groupColumn) => valueSources.map(
|
|
10255
10266
|
(source, col) => makeColumn({
|
|
10256
10267
|
name: makeGrandTotalColumnName(source),
|
|
10257
10268
|
displayName: source.name,
|
|
10258
10269
|
description: source.description,
|
|
10259
10270
|
type: source.type,
|
|
10260
|
-
index: pivotTable.rowSources.length + col,
|
|
10271
|
+
index: pivotTable.rowSources.length + col + (groupColumn == null ? 0 : 1),
|
|
10261
10272
|
depth: 2,
|
|
10262
10273
|
isExpanded: true,
|
|
10263
10274
|
hasChildren: true
|
|
10264
10275
|
})
|
|
10265
10276
|
)
|
|
10266
10277
|
));
|
|
10278
|
+
__publicField(this, "getCachedKeyColumns", memoizeOne(
|
|
10279
|
+
(pivotTable, groupColumn) => pivotTable.rowSources.map(
|
|
10280
|
+
(source, index) => makeColumnFromSource(source, index + (groupColumn == null ? 0 : 1))
|
|
10281
|
+
)
|
|
10282
|
+
));
|
|
10267
10283
|
__publicField(this, "getCachedVirtualColumns", memoizeOne(
|
|
10268
|
-
(keyColumns, totalsColumns) => [...keyColumns, ...totalsColumns]
|
|
10284
|
+
(groupColumn, keyColumns, totalsColumns) => groupColumn ? [groupColumn, ...keyColumns, ...totalsColumns] : [...keyColumns, ...totalsColumns]
|
|
10269
10285
|
));
|
|
10270
10286
|
/**
|
|
10271
|
-
* Get the cached
|
|
10287
|
+
* Get the cached header groups data, including groups array, max depth, parent map, and group map.
|
|
10272
10288
|
* Returns groups for the key columns, totals, and the snapshot column in the current viewport.
|
|
10273
10289
|
* Placeholder columns are not included in the groups.
|
|
10274
10290
|
*/
|
|
10275
|
-
__publicField(this, "
|
|
10276
|
-
(snapshotColumns,
|
|
10277
|
-
|
|
10278
|
-
|
|
10279
|
-
|
|
10280
|
-
|
|
10281
|
-
|
|
10291
|
+
__publicField(this, "getCachedParsedColumnHeaderData", memoizeOne(
|
|
10292
|
+
(snapshotColumns, groupColumn, formatter, isRootColumnExpanded) => {
|
|
10293
|
+
const columnGroups = makeColumnGroups(
|
|
10294
|
+
this.pivotTable,
|
|
10295
|
+
snapshotColumns,
|
|
10296
|
+
isRootColumnExpanded,
|
|
10297
|
+
groupColumn != null,
|
|
10298
|
+
(value2, type) => this.getCachedFormattedString(formatter, value2, type, "")
|
|
10299
|
+
);
|
|
10300
|
+
return irisGrid.IrisGridUtils.parseColumnHeaderGroups(
|
|
10301
|
+
this,
|
|
10302
|
+
columnGroups,
|
|
10303
|
+
(args) => new PivotColumnHeaderGroup(args)
|
|
10304
|
+
);
|
|
10305
|
+
}
|
|
10282
10306
|
));
|
|
10283
10307
|
__publicField(this, "getColumnIndicesByNameMap", memoizeOne(
|
|
10284
10308
|
(columns) => {
|
|
10285
10309
|
const indices = /* @__PURE__ */ new Map();
|
|
10286
|
-
|
|
10310
|
+
Object.entries(columns).forEach(
|
|
10311
|
+
([i, { name }]) => indices.set(name, Number(i))
|
|
10312
|
+
);
|
|
10287
10313
|
return indices;
|
|
10288
10314
|
}
|
|
10289
10315
|
));
|
|
@@ -10415,9 +10441,6 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
|
|
|
10415
10441
|
this.snapshotValueSources = pivotTable.valueSources;
|
|
10416
10442
|
this.rowBufferPages = config.rowBufferPages ?? ROW_BUFFER_PAGES;
|
|
10417
10443
|
this.columnBufferPages = config.columnBufferPages ?? COLUMN_BUFFER_PAGES;
|
|
10418
|
-
this.keyColumns = pivotTable.rowSources.map(
|
|
10419
|
-
(source, col) => makeRowSourceColumn(source, col)
|
|
10420
|
-
);
|
|
10421
10444
|
this._layoutHints = {
|
|
10422
10445
|
backColumns: [],
|
|
10423
10446
|
hiddenColumns: [],
|
|
@@ -10434,10 +10457,38 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
|
|
|
10434
10457
|
}
|
|
10435
10458
|
set filter(_) {
|
|
10436
10459
|
}
|
|
10437
|
-
|
|
10438
|
-
|
|
10460
|
+
hydratePivotSort(sort) {
|
|
10461
|
+
const sourceIndex = this.getColumnIndexByName(sort.column.name);
|
|
10462
|
+
const source = this.columns[sourceIndex ?? -1];
|
|
10463
|
+
return (source == null ? void 0 : source.sort()[sort.direction === "ASC" ? "asc" : "desc"]()) ?? null;
|
|
10439
10464
|
}
|
|
10440
|
-
|
|
10465
|
+
get sort() {
|
|
10466
|
+
return this._sorts ?? EMPTY_ARRAY;
|
|
10467
|
+
}
|
|
10468
|
+
set sort(sorts) {
|
|
10469
|
+
log$3.debug("Setting sorts on pivot table", sorts);
|
|
10470
|
+
this._sorts = sorts;
|
|
10471
|
+
const columnBySorts = [];
|
|
10472
|
+
const rowBySorts = [];
|
|
10473
|
+
sorts.forEach((s) => {
|
|
10474
|
+
const sort = this.hydratePivotSort(s);
|
|
10475
|
+
if (sort == null) {
|
|
10476
|
+
log$3.warn(`Cannot hydrate sort for source: ${s.column.name}`, s);
|
|
10477
|
+
return;
|
|
10478
|
+
}
|
|
10479
|
+
const index = this.getColumnIndexByName(sort.name);
|
|
10480
|
+
if (index == null) {
|
|
10481
|
+
log$3.warn(`Cannot find index for source: ${s.column.name}`, s);
|
|
10482
|
+
return;
|
|
10483
|
+
}
|
|
10484
|
+
if (index < 0) {
|
|
10485
|
+
columnBySorts.push(sort);
|
|
10486
|
+
} else {
|
|
10487
|
+
rowBySorts.push(sort);
|
|
10488
|
+
}
|
|
10489
|
+
});
|
|
10490
|
+
this.pivotTable.applyRowSort(rowBySorts);
|
|
10491
|
+
this.pivotTable.applyColumnSort(columnBySorts);
|
|
10441
10492
|
}
|
|
10442
10493
|
get customColumns() {
|
|
10443
10494
|
return EMPTY_ARRAY;
|
|
@@ -10482,68 +10533,69 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
|
|
|
10482
10533
|
async export() {
|
|
10483
10534
|
throw new Error("Method not implemented.");
|
|
10484
10535
|
}
|
|
10536
|
+
get showExtraGroupColumn() {
|
|
10537
|
+
return this.showExtraGroupCol;
|
|
10538
|
+
}
|
|
10539
|
+
set showExtraGroupColumn(showExtraGroupCol) {
|
|
10540
|
+
if (showExtraGroupCol === this.showExtraGroupCol) {
|
|
10541
|
+
return;
|
|
10542
|
+
}
|
|
10543
|
+
this.showExtraGroupCol = showExtraGroupCol;
|
|
10544
|
+
this.dispatchEvent(
|
|
10545
|
+
new EventShimCustomEvent(irisGrid.IrisGridModel.EVENT.COLUMNS_CHANGED, {
|
|
10546
|
+
detail: this.columns
|
|
10547
|
+
})
|
|
10548
|
+
);
|
|
10549
|
+
}
|
|
10550
|
+
get groupColumn() {
|
|
10551
|
+
return this.pivotTable.rowSources.length !== 1 && this.showExtraGroupCol ? VirtualGroupColumn : null;
|
|
10552
|
+
}
|
|
10553
|
+
get keyColumns() {
|
|
10554
|
+
return this.getCachedKeyColumns(this.pivotTable, this.groupColumn);
|
|
10555
|
+
}
|
|
10485
10556
|
get totalsColumns() {
|
|
10486
10557
|
return this.getCachedTotalsColumns(
|
|
10487
10558
|
this.pivotTable,
|
|
10488
|
-
this.snapshotValueSources
|
|
10559
|
+
this.snapshotValueSources,
|
|
10560
|
+
this.groupColumn
|
|
10489
10561
|
);
|
|
10490
10562
|
}
|
|
10491
10563
|
get virtualColumns() {
|
|
10492
|
-
return this.getCachedVirtualColumns(
|
|
10564
|
+
return this.getCachedVirtualColumns(
|
|
10565
|
+
this.groupColumn,
|
|
10566
|
+
this.keyColumns,
|
|
10567
|
+
this.totalsColumns
|
|
10568
|
+
);
|
|
10493
10569
|
}
|
|
10494
|
-
|
|
10495
|
-
|
|
10570
|
+
getParsedColumnHeaderData() {
|
|
10571
|
+
return this.getCachedParsedColumnHeaderData(
|
|
10496
10572
|
this.snapshotColumns,
|
|
10497
|
-
this.
|
|
10498
|
-
|
|
10499
|
-
|
|
10500
|
-
this.getCachedFormattedString(this.formatter, value2, type, "")
|
|
10501
|
-
)
|
|
10573
|
+
this.groupColumn,
|
|
10574
|
+
this.formatter,
|
|
10575
|
+
this.isRootColumnExpanded
|
|
10502
10576
|
);
|
|
10503
|
-
|
|
10504
|
-
|
|
10577
|
+
}
|
|
10578
|
+
get initialColumnHeaderGroups() {
|
|
10579
|
+
return this.columnHeaderGroups;
|
|
10505
10580
|
}
|
|
10506
10581
|
get columnHeaderMaxDepth() {
|
|
10507
|
-
|
|
10582
|
+
const { maxDepth } = this.getParsedColumnHeaderData();
|
|
10583
|
+
return maxDepth;
|
|
10508
10584
|
}
|
|
10509
|
-
|
|
10510
|
-
|
|
10585
|
+
get columnHeaderParentMap() {
|
|
10586
|
+
const { parentMap } = this.getParsedColumnHeaderData();
|
|
10587
|
+
return parentMap;
|
|
10511
10588
|
}
|
|
10512
10589
|
get columnHeaderGroupMap() {
|
|
10513
|
-
this.
|
|
10514
|
-
return
|
|
10590
|
+
const { groupMap } = this.getParsedColumnHeaderData();
|
|
10591
|
+
return groupMap;
|
|
10515
10592
|
}
|
|
10516
10593
|
get columnHeaderGroups() {
|
|
10517
|
-
this.
|
|
10518
|
-
return
|
|
10594
|
+
const { groups } = this.getParsedColumnHeaderData();
|
|
10595
|
+
return groups;
|
|
10519
10596
|
}
|
|
10520
10597
|
set columnHeaderGroups(_groups) {
|
|
10521
10598
|
}
|
|
10522
|
-
setInternalColumnHeaderGroups(groups) {
|
|
10523
|
-
if (groups === this._columnHeaderGroups) {
|
|
10524
|
-
return;
|
|
10525
|
-
}
|
|
10526
|
-
const {
|
|
10527
|
-
groups: newGroups,
|
|
10528
|
-
maxDepth,
|
|
10529
|
-
parentMap,
|
|
10530
|
-
groupMap
|
|
10531
|
-
} = irisGrid.IrisGridUtils.parseColumnHeaderGroups(
|
|
10532
|
-
this,
|
|
10533
|
-
groups,
|
|
10534
|
-
(args) => new PivotColumnHeaderGroup(args)
|
|
10535
|
-
);
|
|
10536
|
-
this._columnHeaderGroups = newGroups;
|
|
10537
|
-
this.columnHeaderMaxDepth = maxDepth;
|
|
10538
|
-
this.columnHeaderParentMap = parentMap;
|
|
10539
|
-
this._columnHeaderGroupMap = groupMap;
|
|
10540
|
-
this._isColumnHeaderGroupsInitialized = true;
|
|
10541
|
-
}
|
|
10542
|
-
initializeColumnHeaderGroups() {
|
|
10543
|
-
if (!this._isColumnHeaderGroupsInitialized) {
|
|
10544
|
-
this.setInternalColumnHeaderGroups(this.initialColumnHeaderGroups);
|
|
10545
|
-
}
|
|
10546
|
-
}
|
|
10547
10599
|
textForColumnHeader(x, depth = 0) {
|
|
10548
10600
|
const header = this.columnAtDepth(x, depth);
|
|
10549
10601
|
if (isPivotColumnHeaderGroup(header)) {
|
|
@@ -10602,6 +10654,10 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
|
|
|
10602
10654
|
get initialMovedColumns() {
|
|
10603
10655
|
return EMPTY_ARRAY;
|
|
10604
10656
|
}
|
|
10657
|
+
/**
|
|
10658
|
+
* Get the columns in the pivot model.
|
|
10659
|
+
* Returned array includes column sources with negative indexes.
|
|
10660
|
+
*/
|
|
10605
10661
|
get columns() {
|
|
10606
10662
|
return this.getCachedColumns(
|
|
10607
10663
|
this.snapshotColumns,
|
|
@@ -10631,7 +10687,8 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
|
|
|
10631
10687
|
return false;
|
|
10632
10688
|
}
|
|
10633
10689
|
isColumnSortable(columnIndex) {
|
|
10634
|
-
|
|
10690
|
+
var _a;
|
|
10691
|
+
return ((_a = this.columns[columnIndex]) == null ? void 0 : _a.isSortable) ?? false;
|
|
10635
10692
|
}
|
|
10636
10693
|
get isTotalsAvailable() {
|
|
10637
10694
|
return false;
|
|
@@ -10697,10 +10754,10 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
|
|
|
10697
10754
|
this.formattedStringData = [];
|
|
10698
10755
|
this.viewportData = this.extractSnapshotData(snapshot);
|
|
10699
10756
|
this.updatePendingExpandCollapseState();
|
|
10700
|
-
this.setInternalColumnHeaderGroups(this.initialColumnHeaderGroups);
|
|
10701
10757
|
log$3.debug2("Pivot updated", {
|
|
10702
10758
|
columns: this.columns,
|
|
10703
|
-
snapshot
|
|
10759
|
+
snapshot,
|
|
10760
|
+
snapshotColumns: this.snapshotColumns,
|
|
10704
10761
|
viewport: (_a = this.viewportData) == null ? void 0 : _a.rowTotalCount,
|
|
10705
10762
|
columnCount: this.columnCount,
|
|
10706
10763
|
rowCount: this.rowCount
|
|
@@ -10751,10 +10808,7 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
|
|
|
10751
10808
|
const keyData = /* @__PURE__ */ new Map();
|
|
10752
10809
|
const totalsData = /* @__PURE__ */ new Map();
|
|
10753
10810
|
for (let c = 0; c < keys2.length; c += 1) {
|
|
10754
|
-
keyData.set(c, {
|
|
10755
|
-
// Only render the value for the deepest level
|
|
10756
|
-
value: c === depth - 1 ? keys2[c] : void 0
|
|
10757
|
-
});
|
|
10811
|
+
keyData.set(c, { value: keys2[c] });
|
|
10758
10812
|
}
|
|
10759
10813
|
for (let v = 0; v < snapshot.valueSources.length; v += 1) {
|
|
10760
10814
|
totalsData.set(v, {
|
|
@@ -10965,41 +11019,33 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
|
|
|
10965
11019
|
this.setColumnExpanded(this.keyColumns.length, false, true);
|
|
10966
11020
|
}
|
|
10967
11021
|
isColumnExpandable(x, depth) {
|
|
10968
|
-
var _a
|
|
10969
|
-
|
|
10970
|
-
x,
|
|
10971
|
-
depth,
|
|
10972
|
-
name: (_a = this.columns[x]) == null ? void 0 : _a.name,
|
|
10973
|
-
v: this.virtualColumns,
|
|
10974
|
-
cC: this.columnCount,
|
|
10975
|
-
c: this.columns
|
|
10976
|
-
});
|
|
10977
|
-
if (x >= this.keyColumns.length && x < this.virtualColumns.length) {
|
|
11022
|
+
var _a;
|
|
11023
|
+
if (this.isGrandTotalsColumn(x)) {
|
|
10978
11024
|
return !this.isRootColumnExpanded || this.columns.length > this.virtualColumns.length;
|
|
10979
11025
|
}
|
|
10980
11026
|
if (x < this.keyColumns.length) {
|
|
10981
11027
|
return false;
|
|
10982
11028
|
}
|
|
10983
|
-
return ((
|
|
11029
|
+
return ((_a = this.columns[x]) == null ? void 0 : _a.hasChildren) ?? false;
|
|
11030
|
+
}
|
|
11031
|
+
isGrandTotalsColumn(x) {
|
|
11032
|
+
const totalsStartIndex = this.keyColumns.length + (this.groupColumn == null ? 0 : 1);
|
|
11033
|
+
return x >= totalsStartIndex && x < this.virtualColumns.length;
|
|
10984
11034
|
}
|
|
10985
11035
|
isColumnExpanded(x) {
|
|
10986
11036
|
var _a;
|
|
10987
|
-
if (
|
|
11037
|
+
if (this.isGrandTotalsColumn(x)) {
|
|
10988
11038
|
return this.isRootColumnExpanded;
|
|
10989
11039
|
}
|
|
10990
11040
|
return ((_a = this.columns[x]) == null ? void 0 : _a.isExpanded) ?? false;
|
|
10991
11041
|
}
|
|
10992
11042
|
setColumnExpanded(x, isExpanded, expandDescendants = false) {
|
|
10993
|
-
|
|
10994
|
-
log$3.debug2("[0] setColumnExpanded", {
|
|
11043
|
+
log$3.debug2("setColumnExpanded", {
|
|
10995
11044
|
x,
|
|
10996
11045
|
isExpanded,
|
|
10997
|
-
|
|
10998
|
-
v: this.virtualColumns,
|
|
10999
|
-
cC: this.columnCount,
|
|
11000
|
-
c: this.columns
|
|
11046
|
+
expandDescendants
|
|
11001
11047
|
});
|
|
11002
|
-
if (
|
|
11048
|
+
if (this.isGrandTotalsColumn(x)) {
|
|
11003
11049
|
this.pivotTable.setRootColumnExpanded(isExpanded, expandDescendants);
|
|
11004
11050
|
this.isRootColumnExpanded = isExpanded;
|
|
11005
11051
|
return;
|
|
@@ -11065,15 +11111,27 @@ class IrisGridPivotModel extends irisGrid.IrisGridModel {
|
|
|
11065
11111
|
this.formattedStringData[x][y] = text;
|
|
11066
11112
|
}
|
|
11067
11113
|
dataForCell(x, y) {
|
|
11068
|
-
var _a, _b, _c;
|
|
11114
|
+
var _a, _b, _c, _d, _e, _f;
|
|
11069
11115
|
const keyCount = this.keyColumns.length;
|
|
11070
|
-
|
|
11071
|
-
|
|
11116
|
+
const groupOffset = this.groupColumn == null ? 0 : 1;
|
|
11117
|
+
if (groupOffset === 1 && x === 0) {
|
|
11118
|
+
const rowDepth = ((_a = this.row(y)) == null ? void 0 : _a.depth) ?? 2;
|
|
11119
|
+
return y === 0 ? (
|
|
11120
|
+
// Empty value for the group cell in the totals row
|
|
11121
|
+
{ value: "" }
|
|
11122
|
+
) : {
|
|
11123
|
+
// Render all key values except the last one in the group column
|
|
11124
|
+
// to match the Rollup UI
|
|
11125
|
+
value: rowDepth < keyCount ? (_c = (_b = this.row(y)) == null ? void 0 : _b.keyData.get(rowDepth - 1)) == null ? void 0 : _c.value : ""
|
|
11126
|
+
};
|
|
11127
|
+
}
|
|
11128
|
+
if (x < keyCount + groupOffset) {
|
|
11129
|
+
return (_d = this.row(y)) == null ? void 0 : _d.keyData.get(x - groupOffset);
|
|
11072
11130
|
}
|
|
11073
11131
|
if (x < this.virtualColumns.length) {
|
|
11074
|
-
return (
|
|
11132
|
+
return (_e = this.row(y)) == null ? void 0 : _e.totalsData.get(x - keyCount - groupOffset);
|
|
11075
11133
|
}
|
|
11076
|
-
return (
|
|
11134
|
+
return (_f = this.row(y)) == null ? void 0 : _f.data.get(x - this.virtualColumns.length);
|
|
11077
11135
|
}
|
|
11078
11136
|
formatForCell(x, y) {
|
|
11079
11137
|
var _a;
|
|
@@ -11146,8 +11204,8 @@ function useIrisGridPivotModel(fetch) {
|
|
|
11146
11204
|
[model]
|
|
11147
11205
|
);
|
|
11148
11206
|
const makeModel = React.useCallback(async () => {
|
|
11149
|
-
const
|
|
11150
|
-
return new IrisGridPivotModel(dh,
|
|
11207
|
+
const pivotTable = await fetch();
|
|
11208
|
+
return new IrisGridPivotModel(dh, pivotTable);
|
|
11151
11209
|
}, [dh, fetch]);
|
|
11152
11210
|
const reload = React.useCallback(async () => {
|
|
11153
11211
|
setIsLoading(true);
|
|
@@ -11195,6 +11253,22 @@ function useIrisGridPivotModel(fetch) {
|
|
|
11195
11253
|
}
|
|
11196
11254
|
throw new Error("Invalid state");
|
|
11197
11255
|
}
|
|
11256
|
+
const log$2 = Log.module("@deephaven/js-plugin-pivot/usePivotTableFetch");
|
|
11257
|
+
function usePivotTableFetch(fetch) {
|
|
11258
|
+
const api = jsapiBootstrap.useApi();
|
|
11259
|
+
return React.useCallback(
|
|
11260
|
+
() => fetch().then((widget) => {
|
|
11261
|
+
log$2.debug("Pivot fetch result:", widget);
|
|
11262
|
+
if (!isCorePlusDh(api)) {
|
|
11263
|
+
throw new Error("CorePlus is not available");
|
|
11264
|
+
}
|
|
11265
|
+
const pivotTable = new api.coreplus.pivot.PivotTable(widget);
|
|
11266
|
+
log$2.debug("Created pivot table:", pivotTable);
|
|
11267
|
+
return pivotTable;
|
|
11268
|
+
}),
|
|
11269
|
+
[api, fetch]
|
|
11270
|
+
);
|
|
11271
|
+
}
|
|
11198
11272
|
class PivotColumnGroupMouseHandler extends GridMouseHandler {
|
|
11199
11273
|
constructor(irisGrid2) {
|
|
11200
11274
|
super();
|
|
@@ -11238,162 +11312,71 @@ class PivotColumnGroupMouseHandler extends GridMouseHandler {
|
|
|
11238
11312
|
onClick(gridPoint, grid, event) {
|
|
11239
11313
|
const column = this.getColumnGroupFromGridPoint(gridPoint);
|
|
11240
11314
|
if (column != null && column === this.column && this.isExpandableColumnGroup(column, gridPoint.columnHeaderDepth)) {
|
|
11241
|
-
this.irisGrid.toggleExpandColumn(
|
|
11315
|
+
this.irisGrid.toggleExpandColumn(
|
|
11316
|
+
column,
|
|
11317
|
+
GridUtils.isModifierKeyDown(event)
|
|
11318
|
+
);
|
|
11242
11319
|
return true;
|
|
11243
11320
|
}
|
|
11244
11321
|
return false;
|
|
11245
11322
|
}
|
|
11246
11323
|
}
|
|
11324
|
+
class PivotSortMouseHandler extends GridMouseHandler {
|
|
11325
|
+
constructor(irisGrid2) {
|
|
11326
|
+
super();
|
|
11327
|
+
__publicField(this, "columnSource");
|
|
11328
|
+
__publicField(this, "irisGrid");
|
|
11329
|
+
this.columnSource = null;
|
|
11330
|
+
this.irisGrid = irisGrid2;
|
|
11331
|
+
}
|
|
11332
|
+
/**
|
|
11333
|
+
* Get the column source from a grid point
|
|
11334
|
+
* @param gridPoint The grid point to check
|
|
11335
|
+
* @returns The column source index if the grid point is in a column source header, else null
|
|
11336
|
+
*/
|
|
11337
|
+
getColumnSourceHeaderFromGridPoint(gridPoint) {
|
|
11338
|
+
const { column, row, columnHeaderDepth } = gridPoint;
|
|
11339
|
+
const { model } = this.irisGrid.props;
|
|
11340
|
+
assertNotNull(model);
|
|
11341
|
+
const sourceIndex = columnHeaderDepth != null ? -columnHeaderDepth : null;
|
|
11342
|
+
if (column == null || row !== null || columnHeaderDepth == null) {
|
|
11343
|
+
return null;
|
|
11344
|
+
}
|
|
11345
|
+
const group = model.getColumnHeaderGroup(column, columnHeaderDepth);
|
|
11346
|
+
if (sourceIndex != null && sourceIndex < 0 && isIrisGridPivotModel(model) && model.isColumnSortable(sourceIndex) && isPivotColumnHeaderGroup(group) && group.isKeyColumnGroup) {
|
|
11347
|
+
return sourceIndex;
|
|
11348
|
+
}
|
|
11349
|
+
return null;
|
|
11350
|
+
}
|
|
11351
|
+
// We need to remember where the down started, because the canvas element will trigger a click where mouseUp is
|
|
11352
|
+
onDown(gridPoint, grid, event) {
|
|
11353
|
+
this.columnSource = this.getColumnSourceHeaderFromGridPoint(gridPoint);
|
|
11354
|
+
return false;
|
|
11355
|
+
}
|
|
11356
|
+
onClick(gridPoint, grid, event) {
|
|
11357
|
+
const columnSource = this.getColumnSourceHeaderFromGridPoint(gridPoint);
|
|
11358
|
+
if (columnSource != null && columnSource === this.columnSource) {
|
|
11359
|
+
const addToExisting = components.ContextActionUtils.isModifierKeyDown(event);
|
|
11360
|
+
this.irisGrid.toggleSort(columnSource, addToExisting);
|
|
11361
|
+
return true;
|
|
11362
|
+
}
|
|
11363
|
+
return false;
|
|
11364
|
+
}
|
|
11365
|
+
}
|
|
11366
|
+
function usePivotMouseHandlers() {
|
|
11367
|
+
return React.useMemo(
|
|
11368
|
+
() => [
|
|
11369
|
+
(irisGrid2) => new PivotColumnGroupMouseHandler(irisGrid2),
|
|
11370
|
+
(irisGrid2) => new PivotSortMouseHandler(irisGrid2)
|
|
11371
|
+
],
|
|
11372
|
+
[]
|
|
11373
|
+
);
|
|
11374
|
+
}
|
|
11247
11375
|
function getColumnGroupName(model, modelColumn, depth) {
|
|
11248
11376
|
var _a;
|
|
11249
11377
|
return (_a = model.getColumnHeaderGroup(modelColumn, depth ?? 0)) == null ? void 0 : _a.name;
|
|
11250
11378
|
}
|
|
11251
11379
|
class IrisGridPivotRenderer extends irisGrid.IrisGridRenderer {
|
|
11252
|
-
drawColumnHeaders(context, state) {
|
|
11253
|
-
const {
|
|
11254
|
-
mouseX,
|
|
11255
|
-
mouseY,
|
|
11256
|
-
theme,
|
|
11257
|
-
metrics,
|
|
11258
|
-
draggingColumnSeparator,
|
|
11259
|
-
isDragging,
|
|
11260
|
-
model
|
|
11261
|
-
} = state;
|
|
11262
|
-
const {
|
|
11263
|
-
columnHeaderHeight,
|
|
11264
|
-
floatingColumns,
|
|
11265
|
-
gridX,
|
|
11266
|
-
width,
|
|
11267
|
-
visibleColumns,
|
|
11268
|
-
allColumnWidths,
|
|
11269
|
-
allColumnXs,
|
|
11270
|
-
floatingLeftColumnCount,
|
|
11271
|
-
floatingLeftWidth,
|
|
11272
|
-
floatingRightWidth,
|
|
11273
|
-
modelColumns,
|
|
11274
|
-
columnHeaderMaxDepth
|
|
11275
|
-
} = metrics;
|
|
11276
|
-
if (columnHeaderHeight <= 0) {
|
|
11277
|
-
return;
|
|
11278
|
-
}
|
|
11279
|
-
const {
|
|
11280
|
-
headerHiddenSeparatorSize,
|
|
11281
|
-
headerHiddenSeparatorHoverColor,
|
|
11282
|
-
headerSeparatorColor,
|
|
11283
|
-
headerSeparatorHoverColor
|
|
11284
|
-
} = theme;
|
|
11285
|
-
const hiddenSeparatorHeight = columnHeaderHeight * 0.5;
|
|
11286
|
-
const hiddenY = columnHeaderHeight * (columnHeaderMaxDepth - 1) + columnHeaderHeight * 0.5 - hiddenSeparatorHeight * 0.5;
|
|
11287
|
-
const containsFrozenColumns = floatingLeftColumnCount > 0;
|
|
11288
|
-
if (!isExpandableColumnGridModel(model)) {
|
|
11289
|
-
throw new Error("Unsupported model type");
|
|
11290
|
-
}
|
|
11291
|
-
context.save();
|
|
11292
|
-
this.drawColumnHeadersForRange(
|
|
11293
|
-
context,
|
|
11294
|
-
state,
|
|
11295
|
-
[visibleColumns[0], visibleColumns[visibleColumns.length - 1]],
|
|
11296
|
-
{
|
|
11297
|
-
minX: gridX + floatingLeftWidth,
|
|
11298
|
-
maxX: width - floatingRightWidth
|
|
11299
|
-
}
|
|
11300
|
-
);
|
|
11301
|
-
if (containsFrozenColumns) {
|
|
11302
|
-
this.drawColumnHeadersForRange(
|
|
11303
|
-
context,
|
|
11304
|
-
state,
|
|
11305
|
-
[floatingColumns[0], floatingColumns[floatingColumns.length - 1]],
|
|
11306
|
-
{
|
|
11307
|
-
minX: gridX,
|
|
11308
|
-
maxX: gridX + floatingLeftWidth
|
|
11309
|
-
}
|
|
11310
|
-
);
|
|
11311
|
-
}
|
|
11312
|
-
if (headerSeparatorColor) {
|
|
11313
|
-
context.strokeStyle = headerSeparatorColor;
|
|
11314
|
-
const hiddenColumns = [...allColumnWidths.entries()].filter(([_, w]) => w === 0).map(([index]) => index);
|
|
11315
|
-
context.beginPath();
|
|
11316
|
-
context.fillStyle = headerSeparatorColor;
|
|
11317
|
-
for (let i = 0; i < hiddenColumns.length; i += 1) {
|
|
11318
|
-
const column = hiddenColumns[i];
|
|
11319
|
-
const columnX = getOrThrow(allColumnXs, column);
|
|
11320
|
-
const columnWidth = getOrThrow(allColumnWidths, column);
|
|
11321
|
-
const minX = gridX + columnX + columnWidth + 0.5 - headerHiddenSeparatorSize * 0.5;
|
|
11322
|
-
context.rect(
|
|
11323
|
-
minX,
|
|
11324
|
-
hiddenY,
|
|
11325
|
-
headerHiddenSeparatorSize,
|
|
11326
|
-
hiddenSeparatorHeight
|
|
11327
|
-
);
|
|
11328
|
-
}
|
|
11329
|
-
context.fill();
|
|
11330
|
-
}
|
|
11331
|
-
if (headerSeparatorHoverColor) {
|
|
11332
|
-
let { index: highlightedSeparator, depth } = draggingColumnSeparator ?? {};
|
|
11333
|
-
if (highlightedSeparator == null && mouseX != null && mouseY != null) {
|
|
11334
|
-
const separator = GridColumnSeparatorMouseHandler$1.getColumnSeparator(
|
|
11335
|
-
GridUtils.getGridPointFromXY(mouseX, mouseY, metrics),
|
|
11336
|
-
metrics,
|
|
11337
|
-
model,
|
|
11338
|
-
theme
|
|
11339
|
-
);
|
|
11340
|
-
highlightedSeparator = separator == null ? void 0 : separator.index;
|
|
11341
|
-
depth = separator == null ? void 0 : separator.depth;
|
|
11342
|
-
}
|
|
11343
|
-
let shouldDrawSeparator;
|
|
11344
|
-
if (highlightedSeparator == null) {
|
|
11345
|
-
shouldDrawSeparator = false;
|
|
11346
|
-
} else {
|
|
11347
|
-
const columnIndex = modelColumns.get(highlightedSeparator);
|
|
11348
|
-
const nextColumnIndex = modelColumns.get(highlightedSeparator + 1);
|
|
11349
|
-
if (columnIndex == null || nextColumnIndex == null) {
|
|
11350
|
-
shouldDrawSeparator = false;
|
|
11351
|
-
} else {
|
|
11352
|
-
shouldDrawSeparator = getColumnGroupName(model, columnIndex, depth) !== getColumnGroupName(model, nextColumnIndex, depth);
|
|
11353
|
-
}
|
|
11354
|
-
}
|
|
11355
|
-
if (shouldDrawSeparator && highlightedSeparator != null && depth != null && (!isDragging || draggingColumnSeparator != null)) {
|
|
11356
|
-
context.strokeStyle = headerSeparatorHoverColor;
|
|
11357
|
-
const columnX = getOrThrow(allColumnXs, highlightedSeparator);
|
|
11358
|
-
const columnWidth = getOrThrow(allColumnWidths, highlightedSeparator);
|
|
11359
|
-
const x = gridX + columnX + columnWidth + 0.5;
|
|
11360
|
-
const visibleColumnIndex = visibleColumns.indexOf(highlightedSeparator);
|
|
11361
|
-
const nextColumn = visibleColumnIndex < visibleColumns.length - 1 ? visibleColumns[visibleColumnIndex + 1] : null;
|
|
11362
|
-
const nextColumnWidth = nextColumn != null ? allColumnWidths.get(nextColumn) : null;
|
|
11363
|
-
const isColumnHidden = columnWidth === 0;
|
|
11364
|
-
const isNextColumnHidden = nextColumnWidth != null && nextColumnWidth === 0;
|
|
11365
|
-
if (isColumnHidden) {
|
|
11366
|
-
context.strokeStyle = headerHiddenSeparatorHoverColor;
|
|
11367
|
-
context.fillStyle = headerHiddenSeparatorHoverColor;
|
|
11368
|
-
context.fillRect(
|
|
11369
|
-
x,
|
|
11370
|
-
hiddenY,
|
|
11371
|
-
headerHiddenSeparatorSize * 0.5,
|
|
11372
|
-
hiddenSeparatorHeight
|
|
11373
|
-
);
|
|
11374
|
-
} else if (isNextColumnHidden) {
|
|
11375
|
-
context.fillStyle = headerSeparatorHoverColor;
|
|
11376
|
-
context.fillRect(
|
|
11377
|
-
x - headerHiddenSeparatorSize * 0.5,
|
|
11378
|
-
hiddenY,
|
|
11379
|
-
headerHiddenSeparatorSize * 0.5,
|
|
11380
|
-
hiddenSeparatorHeight
|
|
11381
|
-
);
|
|
11382
|
-
}
|
|
11383
|
-
context.beginPath();
|
|
11384
|
-
context.moveTo(
|
|
11385
|
-
x,
|
|
11386
|
-
(columnHeaderMaxDepth - depth - 1) * columnHeaderHeight
|
|
11387
|
-
);
|
|
11388
|
-
context.lineTo(
|
|
11389
|
-
x,
|
|
11390
|
-
(columnHeaderMaxDepth - depth) * columnHeaderHeight - 1
|
|
11391
|
-
);
|
|
11392
|
-
context.stroke();
|
|
11393
|
-
}
|
|
11394
|
-
}
|
|
11395
|
-
context.restore();
|
|
11396
|
-
}
|
|
11397
11380
|
drawColumnHeadersAtDepth(context, state, range, bounds, depth) {
|
|
11398
11381
|
const { metrics, model, theme } = state;
|
|
11399
11382
|
if (!isIrisGridPivotModel(model)) {
|
|
@@ -11485,7 +11468,8 @@ class IrisGridPivotRenderer extends irisGrid.IrisGridRenderer {
|
|
|
11485
11468
|
},
|
|
11486
11469
|
bounds,
|
|
11487
11470
|
isExpandable,
|
|
11488
|
-
isExpanded
|
|
11471
|
+
isExpanded,
|
|
11472
|
+
jsapiUtils.TableUtils.getSortForColumn(model.sort, columnGroupName)
|
|
11489
11473
|
);
|
|
11490
11474
|
}
|
|
11491
11475
|
columnIndex += 1;
|
|
@@ -11493,7 +11477,7 @@ class IrisGridPivotRenderer extends irisGrid.IrisGridRenderer {
|
|
|
11493
11477
|
}
|
|
11494
11478
|
context.restore();
|
|
11495
11479
|
}
|
|
11496
|
-
drawColumnHeader(context, state, columnText, columnX, columnWidth, style, bounds, isExpandable = false, isExpanded = false) {
|
|
11480
|
+
drawColumnHeader(context, state, columnText, columnX, columnWidth, style, bounds, isExpandable = false, isExpanded = false, sort = null) {
|
|
11497
11481
|
if (columnWidth <= 0) {
|
|
11498
11482
|
return;
|
|
11499
11483
|
}
|
|
@@ -11601,6 +11585,15 @@ class IrisGridPivotRenderer extends irisGrid.IrisGridRenderer {
|
|
|
11601
11585
|
isExpanded
|
|
11602
11586
|
);
|
|
11603
11587
|
}
|
|
11588
|
+
this.drawColumnSourceSortIndicator(
|
|
11589
|
+
context,
|
|
11590
|
+
state,
|
|
11591
|
+
sort,
|
|
11592
|
+
columnText,
|
|
11593
|
+
columnX,
|
|
11594
|
+
columnWidth,
|
|
11595
|
+
{ minX, maxX }
|
|
11596
|
+
);
|
|
11604
11597
|
context.restore();
|
|
11605
11598
|
}
|
|
11606
11599
|
drawColumnHeaderTreeMarker(context, state, columnX, columnWidth, headerY, headerHeight, treeBox, isExpanded) {
|
|
@@ -11628,39 +11621,60 @@ class IrisGridPivotRenderer extends irisGrid.IrisGridRenderer {
|
|
|
11628
11621
|
isExpanded
|
|
11629
11622
|
);
|
|
11630
11623
|
}
|
|
11624
|
+
drawColumnSourceSortIndicator(context, state, sort, columnText, columnX, columnWidth, bounds) {
|
|
11625
|
+
const { metrics, theme } = state;
|
|
11626
|
+
const { gridX, columnHeaderHeight } = metrics;
|
|
11627
|
+
const { headerHorizontalPadding, iconSize: themeIconSize } = theme;
|
|
11628
|
+
const iconSize = Math.round(themeIconSize * 0.75);
|
|
11629
|
+
if (sort == null) {
|
|
11630
|
+
return;
|
|
11631
|
+
}
|
|
11632
|
+
const icon = this.getSortIcon(sort, iconSize);
|
|
11633
|
+
if (!icon) {
|
|
11634
|
+
return;
|
|
11635
|
+
}
|
|
11636
|
+
const textWidth = this.getCachedHeaderWidth(context, columnText);
|
|
11637
|
+
const textRight = gridX + columnX + textWidth + headerHorizontalPadding;
|
|
11638
|
+
let { maxX } = bounds;
|
|
11639
|
+
maxX -= headerHorizontalPadding;
|
|
11640
|
+
const defaultX = gridX + columnX + columnWidth - iconSize;
|
|
11641
|
+
const x = textRight > maxX ? textRight + 1 : Math.min(maxX, defaultX);
|
|
11642
|
+
const y = (columnHeaderHeight - iconSize) * 0.5;
|
|
11643
|
+
context.save();
|
|
11644
|
+
context.fillStyle = theme.headerSortBarColor;
|
|
11645
|
+
context.translate(x, y);
|
|
11646
|
+
context.fill(icon);
|
|
11647
|
+
context.restore();
|
|
11648
|
+
}
|
|
11649
|
+
}
|
|
11650
|
+
function usePivotRenderer() {
|
|
11651
|
+
return React.useMemo(() => new IrisGridPivotRenderer(), []);
|
|
11631
11652
|
}
|
|
11632
|
-
const
|
|
11653
|
+
const IrisGridPivotThemeColors = Object.freeze({
|
|
11633
11654
|
columnSourceHeaderBackground: "var(--dh-color-grid-bg)",
|
|
11634
11655
|
totalsHeaderBackground: "var(--dh-color-grid-bg)"
|
|
11635
11656
|
});
|
|
11636
|
-
|
|
11657
|
+
function getIrisGridPivotTheme() {
|
|
11658
|
+
return Object.freeze({
|
|
11659
|
+
...components.resolveCssVariablesInRecord(IrisGridPivotThemeColors)
|
|
11660
|
+
});
|
|
11661
|
+
}
|
|
11662
|
+
const log$1 = Log.module("@deephaven/js-plugin-pivot/usePivotTheme");
|
|
11663
|
+
function usePivotTheme() {
|
|
11664
|
+
const theme = components.useTheme();
|
|
11665
|
+
return React.useMemo(() => {
|
|
11666
|
+
log$1.debug("Theme changed, updating pivot theme", theme);
|
|
11667
|
+
return getIrisGridPivotTheme();
|
|
11668
|
+
}, [theme]);
|
|
11669
|
+
}
|
|
11637
11670
|
function PivotWidget({
|
|
11638
11671
|
fetch
|
|
11639
11672
|
}) {
|
|
11640
|
-
const
|
|
11641
|
-
const mouseHandlers =
|
|
11642
|
-
|
|
11643
|
-
|
|
11644
|
-
);
|
|
11645
|
-
const renderer = React.useMemo(() => new IrisGridPivotRenderer(), []);
|
|
11646
|
-
const theme = components.useTheme();
|
|
11647
|
-
const pivotTheme = React.useMemo(() => {
|
|
11648
|
-
log$2.debug("Theme changed, updating pivot theme", theme);
|
|
11649
|
-
return components.resolveCssVariablesInRecord(IrisGridPivotTheme);
|
|
11650
|
-
}, [theme]);
|
|
11651
|
-
const pivotTableFetch = React.useCallback(
|
|
11652
|
-
() => fetch().then((result) => {
|
|
11653
|
-
log$2.debug("pivotWidget fetch result:", result);
|
|
11654
|
-
if (!isCorePlusDh(dh)) {
|
|
11655
|
-
throw new Error("CorePlus is not available");
|
|
11656
|
-
}
|
|
11657
|
-
const pivot = new dh.coreplus.pivot.PivotTable(result);
|
|
11658
|
-
log$2.debug("Created pivot table:", pivot);
|
|
11659
|
-
return pivot;
|
|
11660
|
-
}),
|
|
11661
|
-
[dh, fetch]
|
|
11662
|
-
);
|
|
11663
|
-
const fetchResult = useIrisGridPivotModel(pivotTableFetch);
|
|
11673
|
+
const pivotFetch = usePivotTableFetch(fetch);
|
|
11674
|
+
const mouseHandlers = usePivotMouseHandlers();
|
|
11675
|
+
const renderer = usePivotRenderer();
|
|
11676
|
+
const pivotTheme = usePivotTheme();
|
|
11677
|
+
const fetchResult = useIrisGridPivotModel(pivotFetch);
|
|
11664
11678
|
if (fetchResult.status === "loading") {
|
|
11665
11679
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(components.LoadingOverlay, { isLoading: true });
|
|
11666
11680
|
}
|
|
@@ -11684,67 +11698,77 @@ function PivotWidget({
|
|
|
11684
11698
|
}
|
|
11685
11699
|
);
|
|
11686
11700
|
}
|
|
11687
|
-
const log
|
|
11688
|
-
function useHydratePivotGrid(
|
|
11701
|
+
const log = Log.module("@deephaven/js-plugin-pivot/useHydratePivotGrid");
|
|
11702
|
+
function useHydratePivotGrid(id, metadata) {
|
|
11703
|
+
assertNotNull(metadata, "Missing Pivot metadata");
|
|
11704
|
+
const objectFetch = jsapiBootstrap.useObjectFetch(metadata);
|
|
11689
11705
|
const api = jsapiBootstrap.useApi();
|
|
11690
11706
|
const loadPlugin = dashboardCorePlugins.useLoadTablePlugin();
|
|
11691
|
-
const
|
|
11692
|
-
|
|
11693
|
-
|
|
11694
|
-
|
|
11695
|
-
|
|
11696
|
-
|
|
11697
|
-
|
|
11698
|
-
|
|
11699
|
-
|
|
11700
|
-
|
|
11701
|
-
|
|
11702
|
-
|
|
11703
|
-
|
|
11704
|
-
|
|
11705
|
-
|
|
11706
|
-
|
|
11707
|
-
|
|
11708
|
-
|
|
11709
|
-
|
|
11710
|
-
log$1.debug("Theme changed, updating pivot theme", theme);
|
|
11711
|
-
return components.resolveCssVariablesInRecord(IrisGridPivotTheme);
|
|
11712
|
-
}, [theme]);
|
|
11713
|
-
const hydratedProps = React.useMemo(
|
|
11714
|
-
() => ({
|
|
11707
|
+
const mouseHandlers = usePivotMouseHandlers();
|
|
11708
|
+
const renderer = usePivotRenderer();
|
|
11709
|
+
const theme = usePivotTheme();
|
|
11710
|
+
const { status } = objectFetch;
|
|
11711
|
+
if (status === "loading") {
|
|
11712
|
+
log.debug("Widget is loading");
|
|
11713
|
+
return { status: "loading" };
|
|
11714
|
+
}
|
|
11715
|
+
if (status === "error") {
|
|
11716
|
+
log.debug("Error fetching widget:", objectFetch.error);
|
|
11717
|
+
return {
|
|
11718
|
+
status: "error",
|
|
11719
|
+
error: objectFetch.error
|
|
11720
|
+
};
|
|
11721
|
+
}
|
|
11722
|
+
const { fetch } = objectFetch;
|
|
11723
|
+
return {
|
|
11724
|
+
status: "success",
|
|
11725
|
+
props: {
|
|
11715
11726
|
loadPlugin,
|
|
11716
11727
|
localDashboardId: id,
|
|
11717
|
-
makeModel: async ()
|
|
11718
|
-
|
|
11719
|
-
|
|
11728
|
+
makeModel: async function makeModel() {
|
|
11729
|
+
log.debug("Fetching pivot widget");
|
|
11730
|
+
const widget = await fetch();
|
|
11731
|
+
log.debug("Pivot fetch result:", widget);
|
|
11732
|
+
if (!isCorePlusDh(api)) {
|
|
11733
|
+
throw new Error("CorePlus is not available");
|
|
11734
|
+
}
|
|
11735
|
+
const pivotTable = new api.coreplus.pivot.PivotTable(widget);
|
|
11736
|
+
log.debug("Created pivot table:", pivotTable);
|
|
11737
|
+
return new IrisGridPivotModel(api, pivotTable);
|
|
11720
11738
|
},
|
|
11721
11739
|
metadata,
|
|
11722
11740
|
mouseHandlers,
|
|
11723
|
-
renderer
|
|
11724
|
-
|
|
11725
|
-
|
|
11726
|
-
|
|
11727
|
-
const hydratedPropsWithTheme = React.useMemo(
|
|
11728
|
-
() => ({ ...hydratedProps, theme: pivotTheme }),
|
|
11729
|
-
[hydratedProps, pivotTheme]
|
|
11730
|
-
);
|
|
11731
|
-
return hydratedPropsWithTheme;
|
|
11741
|
+
renderer,
|
|
11742
|
+
theme
|
|
11743
|
+
}
|
|
11744
|
+
};
|
|
11732
11745
|
}
|
|
11733
11746
|
const PivotPanel = React.forwardRef(
|
|
11747
|
+
// Unconnected IrisGridPanel type is not exported from dashboard-core-plugins
|
|
11734
11748
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
11735
|
-
(
|
|
11736
|
-
const { localDashboardId,
|
|
11737
|
-
const
|
|
11738
|
-
|
|
11739
|
-
|
|
11740
|
-
|
|
11741
|
-
)
|
|
11749
|
+
(panelProps, ref) => {
|
|
11750
|
+
const { localDashboardId, metadata, panelState, ...props } = panelProps;
|
|
11751
|
+
const hydrateResult = useHydratePivotGrid(localDashboardId, metadata);
|
|
11752
|
+
if (hydrateResult.status === "loading") {
|
|
11753
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(components.LoadingOverlay, { isLoading: true });
|
|
11754
|
+
}
|
|
11755
|
+
if (hydrateResult.status === "error") {
|
|
11756
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11757
|
+
components.LoadingOverlay,
|
|
11758
|
+
{
|
|
11759
|
+
errorMessage: getErrorMessage(hydrateResult.error),
|
|
11760
|
+
isLoading: false
|
|
11761
|
+
}
|
|
11762
|
+
);
|
|
11763
|
+
}
|
|
11764
|
+
const { props: hydratedProps } = hydrateResult;
|
|
11742
11765
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
11743
11766
|
dashboardCorePlugins.IrisGridPanel,
|
|
11744
11767
|
{
|
|
11745
11768
|
ref,
|
|
11746
11769
|
...props,
|
|
11747
|
-
...hydratedProps
|
|
11770
|
+
...hydratedProps,
|
|
11771
|
+
panelState
|
|
11748
11772
|
}
|
|
11749
11773
|
);
|
|
11750
11774
|
}
|
|
@@ -11759,63 +11783,15 @@ const PivotPlugin = {
|
|
|
11759
11783
|
icon: icons.dhTable,
|
|
11760
11784
|
title: "Pivot Table"
|
|
11761
11785
|
};
|
|
11762
|
-
const urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
|
|
11763
|
-
let nanoid = (size = 21) => {
|
|
11764
|
-
let id = "";
|
|
11765
|
-
let bytes = crypto.getRandomValues(new Uint8Array(size |= 0));
|
|
11766
|
-
while (size--) {
|
|
11767
|
-
id += urlAlphabet[bytes[size] & 63];
|
|
11768
|
-
}
|
|
11769
|
-
return id;
|
|
11770
|
-
};
|
|
11771
11786
|
const VARIABLE_TYPE = "PivotTable";
|
|
11772
|
-
|
|
11773
|
-
|
|
11774
|
-
|
|
11775
|
-
|
|
11776
|
-
|
|
11777
|
-
|
|
11778
|
-
|
|
11779
|
-
|
|
11780
|
-
dragEvent,
|
|
11781
|
-
fetch,
|
|
11782
|
-
metadata = {},
|
|
11783
|
-
panelId = nanoid(),
|
|
11784
|
-
widget
|
|
11785
|
-
}) => {
|
|
11786
|
-
const { name, type } = widget;
|
|
11787
|
-
if (type !== VARIABLE_TYPE) {
|
|
11788
|
-
return;
|
|
11789
|
-
}
|
|
11790
|
-
log.info("Panel opened of type", type);
|
|
11791
|
-
const config = {
|
|
11792
|
-
type: "react-component",
|
|
11793
|
-
component: PivotPanel.displayName,
|
|
11794
|
-
props: {
|
|
11795
|
-
localDashboardId: id,
|
|
11796
|
-
id: panelId,
|
|
11797
|
-
metadata: {
|
|
11798
|
-
...metadata,
|
|
11799
|
-
...widget
|
|
11800
|
-
},
|
|
11801
|
-
fetch
|
|
11802
|
-
},
|
|
11803
|
-
title: name ?? void 0,
|
|
11804
|
-
id: panelId
|
|
11805
|
-
};
|
|
11806
|
-
const { root: root2 } = layout;
|
|
11807
|
-
dashboard.LayoutUtils.openComponent({ root: root2, config, dragEvent });
|
|
11808
|
-
},
|
|
11809
|
-
[id, layout]
|
|
11810
|
-
);
|
|
11811
|
-
React.useEffect(() => {
|
|
11812
|
-
assertNotNull(PivotPanel.displayName);
|
|
11813
|
-
const cleanups = [registerComponent(PivotPanel.displayName, PivotPanel)];
|
|
11814
|
-
return () => {
|
|
11815
|
-
cleanups.forEach((cleanup) => cleanup());
|
|
11816
|
-
};
|
|
11817
|
-
}, [registerComponent]);
|
|
11818
|
-
dashboard.useListener(layout.eventHub, "PanelEvent.OPEN", handlePanelOpen);
|
|
11787
|
+
function DashboardPlugin(dashboardProps) {
|
|
11788
|
+
assertNotNull(PivotPanel.displayName);
|
|
11789
|
+
dashboard.useDashboardPanel({
|
|
11790
|
+
dashboardProps,
|
|
11791
|
+
componentName: PivotPanel.displayName,
|
|
11792
|
+
supportedTypes: VARIABLE_TYPE,
|
|
11793
|
+
component: PivotPanel
|
|
11794
|
+
});
|
|
11819
11795
|
return null;
|
|
11820
11796
|
}
|
|
11821
11797
|
exports.DashboardPlugin = DashboardPlugin;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deephaven/js-plugin-pivot",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Pivot plugin for Deephaven",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Deephaven",
|
|
@@ -29,7 +29,6 @@
|
|
|
29
29
|
"@types/react-dom": "^17.0.2",
|
|
30
30
|
"@vitejs/plugin-react-swc": "^3.0.0",
|
|
31
31
|
"react": "^17.0.2",
|
|
32
|
-
"typescript": "^4.5.4",
|
|
33
32
|
"vite": "~4.1.4"
|
|
34
33
|
},
|
|
35
34
|
"peerDependencies": {
|
|
@@ -38,15 +37,15 @@
|
|
|
38
37
|
},
|
|
39
38
|
"dependencies": {
|
|
40
39
|
"@deephaven/components": "^0.85.35",
|
|
41
|
-
"@deephaven/dashboard": "^0.85.
|
|
42
|
-
"@deephaven/dashboard-core-plugins": "^0.85.
|
|
43
|
-
"@deephaven/grid": "^0.85.
|
|
40
|
+
"@deephaven/dashboard": "^0.85.38",
|
|
41
|
+
"@deephaven/dashboard-core-plugins": "^0.85.37",
|
|
42
|
+
"@deephaven/grid": "^0.85.38",
|
|
44
43
|
"@deephaven/icons": "^0.85.0",
|
|
45
|
-
"@deephaven/iris-grid": "^0.85.
|
|
44
|
+
"@deephaven/iris-grid": "^0.85.39",
|
|
46
45
|
"@deephaven/jsapi-bootstrap": "^0.85.35",
|
|
47
|
-
"@deephaven/jsapi-utils": "^0.85.
|
|
46
|
+
"@deephaven/jsapi-utils": "^0.85.39",
|
|
48
47
|
"@deephaven/log": "^0.85.19",
|
|
49
|
-
"@deephaven/plugin": "^0.85.
|
|
48
|
+
"@deephaven/plugin": "^0.85.37",
|
|
50
49
|
"@deephaven/utils": "^0.85.35",
|
|
51
50
|
"lodash.clamp": "^4.0.3",
|
|
52
51
|
"lodash.throttle": "^4.1.1",
|
|
@@ -59,5 +58,5 @@
|
|
|
59
58
|
"files": [
|
|
60
59
|
"dist/index.js"
|
|
61
60
|
],
|
|
62
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "d75552a0c9814b285ce678709e74584f2ed9611c"
|
|
63
62
|
}
|