Skip to content

Commit 5328ccb

Browse files
committed
@wq/analyst v3
1 parent a0fb63c commit 5328ccb

17 files changed

+451
-1491
lines changed

Diff for: package-lock.json

+27-1,261
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: packages/analyst/.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
/Analyst.js
12
/index.js
23
/icons.js
34
/hooks.js
45
/components/
5-
/views/
66
/version.js

Diff for: packages/analyst/package.json

+3-11
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88
"files": [
99
"src",
1010
"dist",
11+
"Analyst.js",
1112
"index.js",
1213
"icons.js",
1314
"hooks.js",
1415
"version.js",
15-
"components",
16-
"views"
16+
"components"
1717
],
1818
"scripts": {
1919
"test": "cd ../../ && npm run jest packages/analyst",
@@ -42,14 +42,6 @@
4242
"dependencies": {
4343
"@wq/chart": "^2.0.0-alpha.0",
4444
"@wq/pandas": "^2.0.0-alpha.0",
45-
"mustache": "^4.2.0"
46-
},
47-
"peerDependencies": {
48-
"@wq/material": "*",
49-
"@wq/material-web": "*"
50-
},
51-
"devDependencies": {
52-
"@wq/material": "^2.1.0",
53-
"@wq/material-web": "^2.1.0"
45+
"@wq/react": "^3.0.0-a1-dev4.g2569553"
5446
}
5547
}

Diff for: packages/analyst/src/Analyst.jsx

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import React from "react";
2+
import { useComponents, withWQ, createFallbackComponent } from "@wq/react";
3+
import { useAnalyst } from "./hooks.js";
4+
import { AnalystIcon, Table, Series, Scatter, Boxplot } from "./icons.js";
5+
import PropTypes from "prop-types";
6+
7+
import {
8+
AnalystDownload,
9+
AnalystTable,
10+
AnalystForm,
11+
AnalystSeries,
12+
AnalystScatter,
13+
AnalystBoxplot,
14+
} from "./components/index.js";
15+
16+
const AnalystDefaults = {
17+
components: {
18+
AnalystDownload,
19+
AnalystForm,
20+
AnalystTable,
21+
AnalystSeries,
22+
AnalystScatter,
23+
AnalystBoxplot,
24+
},
25+
icons: {
26+
Analyst: AnalystIcon,
27+
Table,
28+
Series,
29+
Scatter,
30+
Boxplot,
31+
},
32+
};
33+
34+
const AnalystFallback = {
35+
components: {
36+
View: createFallbackComponent("View", "@wq/material"),
37+
Typography: createFallbackComponent("Typography", "@wq/material"),
38+
},
39+
};
40+
41+
function Analyst({ children, ...props }) {
42+
const { View, Typography, AnalystDownload, AnalystForm, AnalystTable } =
43+
useComponents(),
44+
{
45+
url,
46+
data,
47+
fields,
48+
error,
49+
title,
50+
formats,
51+
initial_rows,
52+
initial_order,
53+
id_column,
54+
id_url_prefix,
55+
form,
56+
options,
57+
setOptions,
58+
ActiveMode = AnalystTable,
59+
} = useAnalyst(props);
60+
61+
if (error) {
62+
return (
63+
<View sx={{ p: 2 }}>
64+
{title && <Typography variant="h5">{title}</Typography>}
65+
{children}
66+
<Typography>{error}</Typography>
67+
</View>
68+
);
69+
}
70+
71+
return (
72+
<View
73+
style={{
74+
flex: 1,
75+
display: "flex",
76+
flexDirection: "column",
77+
overflow: "hidden",
78+
}}
79+
>
80+
{formats && (
81+
<AnalystDownload url={url} title={title} formats={formats} />
82+
)}
83+
{!formats && title && <Typography variant="h5">{title}</Typography>}
84+
{children}
85+
{form && (
86+
<AnalystForm
87+
form={form}
88+
options={options}
89+
setOptions={setOptions}
90+
/>
91+
)}
92+
{ActiveMode && (
93+
<ActiveMode
94+
data={data}
95+
options={options}
96+
fields={fields}
97+
initial_rows={initial_rows}
98+
initial_order={initial_order}
99+
id_column={id_column}
100+
id_url_prefix={id_url_prefix}
101+
/>
102+
)}
103+
</View>
104+
);
105+
}
106+
107+
Analyst.propTypes = {
108+
children: PropTypes.node,
109+
};
110+
111+
export default withWQ(Analyst, {
112+
defaults: AnalystDefaults,
113+
fallback: AnalystFallback,
114+
});

