Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

updates for v0.1.1 #5

Merged
merged 6 commits into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
Package: GWalkR
Title: Interactive Exploratory Data Analysis Tool
Version: 0.1.0
Version: 0.1.1
Authors@R: c(
person("Yue", "Yu", , "[email protected]", role = c("aut", "cre"),
comment = c(ORCID = "0000-0002-9302-0793")),
person("Kanaries Data Inc.", role = c("cph", "fnd")))
Maintainer: Yue Yu <[email protected]>
Description: Simplify your R data analysis and data visualization workflow, by turning your data frame into a 'Tableau' style User Interface for visual exploration.
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.
License: Apache License (>= 2)
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.2.3
URL: https://github.com/Kanaries/GWalkR/
BugReports: https://github.com/Kanaries/GWalkR/issues
Imports:
htmlwidgets,
jsonlite,
openssl,
shiny
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ export(gwalkr)
export(gwalkrOutput)
export(renderGwalkr)
import(htmlwidgets)
import(openssl)
import(shiny)
62 changes: 56 additions & 6 deletions R/data_parser.R
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
raw_fields <- function(df) {
library(openssl)

raw_fields <- function(df, columnSpecs = list()) {
validate_columnSpecs(columnSpecs)
cols <- colnames(df)
props <- lapply(seq_along(cols), function(i) {
infer_prop(cols[i], i, df)
infer_prop(cols[i], i, df, columnSpecs)
})
return(props)
}

infer_prop <- function(col, i = NULL, df) {
infer_prop <- function(col, i = NULL, df, columnSpecs = list()) {
s <- df[[col]]
semantic_type <- infer_semantic(s)
analytic_type <- infer_analytic(s)
semantic_type <- ifelse((col %in% names(columnSpecs)), columnSpecs[[col]]$semanticType, infer_semantic(s))
analytic_type <- ifelse((col %in% names(columnSpecs)), columnSpecs[[col]]$analyticalType, infer_analytic(s))
prop <- list(
fid = col,
fid = fname_encode(col),
name = col,
semanticType = semantic_type,
analyticType = analytic_type
Expand Down Expand Up @@ -41,4 +44,51 @@ infer_analytic <- function(s) {
} else {
return('dimension')
}
}

validate_columnSpecs <- function(columnSpecs) {
acceptable_analyticalTypes <- c("measure", "dimension")
acceptable_semanticTypes <- c("quantitative", "temporal", "nominal", "ordinal")

# Check that columnSpecs is a list
if (!is.list(columnSpecs)) {
stop("columnSpecs should be a list.")
}

for (column in names(columnSpecs)) {
# Check that the column specification is a list
if (!is.list(columnSpecs[[column]])) {
stop(paste0("The specification for '", column, "' should be a list."))
}

# Check that the analyticalType and semanticType are specified
if (!"analyticalType" %in% names(columnSpecs[[column]]) ||
!"semanticType" %in% names(columnSpecs[[column]])) {
stop(paste0("Both 'analyticalType' and 'semanticType' should be specified for '", column, "'."))
}

# Check that the analyticalType and semanticType have acceptable values
if (!(columnSpecs[[column]]$analyticalType %in% acceptable_analyticalTypes)) {
stop(paste0("The 'analyticalType' for '", column, "' is invalid. It should be either 'measure' or 'dimension'."))
}

if (!(columnSpecs[[column]]$semanticType %in% acceptable_semanticTypes)) {
stop(paste0("The 'semanticType' for '", column, "' is invalid. It should be one of 'quantitative', 'temporal', 'nominal', or 'ordinal'."))
}
}
}

fname_encode <- function(fname) {
# Convert fname to base64
return(base64_encode(charToRaw(as.character(fname))))
}

fname_decode <- function(fname) {
# Convert base64 back to string
decoded <- rawToChar(base64_decode(fname))
if (grepl("_", decoded)) {
return(unlist(strsplit(decoded, "_"))[1])
} else {
return(decoded)
}
}
50 changes: 43 additions & 7 deletions R/gwalkr.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,41 @@
#' Use this function to create a GWalkR interface from a given data frame in your "Viewer" window, and start your data exploration! Please make sure the width and the height of your "Viewer" window are large enough.
#'
#' @import htmlwidgets
#' @import openssl
#'
#' @param data A data frame to be visualized in the GWalkR. The data frame should not be empty.
#' @param lang A character string specifying the language for the widget. Possible values are "en" (default), "ja", "zh".
#' @param columnSpecs An optional list of lists to manually specify the types of some columns in the data frame.
#' Each top level element in the list corresponds to a column, and the list assigned to each column should have
#' two elements: `analyticalType` and `semanticType`. `analyticalType` can
#' only be one of "measure" or "dimension". `semanticType` can only be one of
#' "quantitative", "temporal", "nominal" or "ordinal". For example:
#' \code{list(
#' "gender" = list(analyticalType = "dimension", semanticType = "nominal"),
#' "age" = list(analyticalType = "measure", semanticType = "quantitative")
#' )}
#' @param visConfig An optional config string to reproduce your chart. You can copy the string by clicking "export config" button on the GWalkR interface.
#'
#' @return An \code{htmlwidget} object that can be rendered in R environments
#'
#' @examples
#' \dontrun{
#' data(mtcars)
#' gwalkr(mtcars)
#' }
#'
#' @export
gwalkr <- function(data, lang = "en") {
gwalkr <- function(data, lang = "en", columnSpecs = list(), visConfig = NULL) {
if (!is.data.frame(data)) stop("data must be a data frame")
lang <- match.arg(lang, choices = c("en", "ja", "zh"))

rawFields <- raw_fields(data, columnSpecs)
colnames(data) <- sapply(colnames(data), fname_encode)
# forward options using x
x = list(
dataSource = jsonlite::toJSON(data, pretty=TRUE),
rawFields = raw_fields(data),
dataSource = jsonlite::toJSON(data),
rawFields = rawFields,
i18nLang = lang,
hideDataSourceConfig = TRUE
hideDataSourceConfig = TRUE,
visSpec = visConfig
)

# create widget
Expand All @@ -40,6 +54,8 @@ gwalkr <- function(data, lang = "en") {
#'
#' Output and render functions for using gwalkr within Shiny
#' applications and interactive Rmd documents.
#'
#' @import shiny
#'
#' @param outputId output variable to read from
#' @param width,height Must be a valid CSS unit (like \code{'100\%'},
Expand All @@ -53,7 +69,27 @@ gwalkr <- function(data, lang = "en") {
#' @name gwalkr-shiny
#'
#' @export
gwalkrOutput <- function(outputId, width = '100%', height = '400px'){
#' @examples # !formatR
#' library(GWalkR)
#' library(shiny)
#' data(mtcars)
#' app <- shinyApp(
#' ui = fluidPage(
#' titlePanel("Explore the data here: "),
#' gwalkrOutput("mygraph")
#' ),
#' server = function(input, output, session) {
#' output$mygraph = renderGwalkr(
#' gwalkr(mtcars)
#' )
#' }
#' )
#' \donttest{if (interactive()) app}
#' @return \itemize{
#' \item \code{gwalkrOutput}: A \code{shinyWidgetOutput} object for the root HTML element.
#' \item \code{renderGwalkr}: A server-side function to help Shiny display the GWalkR visualization.
#' }
gwalkrOutput <- function(outputId, width = '100%', height = '100%'){
htmlwidgets::shinyWidgetOutput(outputId, 'gwalkr', width, height, package = 'GWalkR')
}

Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[English](README.md) | [中文](./docs/README.zh.md)
[English](README.md) | [中文](docs/README.zh.md)

<img src="docs/img/hex_logo.png" align="right" alt="logo" width="120" height = "139" style = "border: none; float: right;">

Expand All @@ -7,7 +7,7 @@
![](https://img.shields.io/github/actions/workflow/status/kanaries/GWalkR/web-app-build.yml?style=flat-square)
![](https://img.shields.io/github/license/kanaries/GWalkR?style=flat-square)
[![](https://img.shields.io/badge/twitter-kanaries_data-03A9F4?style=flat-square&logo=twitter)](https://twitter.com/kanaries_data)
[![](https://img.shields.io/discord/987366424634884096?color=%237289da&label=Discord&logo=discord&logoColor=white&style=flat-square)](https://discord.gg/WWHraZ8SeV)
[![](https://img.shields.io/discord/987366424634884096?color=%237289da&label=Discord&logo=discord&logoColor=white&style=flat-square)](https://discord.com/invite/WWHraZ8SeV)

Start Exploratory Data Analysis (EDA) in R with a Single Line of Code!
[GWalkR](https://github.com/Kanaries/GWalkR) is an interactive Exploratory Data Analysis (EDA) Tool in R.
Expand All @@ -27,12 +27,12 @@ It can simplify your R data analysis and data visualization workflow, by turning
If you have `devtools` installed in R, you can run the following R code to install.

```R
devtools::install_url("https://kanaries-app.s3.ap-northeast-1.amazonaws.com/oss/gwalkr/GWalkR_0.1.0.tar.gz")
devtools::install_url("https://kanaries-app.s3.ap-northeast-1.amazonaws.com/oss/gwalkr/GWalkR_latest.tar.gz")
```

#### Through Package Archive File (.tar.gz)

Alternatively, download the package archive file `GWalkR_0.1.0.tar.gz` from [this link](https://kanaries-app.s3.ap-northeast-1.amazonaws.com/oss/gwalkr/GWalkR_0.1.0.tar.gz).
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).
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".

#### Through CRAN
Expand Down
6 changes: 3 additions & 3 deletions docs/README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
![](https://img.shields.io/github/actions/workflow/status/kanaries/GWalkR/web-app-build.yml?style=flat-square)
![](https://img.shields.io/github/license/kanaries/GWalkR?style=flat-square)
[![](https://img.shields.io/badge/twitter-kanaries_data-03A9F4?style=flat-square&logo=twitter)](https://twitter.com/kanaries_data)
[![](https://img.shields.io/discord/987366424634884096?color=%237289da&label=Discord&logo=discord&logoColor=white&style=flat-square)](https://discord.gg/WWHraZ8SeV)
[![](https://img.shields.io/discord/987366424634884096?color=%237289da&label=Discord&logo=discord&logoColor=white&style=flat-square)](https://discord.com/invite/WWHraZ8SeV)

一行代码,开启您在R中的数据探索之旅!

Expand All @@ -27,12 +27,12 @@
如果您已在R中安装了`devtools`,您可以在脚本中运行以下R代码来下载。

```R
devtools::install_url("https://kanaries-app.s3.ap-northeast-1.amazonaws.com/oss/gwalkr/GWalkR_0.1.0.tar.gz")
devtools::install_url("https://kanaries-app.s3.ap-northeast-1.amazonaws.com/oss/gwalkr/GWalkR_latest.tar.gz")
```

#### 通过下载 .tar.gz 文件包安装

或者,从[这个链接](https://kanaries-app.s3.ap-northeast-1.amazonaws.com/oss/gwalkr/GWalkR_0.1.0.tar.gz)中下载包 GWalkR_0.1.0.tar.gz。
或者,从[这个链接](https://kanaries-app.s3.ap-northeast-1.amazonaws.com/oss/gwalkr/GWalkR_latest.tar.gz)中下载包 GWalkR_latest.tar.gz。
打开 R Studio,点击 "Packages" 窗口中的 "Install",然后在 "Install from" 中选择 "Package Archive File (.tgz; .tar.gz)"。然后,选择您的文件系统中的下载好的包,最后点击"Install"。

#### 通过 CRAN 安装
Expand Down
2 changes: 1 addition & 1 deletion inst/htmlwidgets/gwalkr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ dependencies:
src: htmlwidgets/lib/gwalkr
script:
- gwalkr-app.iife.js
stylesheet:
- style.css
- vite.svg
26 changes: 25 additions & 1 deletion man/gwalkr-shiny.Rd

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

19 changes: 16 additions & 3 deletions man/gwalkr.Rd

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

4 changes: 2 additions & 2 deletions web_app/index.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<html lang="en" class="dark">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
<title>GWalkR App</title>
</head>
<body>
<div id="rwalker-app"></div>
Expand Down
11 changes: 9 additions & 2 deletions web_app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,26 @@
"mobx-react-lite": "^3.4.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"styled-components": "^5.3.6",
"tailwind": "^4.0.0"
"styled-components": "^5.3.6"
},
"devDependencies": {
"@types/react": "^18.2.14",
"@types/react-dom": "^18.2.6",
"@types/styled-components": "^5.1.26",
"@typescript-eslint/eslint-plugin": "^5.61.0",
"@typescript-eslint/parser": "^5.61.0",
"@vitejs/plugin-react": "^4.0.1",
"autoprefixer": "^10.4.14",
"eslint": "^8.44.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.1",
"postcss": "^8.4.26",
"tailwindcss": "^3.3.3",
"typescript": "^5.0.2",
"vite": "^4.4.0"
},
"prettier": {
"tabWidth": 4,
"printWidth": 160
}
}
6 changes: 6 additions & 0 deletions web_app/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
8 changes: 8 additions & 0 deletions web_app/src/components/button/base.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from "react";

export interface ButtonBaseProps {
onClick: (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
text: string;
disabled?: boolean;
className?: string;
}
Loading