@deephaven/js-plugin-ag-grid
Version:
Deephaven AG Grid plugin
152 lines • 6.49 kB
JavaScript
import { TableUtils } from '@deephaven/jsapi-utils';
import AgGridFormatter from './AgGridFormatter';
export const TREE_NODE_KEY = '__dhTreeNodeKey__';
export function isPivotTable(table) {
return ('columnSources' in table && 'rowSources' in table && 'valueSources' in table);
}
export function isTable(table) {
return ('columns' in table &&
'rollup' in table &&
typeof table.rollup === 'function');
}
export function isTreeTable(table) {
return ('columns' in table &&
'groupedColumns' in table &&
'expand' in table &&
'collapse' in table);
}
/**
* Returns whether the given data type is groupable using Deephaven.
* @param dataType The data type to check
* @returns True if the data type is groupable, false otherwise
*/
export function isRowGroupable(dataType) {
return (!TableUtils.isBigDecimalType(dataType) &&
!TableUtils.isBigIntegerType(dataType));
}
/**
* Get the cell style function for a specific data type.
* @param dataType Data type of the column
* @returns A function to style the cell based on its data type
*/
export function getCellStyleFunction(dataType) {
switch (dataType) {
case TableUtils.dataType.DECIMAL:
case TableUtils.dataType.INT:
return AgGridFormatter.styleForNumberCell;
case TableUtils.dataType.DATETIME:
return AgGridFormatter.styleForDateCell;
default:
return undefined;
}
}
/**
* Converts a Deephaven column to an AG Grid ColDef with appropriate properties.
*
* @param column Deephaven column to map
* @param templateColDef Template ColDef to use as a base
* @returns The equivalent AG Grid ColDef
*/
export function convertColumnToColDef(column, templateColDef) {
const dataType = TableUtils.getNormalizedType(column.type);
switch (dataType) {
case TableUtils.dataType.BOOLEAN:
return Object.assign(Object.assign({}, templateColDef), { cellDataType: dataType, filter: true,
// Disable checkmarks: https://github.com/ag-grid/ag-grid/issues/9315
cellRenderer: null });
case TableUtils.dataType.CHAR:
return Object.assign(Object.assign({}, templateColDef), { cellDataType: dataType, filter: 'agNumberColumnFilter', filterParams: {
allowedCharPattern: 'a-zA-Z',
buttons: ['reset', 'apply'],
numberParser: (text) => text != null && text.length === 1 ? text.charCodeAt(0) : null,
numberFormatter: (value) => value != null ? String.fromCharCode(value) : null,
} });
case TableUtils.dataType.DATETIME:
return Object.assign(Object.assign({}, templateColDef), { cellDataType: dataType, filter: 'agDateColumnFilter', cellStyle: getCellStyleFunction(dataType) });
case TableUtils.dataType.DECIMAL:
return Object.assign(Object.assign({}, templateColDef), { cellDataType: dataType, filter: 'agNumberColumnFilter', cellStyle: getCellStyleFunction(dataType) });
case TableUtils.dataType.INT:
return Object.assign(Object.assign({}, templateColDef), { cellDataType: dataType, filter: 'agNumberColumnFilter', cellStyle: getCellStyleFunction(dataType) });
case TableUtils.dataType.STRING:
return Object.assign(Object.assign({}, templateColDef), { cellDataType: dataType, filter: true });
case TableUtils.dataType.UNKNOWN:
return Object.assign(Object.assign({}, templateColDef), { cellDataType: TableUtils.dataType.STRING, filter: false });
}
}
export function getColumnDefs(table) {
var _a;
if (isTable(table) || isTreeTable(table)) {
const groupedColSet = new Set((isTreeTable(table) ? table.groupedColumns : []).map(c => c.name));
const newDefs = (_a = table === null || table === void 0 ? void 0 : table.columns.map(c => {
const templateColDef = groupedColSet.has(c.name)
? {
field: c.name,
headerName: c.name,
rowGroup: true,
}
: {
field: c.name,
headerName: c.name,
enableRowGroup: isRowGroupable(c.type),
enableValue: true,
};
return convertColumnToColDef(c, templateColDef);
})) !== null && _a !== void 0 ? _a : [];
return newDefs;
}
if (isPivotTable(table)) {
// For pivot tables, we need to create ColDefs for the row, column, and value sources.
const colDefs = [];
table.rowSources.forEach(c => {
colDefs.push({ field: c.name, rowGroup: true });
});
table.columnSources.forEach(c => {
colDefs.push({ field: c.name, pivot: true });
});
table.valueSources.forEach(c => {
// We're just pushing an `aggFunc` here so it shows up correctly in the UI, but we also set the `suppressAggFuncInHeader` so that it doesn't actually appear.
// We specify our own custom aggregation name. We don't actually use it, since the server does the aggregation already.
colDefs.push({ field: c.name, aggFunc: 'deephaven-aggregation' });
});
return colDefs;
}
throw new Error(`Unsupported table type: ${table}`);
}
export function getSideBar(table) {
return {
toolPanels: [
{
id: 'columns',
labelDefault: 'Columns',
labelKey: 'columns',
iconKey: 'columns',
toolPanel: 'agColumnsToolPanel',
toolPanelParams: {
suppressRowGroups: isTreeTable(table),
suppressValues: isTreeTable(table),
suppressPivots: true,
},
},
],
};
}
function isTreeRow(row) {
return 'hasChildren' in row && 'isExpanded' in row && 'depth' in row;
}
export function extractViewportRow(row, columns) {
const data = {};
for (let c = 0; c < columns.length; c += 1) {
const column = columns[c];
data[column.name] = row.get(column);
}
if (isTreeRow(row)) {
data[TREE_NODE_KEY] = {
hasChildren: row.hasChildren,
isExpanded: row.isExpanded,
depth: row.depth,
index: row.index.asNumber(),
};
}
return data;
}
//# sourceMappingURL=AgGridTableUtils.js.map