Diff for: packages/analyst/src/components/AnalystBoxplot.jsx

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import React from "react";
2+
import { Boxplot } from "@wq/chart";
3+
import PropTypes from "prop-types";
4+
5+
export default function AnalystBoxplot({ data, options }) {
6+
return (
7+
<Boxplot
8+
datasets={data && data.datasets}
9+
x={options.date}
10+
y={options.value}
11+
group={options.group}
12+
/>
13+
);
14+
}
15+
16+
AnalystBoxplot.propTypes = {
17+
data: PropTypes.object,
18+
options: PropTypes.object,
19+
};
20+
21+
AnalystBoxplot.getAnalystMode = (data, columnTypes) => {
22+
if (columnTypes.numeric) {
23+
return {
24+
name: "boxplot",
25+
label: "Box",
26+
dateColumns: columnTypes.date,
27+
valueColumns: columnTypes.numeric,
28+
};
29+
}
30+
};

Diff for: packages/analyst/src/components/AnalystDownload.jsx

+21-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
11
import React, { useState } from "react";
22
import { Menu, MenuItem, useMediaQuery } from "@mui/material";
3-
import { useComponents } from "@wq/react";
3+
import { Download } from "../icons";
4+
import { useComponents, withWQ, createFallbackComponents } from "@wq/react";
45
import PropTypes from "prop-types";
56

