Skip to content

Commit

Permalink
feat: Create UI to Display Partitioned Tables (#1663)
Browse files Browse the repository at this point in the history
- `PartitionedTable` objects can now be opened and displayed with a new
UI
- Supports switching between partitions and viewing the merged or key
table
- Partition aware parquet tables will also share this new UI
  - The new UI will no longer allow users to enter invalid partitions
- Closes #1143
- Depends on the following changes to core:
  - deephaven/deephaven-core#4789
  - deephaven/deephaven-core#4931
  - deephaven/deephaven-core#4940

### Testing Instructions
#### PartitionedTable
1. Run the code and open the table `pt`
    ```py
    from deephaven import empty_table
  
_t = empty_table(100).update(["verylongcolumn=(int)Math.floor(i/5)",
"veryveryverylongcolumn=i"])
    pt = _t.partition_by(["verylongcolumn", "veryveryverylongcolumn"])
    ```
2. Check that the features specified in the
[spec](https://user-images.githubusercontent.com/1576283/268390627-d427b993-1d09-43a5-960f-4e6cd0848f36.png)
are present:
- Resizing the panel horizontally wraps the dropdown without wrapping
the '>'
- Hovering over the 'Key' and 'Merge' buttons displays the correct
labels
- The initial partition should be the first valid partition available
when all columns are sorted in descending order
    - Options in the dropdown are displayed in descending order
3. Clicking the 'Key' and 'Merge' tables should correctly display the
respective table and the button should visually indicate if one of them
is being displayed. All the dropdowns should show empty values while one
of the buttons is active.
- While one of the toggle buttons is active, only the leftmost dropdown
should be enabled
4. After clearing the dropdowns by clicking either the 'Key' or 'Merge'
button, selecting any value on any dropdown should automatically set the
remaining dropdowns and display a valid partition.
5. Dropdowns should only contain values that are valid with respect to
the selected values of all the dropdowns left of it
6. Changing the value of a dropdown should try to preserve dropdowns to
the right of it. If this is not possible, the values of the dropdowns
right of it should be changed so that a valid partition can be
displayed.

#### Parquet Tables
1. Run the following code and verify that all tables display and
function correctly for every data type
    ```py
    from deephaven import empty_table
    part = empty_table(4).update("II=ii")
  
    from deephaven.parquet import write, read
    
    write(part, "/tmp/pt-test/intCol=0/part.parquet")
    write(part, "/tmp/pt-test/intCol=1/part.parquet")
    int_partition = read("/tmp/pt-test")
    
    write(part, "/tmp/string-test/stringCol=hello/part.parquet")
    write(part, "/tmp/string-test/stringCol=world/part.parquet")
    string_partition = read("/tmp/string-test")
    
    write(part, "/tmp/double-test/doubleCol=1.5/part.parquet")
    write(part, "/tmp/double-test/doubleCol=2.5/part.parquet")
    double_partition = read("/tmp/double-test")
    
    write(part, "/tmp/char-test/charCol=a/part.parquet")
    write(part, "/tmp/char-test/charCol=b/part.parquet")
    char_partition = read("/tmp/char-test")
    
    write(part, "/tmp/long-test/longCol=2147483648/part.parquet")
    write(part, "/tmp/long-test/longCol=2147483650/part.parquet")
    long_partition = read("/tmp/long-test")
    
    write(part, "/tmp/bool-test/boolCol=true/part.parquet")
    write(part, "/tmp/bool-test/boolCol=false/part.parquet")
    bool_partition = read("/tmp/bool-test")

    write(part, "/tmp/multi_test/x=0/y=0/part.parquet")
    write(part, "/tmp/multi_test/x=0/y=1/part.parquet")
    write(part, "/tmp/multi_test/x=1/y=0/part.parquet")
    write(part, "/tmp/multi_test/x=1/y=1/part.parquet")
    write(part, "/tmp/multi_test/x=1/y=2/part.parquet")
    multi_partition = read("/tmp/multi_test")
    ```

---------

Co-authored-by: georgecwan <georgecwan@users.noreply.github.com>
Co-authored-by: mikebender <mikebender@deephaven.io>
  • Loading branch information
3 people committed Jan 18, 2024
1 parent c6a099d commit db219ca
Show file tree
Hide file tree
Showing 36 changed files with 1,441 additions and 1,116 deletions.
2 changes: 2 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions packages/code-studio/src/styleguide/MockIrisGridTreeModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,22 @@ class MockIrisGridTreeModel
// Ignore for mock
}

get partition(): never[] {
return [];
}

set partition(partition: never[]) {
// Ignore for mock
}

get partitionColumns(): never[] {
return [];
}

set partitionColumns(partitionColumns: never[]) {
// Ignore for mock
}

set formatter(formatter: Formatter) {
// Ignore for mock
}
Expand Down
20 changes: 5 additions & 15 deletions packages/components/src/Option.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,13 @@
import React from 'react';
import React, { OptionHTMLAttributes } from 'react';

export type OptionProps = {
export type OptionProps = OptionHTMLAttributes<HTMLOptionElement> & {
children: React.ReactNode;
disabled?: boolean;
value: string;
'data-testid'?: string;
};

function Option({
children,
disabled,
value,
'data-testid': dataTestId,
}: OptionProps): JSX.Element {
return (
<option value={value} disabled={disabled} data-testid={dataTestId}>
{children}
</option>
);
function Option({ children, ...props }: OptionProps): JSX.Element {
// eslint-disable-next-line react/jsx-props-no-spreading
return <option {...props}>{children}</option>;
}

export default Option;
3 changes: 2 additions & 1 deletion packages/console/src/common/ConsoleUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ class ConsoleUtils {
return (
type === dh.VariableType.TABLE ||
type === dh.VariableType.TREETABLE ||
type === dh.VariableType.HIERARCHICALTABLE
type === dh.VariableType.HIERARCHICALTABLE ||
type === dh.VariableType.PARTITIONEDTABLE
);
}

Expand Down
1 change: 1 addition & 0 deletions packages/console/src/common/ObjectIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ function ObjectIcon({ type }: ObjectIconProps): JSX.Element {
case dh.VariableType.TABLEMAP:
case dh.VariableType.TREETABLE:
case dh.VariableType.HIERARCHICALTABLE:
case dh.VariableType.PARTITIONEDTABLE:
return <FontAwesomeIcon icon={dhTable} />;
case dh.VariableType.FIGURE:
return <FontAwesomeIcon icon={vsGraph} />;
Expand Down
7 changes: 6 additions & 1 deletion packages/dashboard-core-plugins/src/GridPluginConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ const GridPluginConfig: WidgetPlugin = {
type: PluginType.WIDGET_PLUGIN,
component: GridWidgetPlugin,
panelComponent: GridPanelPlugin,
supportedTypes: ['Table', 'TreeTable', 'HierarchicalTable'],
supportedTypes: [
'Table',
'TreeTable',
'HierarchicalTable',
'PartitionedTable',
],
icon: dhTable,
};

Expand Down
33 changes: 14 additions & 19 deletions packages/dashboard-core-plugins/src/panels/IrisGridPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import {
ColumnHeaderGroup,
IrisGridContextMenuData,
IrisGridTableModel,
PartitionConfig,
} from '@deephaven/iris-grid';
import {
AdvancedFilterOptions,
Expand Down Expand Up @@ -126,9 +127,7 @@ export interface PanelState {
type LoadedPanelState = PanelState & {
irisGridPanelState: PanelState['irisGridPanelState'] & {
partitions?: (string | null)[];
partitionColumns?: ColumnName[];
partition?: string | null;
partitionColumn?: ColumnName | null;
};
};

Expand Down Expand Up @@ -190,7 +189,7 @@ interface IrisGridPanelState {
movedRows: readonly MoveOperation[];
isSelectingPartition: boolean;
partitions: (string | null)[];
partitionColumns: Column[];
partitionConfig?: PartitionConfig;
rollupConfig?: UIRollupConfig;
showSearchBar: boolean;
searchValue: string;
Expand Down Expand Up @@ -296,7 +295,6 @@ export class IrisGridPanel extends PureComponent<
movedRows: [],
isSelectingPartition: false,
partitions: [],
partitionColumns: [],
rollupConfig: undefined,
showSearchBar: false,
searchValue: '',
Expand Down Expand Up @@ -466,13 +464,11 @@ export class IrisGridPanel extends PureComponent<
model: IrisGridModel,
isSelectingPartition: boolean,
partitions: (string | null)[],
partitionColumns: Column[],
advancedSettings: Map<AdvancedSettingsType, boolean>
) =>
IrisGridUtils.dehydrateIrisGridPanelState(model, {
isSelectingPartition,
partitions,
partitionColumns,
advancedSettings,
})
);
Expand All @@ -499,7 +495,8 @@ export class IrisGridPanel extends PureComponent<
pendingDataMap: PendingDataMap<UIRow>,
frozenColumns: readonly ColumnName[],
conditionalFormats: readonly SidebarFormattingRule[],
columnHeaderGroups: readonly ColumnHeaderGroup[]
columnHeaderGroups: readonly ColumnHeaderGroup[],
partitionConfig: PartitionConfig | undefined
) => {
assertNotNull(this.irisGridUtils);
return this.irisGridUtils.dehydrateIrisGridState(model, {
Expand All @@ -525,6 +522,7 @@ export class IrisGridPanel extends PureComponent<
frozenColumns,
conditionalFormats,
columnHeaderGroups,
partitionConfig,
});
}
);
Expand Down Expand Up @@ -1035,12 +1033,8 @@ export class IrisGridPanel extends PureComponent<
}[]
);
}
const {
isSelectingPartition,
partitions,
partitionColumns,
advancedSettings,
} = IrisGridUtils.hydrateIrisGridPanelState(model, irisGridPanelState);
const { isSelectingPartition, partitions, advancedSettings } =
IrisGridUtils.hydrateIrisGridPanelState(model, irisGridPanelState);
assertNotNull(this.irisGridUtils);
const {
advancedFilters,
Expand All @@ -1063,6 +1057,7 @@ export class IrisGridPanel extends PureComponent<
frozenColumns,
conditionalFormats,
columnHeaderGroups,
partitionConfig,
} = this.irisGridUtils.hydrateIrisGridState(model, {
...irisGridState,
...irisGridStateOverrides,
Expand All @@ -1084,7 +1079,6 @@ export class IrisGridPanel extends PureComponent<
movedColumns,
movedRows,
partitions,
partitionColumns,
quickFilters,
reverseType,
rollupConfig,
Expand All @@ -1102,6 +1096,7 @@ export class IrisGridPanel extends PureComponent<
isStuckToBottom,
isStuckToRight,
columnHeaderGroups,
partitionConfig,
});
} catch (error) {
log.error('loadPanelState failed to load panelState', panelState, error);
Expand All @@ -1117,7 +1112,6 @@ export class IrisGridPanel extends PureComponent<
panelState: oldPanelState,
isSelectingPartition,
partitions,
partitionColumns,
advancedSettings,
} = this.state;
const {
Expand All @@ -1140,6 +1134,7 @@ export class IrisGridPanel extends PureComponent<
frozenColumns,
conditionalFormats,
columnHeaderGroups,
partitionConfig,
} = irisGridState;
assertNotNull(model);
assertNotNull(metrics);
Expand All @@ -1153,7 +1148,6 @@ export class IrisGridPanel extends PureComponent<
model,
isSelectingPartition,
partitions,
partitionColumns,
advancedSettings
),
this.getDehydratedIrisGridState(
Expand All @@ -1177,7 +1171,8 @@ export class IrisGridPanel extends PureComponent<
pendingDataMap,
frozenColumns,
conditionalFormats,
columnHeaderGroups
columnHeaderGroups,
partitionConfig
),
this.getDehydratedGridState(
model,
Expand Down Expand Up @@ -1241,7 +1236,7 @@ export class IrisGridPanel extends PureComponent<
movedColumns,
movedRows,
partitions,
partitionColumns,
partitionConfig,
quickFilters,
reverseType,
rollupConfig,
Expand Down Expand Up @@ -1323,7 +1318,7 @@ export class IrisGridPanel extends PureComponent<
movedColumns={movedColumns}
movedRows={movedRows}
partitions={partitions}
partitionColumns={partitionColumns}
partitionConfig={partitionConfig}
quickFilters={quickFilters}
reverseType={reverseType}
rollupConfig={rollupConfig}
Expand Down
1 change: 1 addition & 0 deletions packages/embed-grid/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const SUPPORTED_TYPES: string[] = [
dh.VariableType.TREETABLE,
dh.VariableType.HIERARCHICALTABLE,
dh.VariableType.PANDAS,
dh.VariableType.PARTITIONEDTABLE,
];

export type Command = 'filter' | 'sort';
Expand Down
3 changes: 1 addition & 2 deletions packages/grid/src/DataBarGridModel.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { GridThemeType } from '.';
import { ModelIndex } from './GridMetrics';
import GridModel from './GridModel';
import { GridColor } from './GridTheme';
import { GridColor, type GridTheme as GridThemeType } from './GridTheme';

export type Marker = { value: number; color: string };
export type AxisOption = 'proportional' | 'middle' | 'directional';
Expand Down
1 change: 1 addition & 0 deletions packages/iris-grid/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"@deephaven/filters": "file:../filters",
"@deephaven/grid": "file:../grid",
"@deephaven/icons": "file:../icons",
"@deephaven/jsapi-components": "file:../jsapi-components",
"@deephaven/jsapi-types": "file:../jsapi-types",
"@deephaven/jsapi-utils": "file:../jsapi-utils",
"@deephaven/log": "file:../log",
Expand Down
Loading

0 comments on commit db219ca

Please sign in to comment.