Skip to content

Commit 62efa39

Browse files
authored
Merge pull request #16 from bruceyyu/main
updates for v0.1.4
2 parents 1dd0880 + 41046be commit 62efa39

File tree

12 files changed

+3257
-941
lines changed

12 files changed

+3257
-941
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: GWalkR
22
Title: Interactive Exploratory Data Analysis Tool
3-
Version: 0.1.3
3+
Version: 0.1.4
44
Authors@R: c(
55
person("Yue", "Yu", , "[email protected]", role = c("aut", "cre"),
66
comment = c(ORCID = "0000-0002-9302-0793")),

GWalkR.Rproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,13 @@ SaveWorkspace: No
55
AlwaysSaveHistory: Default
66

77
EnableCodeIndexing: Yes
8+
UseSpacesForTab: Yes
9+
NumSpacesForTab: 2
810
Encoding: UTF-8
911

12+
RnwWeave: Sweave
13+
LaTeX: pdfLaTeX
14+
1015
AutoAppendNewline: Yes
1116
StripTrailingWhitespace: Yes
1217
LineEndingConversion: Posix

README.md

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,39 +25,30 @@ It can simplify your R data analysis and data visualization workflow, by turning
2525

2626
### Setup GWalkR
2727

28-
#### Through CRAN (Recommended)
29-
3028
```R
3129
install.packages("GWalkR")
30+
library(GWalkR)
3231
```
3332

34-
#### Through Running R Script
35-
36-
If you have `devtools` installed in R, you can run the following R code to install.
37-
38-
```R
39-
devtools::install_url("https://kanaries-app.s3.ap-northeast-1.amazonaws.com/oss/gwalkr/GWalkR_latest.tar.gz")
40-
```
41-
42-
#### Through Package Archive File (.tar.gz)
43-
44-
Alternatively, download the package archive file `GWalkR_latest.tar.gz` from [this link](https://kanaries-app.s3.ap-northeast-1.amazonaws.com/oss/gwalkr/GWalkR_latest.tar.gz).
45-
Open R Studio, click "Install" in the "Packages" window, and select "Package Archive File (.tgz; .tar.gz)" in the "Install from". Then, select the archive in your file system and click "Install".
46-
4733
### Start Your Data Exploration in a Single Line of Code
4834

4935
```R
50-
library(GWalkR)
5136
data(iris)
5237
gwalkr(iris)
5338
```
5439

55-
<img width="1437" alt="image" src="https://github.com/Bruceshark/GWalkR/assets/33870780/718d8ff6-4ad5-492d-9afb-c4ed67573f51">
56-
5740
## Main Features
58-
1. 🧑‍🎨 Turn a data frame into charts through simple drag-and-drop operations.
59-
2. ✨ Empower your RMarkdown: Showcase your data insights with editable and explorable charts on a webpage ([example](https://bruceyyu.github.io/show/tidytuesday_etymology.nb.html))!
60-
3. 🤖️ [coming soon] Work with AI copilot in R: Let AI generate explorable charts for you!
41+
### Get an overview of your data frame under 'Data' tab.
42+
<img width="700" alt="image" src="https://github.com/bruceyyu/GWalkR/assets/33870780/67131cfa-a25b-44ae-90a0-95902ea5edb1">
43+
44+
### Creat data viz with simple drag-and-drop operations.
45+
<img width="700" alt="image" src="https://github.com/Bruceshark/GWalkR/assets/33870780/718d8ff6-4ad5-492d-9afb-c4ed67573f51">
46+
47+
### Find interesting data points? Brush them and zoom in!
48+
<img width="700" alt="image" src="https://github.com/bruceyyu/GWalkR/assets/33870780/8033885d-3699-4f50-84e1-2201b3846b5a">
49+
50+
### Empower your R notebook (R Markdown).
6151

52+
Showcase your data insights with editable and explorable charts on a webpage ([example](https://bruceyyu.github.io/show/tidytuesday_etymology.nb.html))!
6253

63-
https://github.com/Kanaries/GWalkR/assets/33870780/4a3a9f9c-ff17-484b-9503-af82bd609b99
54+
<img width="700" alt="image" src="https://github.com/bruceyyu/GWalkR/assets/33870780/4798367c-0dd4-4ad3-b25b-7ea48b79205a">

web_app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"preview": "vite preview"
1111
},
1212
"dependencies": {
13-
"@kanaries/graphic-walker": "^0.4.13",
13+
"@kanaries/graphic-walker": "^0.4.61",
1414
"@rollup/plugin-commonjs": "^25.0.2",
1515
"@rollup/plugin-replace": "^5.0.2",
1616
"@rollup/plugin-terser": "^0.4.3",

web_app/src/components/codeExportModal/index.tsx

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import { observer } from "mobx-react-lite";
44
import DefaultButton from "../button/default";
55
import PrimaryButton from "../button/primary";
66

7-
import type { IGlobalStore } from "@kanaries/graphic-walker/dist/store";
7+
import type { VizSpecStore } from '@kanaries/graphic-walker/store/visualSpecStore'
88

99
interface ICodeExport {
10-
globalStore: React.MutableRefObject<IGlobalStore | null>;
10+
globalStore: React.MutableRefObject<VizSpecStore | null>;
1111
open: boolean;
1212
setOpen: (open: boolean) => void;
1313
}
@@ -27,20 +27,21 @@ const downloadFile = (data: string) => {
2727
};
2828

2929
const CodeExport: React.FC<ICodeExport> = observer((props) => {
30+
const { globalStore, open, setOpen } = props;
3031
const [code, setCode] = useState<string>("");
3132

3233
useEffect(() => {
33-
if (props.open) {
34-
const res = props.globalStore.current?.vizStore.exportViewSpec();
34+
if (open && globalStore.current) {
35+
const res = globalStore.current.exportCode();
3536
if (res) setCode(JSON.stringify(res));
3637
}
37-
}, [props.open]);
38+
}, [open]);
3839

3940
return (
4041
<Modal
41-
show={props.open}
42+
show={open}
4243
onClose={() => {
43-
props.setOpen(false);
44+
setOpen(false);
4445
}}
4546
>
4647
<div className="dark:text-white">
@@ -66,7 +67,7 @@ const CodeExport: React.FC<ICodeExport> = observer((props) => {
6667
</div>
6768
<div className="text-sm max-h-56 mt-4 text-left">
6869
<div>Option 1: paste the config in your R code as a string and pass it to `visConfig` parameter.</div>
69-
<div>Option 2: download the config file and pass the file path to `visConfigFile` parameter.</div>
70+
<div>Option 2 (recommended): download the config file and pass the file path to `visConfigFile` parameter.</div>
7071
</div>
7172
</div>
7273
</Modal>

web_app/src/index.tsx

Lines changed: 8 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,21 @@
1-
import React, { useMemo, useState } from "react";
1+
import React, { useState } from "react";
22
import { createRoot } from "react-dom/client";
33
import { observer } from "mobx-react-lite";
44
import { IAppProps } from "./interfaces";
55
import { GraphicWalker } from "@kanaries/graphic-walker";
6-
import type { IGlobalStore } from "@kanaries/graphic-walker/dist/store";
7-
import type { IDataSetInfo, IMutField, IRow, IVisSpec } from "@kanaries/graphic-walker/dist/interfaces";
8-
import type { IStoInfo } from "@kanaries/graphic-walker/dist/utils/save";
6+
import type { VizSpecStore } from '@kanaries/graphic-walker/store/visualSpecStore';
97
import { getExportTool } from "./tools/exportTool";
108
import CodeExportModal from "./components/codeExportModal";
119
import { StyleSheetManager } from "styled-components";
1210
import tailwindStyle from "tailwindcss/tailwind.css?inline";
11+
import formatSpec from "./utils/formatSpec";
1312

14-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
1513
const App: React.FC<IAppProps> = observer((propsIn) => {
16-
const { dataSource, ...props } = propsIn;
17-
const storeRef = React.useRef<IGlobalStore>(null);
18-
const specList: IVisSpec[] = useMemo(() => {
19-
return props.visSpec ? (JSON.parse(props.visSpec) as IVisSpec[]) : [];
20-
}, []);
21-
const [exportOpen, setExportOpen] = useState(false);
22-
23-
const setData = (data?: IRow[], rawFields?: IMutField[]) => {
24-
if (specList.length !== 0) {
25-
setTimeout(() => {
26-
storeRef?.current?.vizStore?.importStoInfo({
27-
dataSources: [
28-
{
29-
id: "dataSource-0",
30-
data: data,
31-
},
32-
],
33-
datasets: [
34-
{
35-
id: "dataset-0",
36-
name: "DataSet",
37-
rawFields: rawFields,
38-
dsId: "dataSource-0",
39-
},
40-
],
41-
specList,
42-
} as IStoInfo);
43-
}, 1);
44-
} else {
45-
storeRef?.current?.commonStore?.updateTempSTDDS({
46-
name: "Dataset",
47-
rawFields: rawFields,
48-
dataSource: data,
49-
} as IDataSetInfo);
50-
storeRef?.current?.commonStore?.commitTempDS();
51-
}
52-
};
14+
const { dataSource, visSpec, rawFields, ...props } = propsIn;
15+
const storeRef = React.useRef<VizSpecStore|null>(null);
5316

54-
React.useEffect(() => {
55-
setData(dataSource, props.rawFields);
56-
}, []);
17+
const specList = visSpec ? formatSpec(JSON.parse(visSpec) as any[], rawFields) : undefined
18+
const [exportOpen, setExportOpen] = useState(false);
5719

5820
const exportTool = getExportTool(setExportOpen);
5921

@@ -66,9 +28,8 @@ const App: React.FC<IAppProps> = observer((propsIn) => {
6628
return (
6729
<React.StrictMode>
6830
<div className="h-full w-full overflow-y-scroll font-sans">
69-
{/* <div style={{ height: "100%", width: "100%", overflowY: "scroll" }}> */}
7031
<CodeExportModal open={exportOpen} setOpen={setExportOpen} globalStore={storeRef} />
71-
<GraphicWalker {...props} storeRef={storeRef} toolbar={toolbarConfig} />
32+
<GraphicWalker {...props} storeRef={storeRef} data={dataSource} toolbar={toolbarConfig} fields={rawFields} chart={specList} />
7233
</div>
7334
</React.StrictMode>
7435
);

web_app/src/interfaces/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
import type { IGWProps } from "@kanaries/graphic-walker/dist/App";
1+
import type { IRow, IMutField } from '@kanaries/graphic-walker/interfaces'
22

3-
export interface IAppProps extends IGWProps {
3+
export interface IAppProps {
44
id: string;
55
version?: string;
66
hashcode?: string;
77
visSpec?: string;
88
env?: string;
99
needLoadDatas?: boolean;
1010
specType?: string;
11+
dataSource: IRow[];
12+
rawFields: IMutField[];
1113
}

web_app/src/tools/exportTool.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from "react";
22

33
import { CodeBracketSquareIcon } from "@heroicons/react/24/outline";
44

5-
import type { ToolbarButtonItem } from "@kanaries/graphic-walker/dist/components/toolbar/toolbar-button";
5+
import type { ToolbarButtonItem } from "@kanaries/graphic-walker/components/toolbar/toolbar-button";
66

77
export function getExportTool(setExportOpen: React.Dispatch<React.SetStateAction<boolean>>): ToolbarButtonItem {
88
return {

web_app/src/utils/formatSpec.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/* eslint-disable @typescript-eslint/no-unsafe-argument */
2+
/* eslint-disable no-prototype-builtins */
3+
/* eslint-disable @typescript-eslint/no-unsafe-call */
4+
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
5+
/* eslint-disable @typescript-eslint/no-unsafe-return */
6+
import { VegaliteMapper } from "@kanaries/graphic-walker/lib/vl2gw";
7+
8+
export default function formatSpec(spec: any[], fields: any[]) {
9+
return spec.map((item, index) => {
10+
if (["config", "encodings", "visId"].every((key) => item.hasOwnProperty(key))) {
11+
return item;
12+
} else {
13+
const result = VegaliteMapper(item, fields, Math.random().toString(16).split(".").at(1)!, `Chart ${index + 1}`);
14+
return result;
15+
}
16+
});
17+
}

web_app/tsconfig.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
"target": "ES2020",
44
"useDefineForClassFields": true,
55
"lib": ["ES2020", "DOM", "DOM.Iterable"],
6+
"allowJs": true,
67
"module": "ESNext",
78
"skipLibCheck": true,
89

910
/* Bundler mode */
10-
"moduleResolution": "Node",
11+
"moduleResolution": "Bundler",
1112
"allowImportingTsExtensions": true,
1213
"allowSyntheticDefaultImports": true,
1314
"resolveJsonModule": true,
@@ -19,7 +20,12 @@
1920
"strict": true,
2021
"noUnusedLocals": true,
2122
"noUnusedParameters": true,
22-
"noFallthroughCasesInSwitch": true
23+
"noFallthroughCasesInSwitch": true,
24+
25+
"baseUrl": ".",
26+
"paths": {
27+
"@/*": ["./src/*"]
28+
}
2329
},
2430
"include": ["src"],
2531
"references": [{ "path": "./tsconfig.node.json" }]

0 commit comments

Comments
 (0)