Skip to content

Commit c6c76ed

Browse files
committed
try adding arrow table
This isn't working, running into a weird error: ``` import { bpfrpt_proptype_WindowScroller } from "../WindowScroller.js"; ``` with react-virtualized and vite. See bvaughn/react-virtualized#1635 bvaughn/react-virtualized#1632 https://github.com/uber/baseweb/issues/4129 Seems like react-virtualized is an inactive project, so probably should just switch to a more active full featured table library
1 parent 7c9d3f9 commit c6c76ed

File tree

8 files changed

+182
-2
lines changed

8 files changed

+182
-2
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"@reduxjs/toolkit": "^1.7.1",
2020
"@rematch/core": "^2.2.0",
2121
"@rematch/immer": "^2.1.3",
22+
"@types/react-virtualized": "^9.21.16",
2223
"apache-arrow": "^6.0.1",
2324
"chakra-react-select": "^1.3.2",
2425
"compassql": "^0.21.2",
@@ -37,6 +38,7 @@
3738
"react-instantsearch-dom": "^6.15.0",
3839
"react-redux": "^7.2.6",
3940
"react-vega": "^7.4.4",
41+
"react-virtualized": "^9.22.3",
4042
"redux": "^4.1.2",
4143
"reselect": "^4.1.4",
4244
"sqlstring": "^2.3.2",

pnpm-lock.yaml

Lines changed: 37 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import React from "react";
2+
import { useAppSelector } from "hooks";
3+
import { ArrowTableGrid } from "./arrow-viewer/ArrowTableGrid";
4+
5+
export const TableGrid = () => {
6+
const data = useAppSelector((s) => s.sqlQuery.data);
7+
const status = useAppSelector((s) => s.sqlQuery.status);
8+
return status == "completed" ? (
9+
<ArrowTableGrid table={data} width={300} height={800}></ArrowTableGrid>
10+
) : null;
11+
};
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// From github.com/cwharris/arrow-viewer
2+
import {Table as ArrowTable} from "apache-arrow";
3+
4+
import { valueToString } from "utils/arrow-utils"
5+
6+
import { Table, Column, AutoSizer, Index } from "react-virtualized";
7+
8+
import "react-virtualized/styles.css";
9+
import { defaultRowRenderer, TableCellProps, TableHeaderProps, TableHeaderRowProps, TableRowProps } from "react-virtualized/dist/es/Table";
10+
11+
export function ArrowTableGrid({
12+
table,
13+
width,
14+
height,
15+
}: {
16+
table: ArrowTable;
17+
width: number;
18+
height: number;
19+
}): JSX.Element {
20+
return (
21+
<AutoSizer>
22+
{(size) => (
23+
<Table
24+
{...size}
25+
height={height - 10}
26+
rowHeight={28}
27+
headerHeight={40}
28+
rowStyle={rowStyle}
29+
rowCount={table.length}
30+
rowGetter={({ index }: Index) => table.get(index)}
31+
rowRenderer={(props: TableRowProps) => {
32+
// console.log(props);
33+
34+
return defaultRowRenderer({
35+
...props,
36+
style: { ...props.style, width: props.style.width - 15 },
37+
});
38+
}}
39+
headerStyle={headerStyle()}
40+
headerRowRenderer={({
41+
className,
42+
columns,
43+
style,
44+
}: TableHeaderRowProps) => (
45+
<div
46+
role="row"
47+
className={className}
48+
style={{ ...style, ...headerStyle(), width: size.width }}
49+
>
50+
{columns}
51+
</div>
52+
)}
53+
>
54+
{table.schema.fields.map((field, idx) => {
55+
// console.log(field, idx);
56+
57+
return (
58+
<Column
59+
key={idx}
60+
width={25}
61+
minWidth={25}
62+
flexGrow={1}
63+
dataKey={idx.toString()}
64+
label={`${field.toString()}`}
65+
columnData={table.getColumn(field.name).toArray()}
66+
cellDataGetter={(props) => {
67+
// console.log(props);
68+
const d = props.rowData[idx];
69+
// console.log(d);
70+
return d;
71+
}}
72+
cellRenderer={({ cellData }: TableCellProps) =>
73+
valueToString(cellData)
74+
}
75+
headerRenderer={({
76+
label,
77+
}: TableHeaderProps) => label}
78+
/>
79+
);
80+
})}
81+
</Table>
82+
)}
83+
</AutoSizer>
84+
);
85+
}
86+
87+
const headerStyle = () =>
88+
({ textAlign: "right", textTransform: "none" } as React.CSSProperties);
89+
90+
const rowStyle = ({ index }: Index) =>
91+
index % 2 === 0
92+
? {
93+
...headerStyle(),
94+
borderBottom: "1px solid #e0e0e0",
95+
backgroundColor: "#fff",
96+
}
97+
: {
98+
...headerStyle(),
99+
borderBottom: "1px solid #e0e0e0",
100+
backgroundColor: "#fafafa",
101+
};

src/features/workspace/components/Workspace.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Box, Text } from "@chakra-ui/react";
22
import { DataSelector } from "features/selectData/components/DataSelector";
33
import { SQLEditor } from "features/sqlEditor/components/SQLEditor";
4+
import { TableGrid } from "features/sqlEditor/components/TableGrid";
45
import {
56
IJsonModel,
67
Layout,
@@ -22,6 +23,7 @@ const ComponentsMap: Record<string, React.ComponentType<{ node: TabNode }>> = {
2223
fields: Fields,
2324
sqlEditor: SQLEditor,
2425
selectData: DataSelector,
26+
tableGrid: TableGrid
2527
};
2628

2729
export const Workspace = () => {

src/hooks/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
2+
import type { RootState, Dispatch } from 'store/store'
3+
4+
// Use throughout your app instead of plain `useDispatch` and `useSelector`
5+
export const useAppDispatch = () => useDispatch<Dispatch>()
6+
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector

src/models/workspace.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ const initialModel = {
4242
type: "tab",
4343
enableClose: false,
4444
name: "Table View",
45-
component: "button",
45+
component: "tableGrid",
4646
},
4747
],
4848
},

src/utils/arrow-utils.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// from import { valueToString } from "apache-arrow/util/pretty";
2+
export function valueToString(x) {
3+
if (x === null) {
4+
return 'null';
5+
}
6+
if (x === undefined) {
7+
return 'undefined';
8+
}
9+
switch (typeof x) {
10+
case 'number': return `${x}`;
11+
case 'bigint': return `${x}`;
12+
case 'string': return `"${x}"`;
13+
}
14+
// If [Symbol.toPrimitive] is implemented (like in BN)
15+
// use it instead of JSON.stringify(). This ensures we
16+
// print BigInts, Decimals, and Binary in their native
17+
// representation
18+
if (typeof x[Symbol.toPrimitive] === 'function') {
19+
return x[Symbol.toPrimitive]('string');
20+
}
21+
return ArrayBuffer.isView(x) ? `[${x}]` : JSON.stringify(x);
22+
}

0 commit comments

Comments
 (0)