```{r setup, include=FALSE} knitr::opts_chunk$set(eval = FALSE) ``` ## Setup R Package Create a package for this HTML widget. We're not going to publish this, so you can call it whatever you want ```{r create-package} usethis::create_package("frappeCharts") ``` Add a dev script for notes ```{r dev} dir.create("dev") file.create("dev/dev.R") rstudioapi::navigateToFile("dev/dev.R") ``` ## Setup npm package Same process again, but this time for npm. ```bash npm init # or npm init -y ``` Open `package.json` and take a look ```json { "name": "frappecharts", "version": "0.0.1", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "MIT" } ``` From Frappe Charts [docs#installation](https://frappe.io/charts/docs#installation): ```bash npm install frappe-charts ``` We now have a dependency in `package.json` and there's a `package-lock.json` file. ```json "dependencies": { "frappe-charts": "^1.3.0" } ``` ## Ignore node_modules but add package-lock There's also a `node_modules/` folder with `frappe-charts/` inside. Add `node_modules` to `.Rbuildignore` and `.gitignore`. (BTW, you can and are supposed to commit `package-lock.json`.) ```{r ignore-node-module} usethis::use_build_ignore("node_modules") usethis::use_build_ignore("package.json") usethis::use_build_ignore("package-lock.json") usethis::use_git_ignore("node_modules") ``` ## Scaffold the HTML widget ```{r htmlwidgets-scaffold} htmlwidgets::scaffoldWidget("frappeChart") ``` This adds files in `inst/htmlwidgets` ``` inst └── htmlwidgets ├── frappeChart.js #<< R <-> JS code └── frappeChart.yaml #<< list of dependencies ``` and creates a file `R/frappeChart.R` with the functions - `frappeChart()` - `frappeChartOutput()` (for shiny) - `renderFrappeChart()` (for shiny) ## Use `npm` to get our dependencies in the right place `htmlwidgets` load dependencies in a way that's exactly the same as using a ` ``` We need to get our dependecy into a subfolder of `inst/htmlwidgets`. Convention is `inst/htmlwidgets/lib/`. Rather than creating the directoy and copying over, etc., we can have an `npm` build script do this for us. To avoid issues with mac/windows, we'll add a dev dependency on [`cpy-cli`](https://github.com/sindresorhus/cpy-cli) ```bash npm install cpy-cli --save-dev ``` and ```{r create-lib-dir} dir.create("inst/htmlwidets/lib/frappe-charts", recursive = TRUE) ``` and then edit `package.json` to add copy tasks ``` "scripts": { "copy-js": "cpy 'node_modules/frappe-charts/dist/frappe-charts.min.iife*' inst/htmlwidgets/lib/frappe-charts/", "build": "npm run copy-js" } ``` ## Create a demo html_document_plain() ```{r create-demo-html} dir.create("dev/demo") js4shiny::js4shiny_rmd(path = "dev/demo/demo.Rmd") ``` Use the example in the [Frappe Charts Docs](https://frappe.io/charts/docs). ```{r} tagList( div(id = "chart"), htmltools::htmlDependency( name = "frappe-charts", version = "1.3.0", package = "frappeCharts", src = "htmlwidgets/lib/frappe-charts", script = "frappe-charts.min.iife.js", all_files = TRUE ) ) ``` And copy the JS into a javascript chunk. `r emo::ji("warning")` The dependencies won't be found until you build/install. ```{r build-install} devtools::document() devtools::install() ``` If you get a path not found error ``` Error: path for html_dependency not found: inst/htmlwidgets/lib/frappe-charts ``` it's most likely because ``` src = "inst/htmlwidgets/lib/frappe-charts" ``` ## Replace the example data with another data set and example The first demo mixes chart types and we don't want to do that. Use the example from [Basic Chart](https://frappe.io/charts/docs/basic/basic_chart#adding-more-datasets). ```js const data = { labels: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], datasets: [ { name: "R", values: [18, 40, 30, 35, 8, 52, 17, -4] }, { name: "Python", values: [30, 50, -10, 15, 18, 32, 27, 14] } ] } ```