Skip to content

Commit 4e06d3b

Browse files
authored
updates for v0.1.3
2 parents 9693870 + 56ff805 commit 4e06d3b

File tree

8 files changed

+121
-28
lines changed

8 files changed

+121
-28
lines changed

DESCRIPTION

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
Package: GWalkR
22
Title: Interactive Exploratory Data Analysis Tool
3-
Version: 0.1.2
3+
Version: 0.1.3
44
Authors@R: c(
5-
person("Yue", "Yu", , "yyubv@connect.ust.hk", role = c("aut", "cre"),
5+
person("Yue", "Yu", , "yue.yu@connect.ust.hk", role = c("aut", "cre"),
66
comment = c(ORCID = "0000-0002-9302-0793")),
77
person("Kanaries Data Inc.", role = c("cph", "fnd")))
8-
Maintainer: Yue Yu <yyubv@connect.ust.hk>
8+
Maintainer: Yue Yu <yue.yu@connect.ust.hk>
99
Description: Simplify your R data analysis and data visualization workflow by turning your data frame into an interactive 'Tableau'-like interface, leveraging the 'graphic-walker' JavaScript library and the 'htmlwidgets' package.
1010
License: Apache License (>= 2)
1111
Encoding: UTF-8

R/gwalkr.R

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#'
88
#' @param data A data frame to be visualized in the GWalkR. The data frame should not be empty.
99
#' @param lang A character string specifying the language for the widget. Possible values are "en" (default), "ja", "zh".
10+
#' @param dark A character string specifying the dark mode preference. Possible values are "light" (default), "dark", "media".
1011
#' @param columnSpecs An optional list of lists to manually specify the types of some columns in the data frame.
1112
#' Each top level element in the list corresponds to a column, and the list assigned to each column should have
1213
#' two elements: `analyticalType` and `semanticType`. `analyticalType` can
@@ -17,6 +18,7 @@
1718
#' "age" = list(analyticalType = "measure", semanticType = "quantitative")
1819
#' )}
1920
#' @param visConfig An optional config string to reproduce your chart. You can copy the string by clicking "export config" button on the GWalkR interface.
21+
#' @param visConfigFile An optional config file path to reproduce your chart. You can download the file by clicking "export config" button then "download" button on the GWalkR interface.
2022
#'
2123
#' @return An \code{htmlwidget} object that can be rendered in R environments
2224
#'
@@ -25,19 +27,25 @@
2527
#' gwalkr(mtcars)
2628
#'
2729
#' @export
28-
gwalkr <- function(data, lang = "en", columnSpecs = list(), visConfig = NULL) {
30+
gwalkr <- function(data, lang = "en", dark = "light", columnSpecs = list(), visConfig = NULL, visConfigFile = NULL) {
2931
if (!is.data.frame(data)) stop("data must be a data frame")
32+
if (!is.null(visConfig) && !is.null(visConfigFile)) stop("visConfig and visConfigFile are mutually exclusive")
3033
lang <- match.arg(lang, choices = c("en", "ja", "zh"))
3134

3235
rawFields <- raw_fields(data, columnSpecs)
3336
colnames(data) <- sapply(colnames(data), fname_encode)
37+
38+
if (!is.null(visConfigFile)) {
39+
visConfig <- readLines(visConfigFile, warn=FALSE)
40+
}
3441
# forward options using x
3542
x = list(
3643
dataSource = jsonlite::toJSON(data),
3744
rawFields = rawFields,
3845
i18nLang = lang,
3946
hideDataSourceConfig = TRUE,
40-
visSpec = visConfig
47+
visSpec = visConfig,
48+
dark = dark
4149
)
4250

4351
# create widget

man/gwalkr.Rd

Lines changed: 12 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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.3",
13+
"@kanaries/graphic-walker": "^0.4.13",
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: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, { useEffect, useState } from "react";
22
import Modal from "../modal";
33
import { observer } from "mobx-react-lite";
44
import DefaultButton from "../button/default";
5+
import PrimaryButton from "../button/primary";
56

67
import type { IGlobalStore } from "@kanaries/graphic-walker/dist/store";
78

@@ -11,6 +12,20 @@ interface ICodeExport {
1112
setOpen: (open: boolean) => void;
1213
}
1314

15+
const downloadFile = (data: string) => {
16+
const fileName = "config";
17+
const json = data;
18+
const blob = new Blob([json], { type: "application/json" });
19+
const href = URL.createObjectURL(blob);
20+
const link = document.createElement("a");
21+
link.href = href;
22+
link.download = fileName + ".json";
23+
document.body.appendChild(link);
24+
link.click();
25+
document.body.removeChild(link);
26+
URL.revokeObjectURL(href);
27+
};
28+
1429
const CodeExport: React.FC<ICodeExport> = observer((props) => {
1530
const [code, setCode] = useState<string>("");
1631

@@ -31,11 +46,7 @@ const CodeExport: React.FC<ICodeExport> = observer((props) => {
3146
<div className="dark:text-white">
3247
<h1 className="mb-4 font-bold text-base">Config Export</h1>
3348
<div className="text-sm max-h-64 overflow-auto w-full">
34-
<code className="font-mono text-xs whitespace-nowrap w-full">
35-
visConfig &lt;- '{code}'
36-
<br />
37-
gwalkr(data="name of your data frame", visConfig=visConfig)
38-
</code>
49+
<code className="font-mono text-xs whitespace-nowrap w-full">{code}</code>
3950
</div>
4051
<div className="mt-4 flex justify-start">
4152
<DefaultButton
@@ -45,8 +56,18 @@ const CodeExport: React.FC<ICodeExport> = observer((props) => {
4556
props.setOpen(false);
4657
}}
4758
/>
59+
<PrimaryButton
60+
text="Download"
61+
className="mr-2 px-6"
62+
onClick={() => {
63+
downloadFile(code);
64+
}}
65+
/>{" "}
66+
</div>
67+
<div className="text-sm max-h-56 mt-4 text-left">
68+
<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>
4870
</div>
49-
<div className="text-sm max-h-56 mt-4 text-right">Please copy the R code above and paste it into your script.</div>
5071
</div>
5172
</Modal>
5273
);

web_app/src/index.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import type { IDataSetInfo, IMutField, IRow, IVisSpec } from "@kanaries/graphic-
88
import type { IStoInfo } from "@kanaries/graphic-walker/dist/utils/save";
99
import { getExportTool } from "./tools/exportTool";
1010
import CodeExportModal from "./components/codeExportModal";
11-
import { StyleSheetManager } from 'styled-components';
12-
import tailwindStyle from 'tailwindcss/tailwind.css?inline'
11+
import { StyleSheetManager } from "styled-components";
12+
import tailwindStyle from "tailwindcss/tailwind.css?inline";
1313

1414
// eslint-disable-next-line @typescript-eslint/no-unused-vars
1515
const App: React.FC<IAppProps> = observer((propsIn) => {
@@ -39,7 +39,7 @@ const App: React.FC<IAppProps> = observer((propsIn) => {
3939
},
4040
],
4141
specList,
42-
} as IStoInfo)
42+
} as IStoInfo);
4343
}, 1);
4444
} else {
4545
storeRef?.current?.commonStore?.updateTempSTDDS({
@@ -49,10 +49,10 @@ const App: React.FC<IAppProps> = observer((propsIn) => {
4949
} as IDataSetInfo);
5050
storeRef?.current?.commonStore?.commitTempDS();
5151
}
52-
}
52+
};
5353

5454
React.useEffect(() => {
55-
setData(dataSource, props.rawFields)
55+
setData(dataSource, props.rawFields);
5656
}, []);
5757

5858
const exportTool = getExportTool(setExportOpen);
@@ -66,7 +66,7 @@ const App: React.FC<IAppProps> = observer((propsIn) => {
6666
return (
6767
<React.StrictMode>
6868
<div className="h-full w-full overflow-y-scroll font-sans">
69-
{/* <div style={{ height: "100%", width: "100%", overflowY: "scroll" }}> */}
69+
{/* <div style={{ height: "100%", width: "100%", overflowY: "scroll" }}> */}
7070
<CodeExportModal open={exportOpen} setOpen={setExportOpen} globalStore={storeRef} />
7171
<GraphicWalker {...props} storeRef={storeRef} toolbar={toolbarConfig} />
7272
</div>
@@ -77,10 +77,10 @@ const App: React.FC<IAppProps> = observer((propsIn) => {
7777
const GWalker = (props: IAppProps, id: string) => {
7878
const container = document.getElementById(id);
7979
if (container) {
80-
const shadowRoot = container.attachShadow({ mode: 'open' });
80+
const shadowRoot = container.attachShadow({ mode: "open" });
8181

8282
// Add Tailwind CSS to the shadow root
83-
const styleElement = document.createElement('style');
83+
const styleElement = document.createElement("style");
8484
styleElement.textContent = tailwindStyle;
8585
shadowRoot.appendChild(styleElement);
8686

web_app/src/interfaces/index.ts

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

33
export interface IAppProps extends IGWProps {
44
id: string;
@@ -8,4 +8,4 @@ export interface IAppProps extends IGWProps {
88
env?: string;
99
needLoadDatas?: boolean;
1010
specType?: string;
11-
}
11+
}

web_app/yarn.lock

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,13 @@
200200
dependencies:
201201
"@babel/helper-plugin-utils" "^7.22.5"
202202

203+
"@babel/runtime@^7.12.5":
204+
version "7.22.15"
205+
resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.22.15.tgz#38f46494ccf6cf020bd4eed7124b425e83e523b8"
206+
integrity sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==
207+
dependencies:
208+
regenerator-runtime "^0.14.0"
209+
203210
"@babel/runtime@^7.14.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.17.2", "@babel/runtime@^7.19.0", "@babel/runtime@^7.9.2":
204211
version "7.22.6"
205212
resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.22.6.tgz#57d64b9ae3cff1d67eb067ae117dac087f5bd438"
@@ -481,17 +488,18 @@
481488
"@jridgewell/resolve-uri" "3.1.0"
482489
"@jridgewell/sourcemap-codec" "1.4.14"
483490

484-
"@kanaries/graphic-walker@^0.4.3":
485-
version "0.4.3"
486-
resolved "https://registry.npmmirror.com/@kanaries/graphic-walker/-/graphic-walker-0.4.3.tgz#e30e8a5ef85781433acadeada828726acf68fb27"
487-
integrity sha512-r+c2bipTqlzPGckrYYNDbYmYi8DxBRJrjA4J1uNsckeb0d047ZT9cmQwqawtJPdxDpuxWnkFK7+oFYX6LcSRew==
491+
"@kanaries/graphic-walker@^0.4.13":
492+
version "0.4.13"
493+
resolved "https://registry.npmmirror.com/@kanaries/graphic-walker/-/graphic-walker-0.4.13.tgz#a03d400f4774974454e1525a2e3a3d879e31eac6"
494+
integrity sha512-8Mn8rQjAuGgnEDN60VgxAlV1aVMqjJ/UdbRdtQkaxwPKdSOQ+DTMoFu/uccFQUaotT77eWJMLIvc06l+R+mpRw==
488495
dependencies:
489496
"@headlessui/react" "^1.7.12"
490497
"@heroicons/react" "^2.0.8"
491498
"@kanaries/react-beautiful-dnd" "^0.0.3"
492499
"@kanaries/web-data-loader" "^0.1.7"
493500
"@tailwindcss/forms" "^0.5.4"
494501
autoprefixer "^10.3.5"
502+
canvas-size "^1.2.6"
495503
d3-format "^3.1.0"
496504
d3-scale "^4.0.2"
497505
d3-time-format "^4.1.0"
@@ -505,6 +513,8 @@
505513
postcss "^8.3.7"
506514
postinstall-postinstall "^2.1.0"
507515
re-resizable "^6.9.8"
516+
react-dropzone "^14.2.3"
517+
react-error-boundary "^4.0.11"
508518
react-i18next "^11.18.6"
509519
react-leaflet "^4.2.1"
510520
react-shadow "^20.0.0"
@@ -872,6 +882,11 @@ array-union@^2.1.0:
872882
resolved "https://registry.npmmirror.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
873883
integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
874884

885+
attr-accept@^2.2.2:
886+
version "2.2.2"
887+
resolved "https://registry.npmmirror.com/attr-accept/-/attr-accept-2.2.2.tgz#646613809660110749e92f2c10833b70968d929b"
888+
integrity sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==
889+
875890
autoprefixer@^10.3.5, autoprefixer@^10.4.14:
876891
version "10.4.14"
877892
resolved "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.14.tgz#e28d49902f8e759dd25b153264e862df2705f79d"
@@ -962,6 +977,11 @@ caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.30001503:
962977
resolved "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001514.tgz#e2a7e184a23affc9367b7c8d734e7ec4628c1309"
963978
integrity sha512-ENcIpYBmwAAOm/V2cXgM7rZUrKKaqisZl4ZAI520FIkqGXUxJjmaIssbRW5HVVR5tyV6ygTLIm15aU8LUmQSaQ==
964979

980+
canvas-size@^1.2.6:
981+
version "1.2.6"
982+
resolved "https://registry.npmmirror.com/canvas-size/-/canvas-size-1.2.6.tgz#1eaa6b56167cf2a70fa4021680829d2073b45706"
983+
integrity sha512-x2iVHOrZ5x9V0Hwx6kBz+Yxf/VCAII+jrD6WLjJbytJLozHq/oDJjEva432Os0eHxWMFR0vYlLJwTr6QxyxQqw==
984+
965985
chalk@^2.0.0:
966986
version "2.4.2"
967987
resolved "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
@@ -1496,6 +1516,13 @@ file-entry-cache@^6.0.1:
14961516
dependencies:
14971517
flat-cache "^3.0.4"
14981518

1519+
file-selector@^0.6.0:
1520+
version "0.6.0"
1521+
resolved "https://registry.npmmirror.com/file-selector/-/file-selector-0.6.0.tgz#fa0a8d9007b829504db4d07dd4de0310b65287dc"
1522+
integrity sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==
1523+
dependencies:
1524+
tslib "^2.4.0"
1525+
14991526
fill-range@^7.0.1:
15001527
version "7.0.1"
15011528
resolved "https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
@@ -2168,7 +2195,7 @@ prelude-ls@^1.2.1:
21682195
resolved "https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
21692196
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
21702197

2171-
prop-types@^15.7.2:
2198+
prop-types@^15.7.2, prop-types@^15.8.1:
21722199
version "15.8.1"
21732200
resolved "https://registry.npmmirror.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
21742201
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@@ -2212,6 +2239,22 @@ react-dom@^18.2.0:
22122239
loose-envify "^1.1.0"
22132240
scheduler "^0.23.0"
22142241

2242+
react-dropzone@^14.2.3:
2243+
version "14.2.3"
2244+
resolved "https://registry.npmmirror.com/react-dropzone/-/react-dropzone-14.2.3.tgz#0acab68308fda2d54d1273a1e626264e13d4e84b"
2245+
integrity sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==
2246+
dependencies:
2247+
attr-accept "^2.2.2"
2248+
file-selector "^0.6.0"
2249+
prop-types "^15.8.1"
2250+
2251+
react-error-boundary@^4.0.11:
2252+
version "4.0.11"
2253+
resolved "https://registry.npmmirror.com/react-error-boundary/-/react-error-boundary-4.0.11.tgz#36bf44de7746714725a814630282fee83a7c9a1c"
2254+
integrity sha512-U13ul67aP5DOSPNSCWQ/eO0AQEYzEFkVljULQIjMV0KlffTAhxuDoBKdO0pb/JZ8mDhMKFZ9NZi0BmLGUiNphw==
2255+
dependencies:
2256+
"@babel/runtime" "^7.12.5"
2257+
22152258
react-i18next@^11.18.6:
22162259
version "11.18.6"
22172260
resolved "https://registry.npmmirror.com/react-i18next/-/react-i18next-11.18.6.tgz#e159c2960c718c1314f1e8fcaa282d1c8b167887"
@@ -2294,6 +2337,11 @@ regenerator-runtime@^0.13.11:
22942337
resolved "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
22952338
integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
22962339

2340+
regenerator-runtime@^0.14.0:
2341+
version "0.14.0"
2342+
resolved "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45"
2343+
integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==
2344+
22972345
require-directory@^2.1.1:
22982346
version "2.1.1"
22992347
resolved "https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
@@ -2638,6 +2686,11 @@ tslib@^2.1.0, tslib@^2.5.0:
26382686
resolved "https://registry.npmmirror.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3"
26392687
integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==
26402688

2689+
tslib@^2.4.0:
2690+
version "2.6.2"
2691+
resolved "https://registry.npmmirror.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
2692+
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
2693+
26412694
tslib@~2.5.0:
26422695
version "2.5.3"
26432696
resolved "https://registry.npmmirror.com/tslib/-/tslib-2.5.3.tgz#24944ba2d990940e6e982c4bea147aba80209913"

0 commit comments

Comments
 (0)