6-
export default function AnalystDownload({ url, title, formats }) {
7+
const AnalystDownloadDefaults = {
8+
icons: {
9+
Download,
10+
},
11+
};
12+
13+
const AnalystDownloadFallback = {
14+
components: createFallbackComponents(
15+
["Button", "IconButton", "HorizontalView", "Typography", "View"],
16+
"@wq/material",
17+
),
18+
};
19+
20+
function AnalystDownload({ url, title, formats }) {
721
const [anchorEl, setAnchorEl] = useState(null),
822
{ Button, IconButton, HorizontalView, Typography, View } =
923
useComponents(),
@@ -58,3 +72,8 @@ AnalystDownload.propTypes = {
5872
title: PropTypes.string,
5973
formats: PropTypes.object,
6074
};
75+
76+
export default withWQ(AnalystDownload, {
77+
defaults: AnalystDownloadDefaults,
78+
fallback: AnalystDownloadFallback,
79+
});

Diff for: packages/analyst/src/components/AnalystForm.jsx

+57-18
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,72 @@
1-
import React from "react";
2-
import { Formik } from "formik";
3-
import { Grid } from "@mui/material";
4-
import { AutoInput } from "@wq/react";
5-
import { View } from "@wq/material";
1+
import React, { useCallback } from "react";
2+
import { useComponents, withWQ, createFallbackComponent } from "@wq/react";
63
import PropTypes from "prop-types";
74

8-
export default function AnalystForm({ form, options, setOptions }) {
5+
const AnalystFormFallback = {
6+
components: {
7+
Grid: createFallbackComponent("Grid", "@wq/material"),
8+
View: createFallbackComponent("View", "@wq/material"),
9+
AutoForm: createFallbackComponent("AutoForm", "@wq/form", "AutoForm"),
10+
AutoInput: createFallbackComponent("AutoInput", "@wq/form", "AutoForm"),
11+
},
12+
};
13+
14+
function AnalystForm({ form, options, setOptions, wq, children }) {
15+
const useValidate = useCallback(() => {
16+
function validate(newOptions) {
17+
setOptions(newOptions);
18+
}
19+
validate.onChange = true;
20+
return validate;
21+
}, [setOptions]),
22+
{ AutoForm, AutoInput } = useComponents();
23+
924
return (
10-
<Formik
11-
initialValues={options}
12-
enableReinitialize={true}
13-
validate={setOptions}
25+
<AutoForm
26+
form={form}
27+
data={options}
28+
hideSubmit
29+
wq={{
30+
...wq,
31+
components: {
32+
...(wq || {}).components,
33+
AutoInput: GridInput,
34+
FormRoot: GridFormRoot,
35+
BaseAutoInput: AutoInput,
36+
useValidate,
37+
},
38+
}}
1439
>
15-
<View sx={{ p: 2 }}>
16-
<Grid container spacing={1} sx={{}}>
17-
{form.map((field) => (
18-
<GridInput key={field.name} {...field} />
19-
))}
20-
</Grid>
21-
</View>
22-
</Formik>
40+
{children}
41+
</AutoForm>
2342
);
2443
}
2544

2645
AnalystForm.propTypes = {
2746
form: PropTypes.arrayOf(PropTypes.object),
2847
options: PropTypes.object,
2948
setOptions: PropTypes.func,
49+
wq: PropTypes.object,
50+
children: PropTypes.node,
51+
};
52+
53+
function GridFormRoot({ children }) {
54+
const { View, Grid } = useComponents();
55+
return (
56+
<View sx={{ p: 2 }}>
57+
<Grid container spacing={1}>
58+
{children}
59+
</Grid>
60+
</View>
61+
);
62+
}
63+
64+
GridFormRoot.propTypes = {
65+
children: PropTypes.node,
3066
};
3167

3268
function GridInput(props) {
69+
const { BaseAutoInput: AutoInput, Grid } = useComponents();
3370
if (props.type === "hidden") {
3471
return <AutoInput {...props} />;
3572
} else if (props.fullwidth) {
@@ -51,3 +88,5 @@ GridInput.propTypes = {
5188
type: PropTypes.string,
5289
fullwidth: PropTypes.bool,
5390
};
91+
92+
export default withWQ(AnalystForm, { fallback: AnalystFormFallback });

Diff for: packages/analyst/src/components/AnalystScatter.jsx

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import React from "react";
2+
import { Scatter } from "@wq/chart";
3+
import PropTypes from "prop-types";
4+
5+
export default function AnalystScatter({ data, options }) {
6+
return (
7+
<Scatter
8+
datasets={data && data.datasets}
9+
x={options.value}
10+
y={options.value2}
11+
label={options.date}
12+
/>
13+
);
14+
}
15+
16+
AnalystScatter.propTypes = {
17+
data: PropTypes.object,
18+
options: PropTypes.object,
19+
};
20+
21+
AnalystScatter.getAnalystMode = (data, columnTypes) => {
22+
if (
23+
columnTypes.date &&
24+
columnTypes.numeric &&
25+
columnTypes.numeric.length > 1
26+
) {
27+
return {
28+
name: "scatter",
29+
label: "Scatter",
30+
dateColumns: columnTypes.date,
31+
valueColumns: columnTypes.numeric,
32+
};
33+
}
34+
};

Diff for: packages/analyst/src/components/AnalystSeries.jsx

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import React from "react";
2+
import { Series } from "@wq/chart";
3+
import PropTypes from "prop-types";
4+
5+
export default function AnalystSeries({ data, options }) {
6+
return (
7+
<Series
8+
datasets={data && data.datasets}
9+
x={options.date}
10+
y={options.value}
11+
/>
12+
);
13+
}
14+
15+
AnalystSeries.propTypes = {
16+
data: PropTypes.object,
17+
options: PropTypes.object,
18+
};
19+
20+
AnalystSeries.getAnalystMode = (data, columnTypes) => {
21+
if (columnTypes.date && columnTypes.numeric) {
22+
return {
23+
name: "series",
24+
label: "Series",
25+
dateColumns: columnTypes.date,
26+
valueColumns: columnTypes.numeric,
27+
};
28+
}
29+
};

0 commit comments

Comments
 (0)