{"id":13735547,"url":"https://github.com/react-R/nivocal","last_synced_at":"2025-05-08T11:33:44.764Z","repository":{"id":98208294,"uuid":"167836665","full_name":"react-R/nivocal","owner":"react-R","description":"nivo heatmap calendar as R htmlwidget","archived":false,"fork":false,"pushed_at":"2019-02-18T04:08:05.000Z","size":7055,"stargazers_count":40,"open_issues_count":3,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-01-28T23:09:57.418Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"R","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/react-R.png","metadata":{"files":{"readme":"README.Rmd","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-01-27T17:25:35.000Z","updated_at":"2023-04-28T17:21:02.000Z","dependencies_parsed_at":"2023-05-18T15:31:54.115Z","dependency_job_id":null,"html_url":"https://github.com/react-R/nivocal","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-R%2Fnivocal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-R%2Fnivocal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-R%2Fnivocal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-R%2Fnivocal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/react-R","download_url":"https://codeload.github.com/react-R/nivocal/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224727181,"owners_count":17359532,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T03:01:08.034Z","updated_at":"2024-11-15T03:32:13.883Z","avatar_url":"https://github.com/react-R.png","language":"R","readme":"---\noutput: github_document\n---\n\n\u003c!-- README.md is generated from README.Rmd. Please edit that file --\u003e\n\n```{r setup, include = FALSE}\nknitr::opts_chunk$set(\n  collapse = TRUE,\n  comment = \"#\u003e\",\n  fig.path = \"man/figures/README-\",\n  out.width = \"100%\"\n)\n```\n# Making of nivocal\n\n`nivocal` was built to be a working package, but while I was at it I wanted to record each step in the creation journey as a reference for future authors of [`reactR`](https://github.com/react-R/reactR)-based `htmlwidgets`.  For reference, the package in its initial working state required less than 30 minutes of effort.  I never left my RStudio window, and I only had to write 1.5 lines of JavaScript.\n\n## One Time on the Internet I Found ...\n\nThere are some amazing [`React`](https://reactjs.org/) comoponents out there.  If one day on the Internet, you find something you like then it can be ready to use in R in less than an hour (hopefully shorter if you read this document).  Take for example the [\\@nivo](https://nivo.rocks/components) set of components.  I'd like to use the Github-style [calendar](https://nivo.rocks/calendar/).\n\n![screenshot of nivo calendar](./man/figures/nivocal_site_screenshot.PNG)\n\n## Starting the Package\n\n[`usethis`](https://github.com/r-lib/usethis) allows us to create a package in one line of code.  Let's begin our journey here.\n\n```{r eval=FALSE}\nusethis::create_package(\"nivocal\")\n```\n\n![screencast of creating package with use this](./man/figures/nivocal2.gif)\n\n## Scaffolding\n\nOnce we have a package, we'll open it up and then build a scaffold.  Sometimes finding the `npmPkgs` argument can be a little tricky.  Usually, the best clues are in the docs, but we can also use [unpkg.com](https://unpkg.com)--the CRAN of Node JavaScript--for some help.  End the url with `/` to see the contents of the package and find the most recent version.  For the calender, we do [https://unpkg.com/@nivo/calendar/](https://unpkg.com/@nivo/calendar/).  Remember the `/`.  Try [https://unpkg.com/@nivo/calendar](https://unpkg.com/@nivo/calendar) to see the difference.\n\n```{r eval=FALSE}\nscaffoldReactWidget(\n  \"nivocal\",\n  npmPkgs = c(\"@nivo/calendar\" = \"0.52.1\")\n)\n```\n\n![screencast of scaffolding the widget](./man/figures/nivocal3.gif)\n\nNow we have  all the files we need for a working `htmlwidget` but unfortunately not working in the way we want.\n\n## 1.5 Lines of JavaScript and Build\n\nIn the JavaScript, we will need to import the module we want to use.  For `nivocal` we want `ResponsiveCalendar`.   `import` in JavaScript is very similar to `library()` in R.\n\n```{r eval=FALSE}\nimport { ResponsiveCalendar } from '@nivo/calendar'\n```\n\nThe JavaScript build toolchain can get complicated, but fortunately `reactR` takes care of much of this for us.  I hate to tell you, but you will need to install [`node`](https://nodejs.org/en/download/) and [`yarn`](https://yarnpkg.com/lang/en/docs/install).  I promise this is not hard or scary though.  Once you have both installed, we will build/webpack our JavaScript in the RStudio terminal or other terminal/console.\n\n```{r eval=FALSE}\nyarn install\nyarn run webpack\n```\n\n![screencast of building the JavaScript](./man/figures/nivocal4.gif)\n\nThe built JavaScript will be copied into the `/inst/htmlwidgets` directory ready for use in our R `htmlwidget`.\n\n## Build R Package\n\nWe have a couple more things to do on the `R` side.  For now, let's see if the package builds. In RStudio, we can `CTRL + Shift + B` or \n\n```{r eval=FALSE}\ndevtools::document()\ndevtools::install(quick = TRUE)\n```\n\n![screencast of building the R package](./man/figures/nivocal5.gif)\n\nIf all goes well, then our package is working, but as I said just not quite in the way we want.\n\n## Add Some Arguments\n\nNow we need a way to go from R to JavaScript.  We'll add arguments for the `data`, `from`, and `to` component `props` in our `R` function.\n\n![screencast of add R function arguments](./man/figures/nivocal6.gif)\n\n## Change the Tag\n\nThe scaffold uses `div`, but we want to use the `ResponsiveCalendar` component.  `React` components are always [capitalized](https://reactjs.org/docs/jsx-in-depth.html#user-defined-components-must-be-capitalized).\n\n![screencast of change tag to component](./man/figures/nivocal7.gif)\n\n\n## Add More Props/options and Do Some R Work\n\nThere are a lot of other options for the calendar.  For a well-built R package, I think each of these should be dcoumented arguments, but for now we'll use `...` to pass other options from R to JavaScript.\n\n`data`, `from`, and `to` are required for the calendar component.  Eventually, we want to accept various forms of `data` from the user, but for now we will assume the user provides a `data.frame` with two columns `day` and `value`.  `htmlwidgets` communicate `data.frames` as an [array of arrays](https://www.htmlwidgets.org/develop_advanced.html#data-transformation) but `ResponsiveCalendar` wants the equivalent of `dataframe = \"rows\"` in `jsonlite::toJSON()`.  We'll use `mapply` to do this, but as described in the [data transformation](https://www.htmlwidgets.org/develop_advanced.html#data-transformation) article we have other methods to achieve this.  The most common form -- using JavaScript `HTMLWidgets.dataframeToD3()` -- does not currently work well with `reactR`-based `htmlwidgets`.\n\nWithout `from` and `to`, the calendar will not render, so let's assume the user wants `from` to be the first row of the data and `to` to be the last row.\n\n\n![screencast of use ellipsis for other options and munge arguments](./man/figures/nivocal8.gif)\n\n## It's Working\n\nNow we have a working `htmlwidget`.  Build the package with `CTRL+Shift+B` or \n\n```{r eval=FALSE}\ndevtools::document()\ndevtools::install(quick = TRUE)\n```\n\nGive it some data and see an interactive calendar.\n\n```{r eval=FALSE}\nlibrary(nivocal)\n\n# fake data of 500 records/days starting 2017-03-15\ndf \u003c- data.frame(\n  day = seq.Date(\n    from = as.Date(\"2017-03-15\"),\n    length.out = 500,\n    by = \"days\"\n  ),\n  value = round(runif(500)*1000, 0)\n)\n\nnivocal(df)\n```\n\n![screencast of working package widget](./man/figures/nivocal9.gif)\n\n## Customize\n\nRemember we added `...` for further customization.  Let's see how this works.\n\n```{r eval=FALSE}\nlibrary(nivocal)\n\n# fake data of 500 records/days starting 2017-03-15\ndf \u003c- data.frame(\n  day = seq.Date(\n    from = as.Date(\"2017-03-15\"),\n    length.out = 500,\n    by = \"days\"\n  ),\n  value = round(runif(500)*1000, 0)\n)\n\nnivocal(\n  df,\n  direction = \"vertical\",\n  colors = RColorBrewer::brewer.pal(n=9, \"Blues\")\n)\n```\n\n![screencast of more customization](./man/figures/nivocal10.gif)\n\n## More Resources\n\nEven though all of this is fairly new, we have tried to offer examples and resources to ease the learning curve.  The [react-R Github organization](https://github.com/react-R) is intended to be a friendly central location for all things R + React.  Please join in the fun.\n\n- [Alan Dipert rstudio::conf 2019 Video](https://resources.rstudio.com/rstudio-conf-2019/integrating-react-js-and-shiny) hear from the creator himself\n\n- [Authoring reactR htmlwidgets tutorial](https://react-r.github.io/reactR/articles/intro_htmlwidgets.html)\n\n- [react-sparklines example package](https://github.com/react-R/sparklines-example) great first example package\n\n- [office-fabric-ui example package](https://github.com/react-R/roffice) widget example with no JavaScript build steps\n\n- [MapboxGL example package](https://github.com/react-R/MapboxGL-example) package discussed in the rstudio::conf 2019 video\n\n- [forcer](https://github.com/react-R/forcer) `react-force-graph` example package for `2d`, `3d`, and virtual reality force directed network graphs.\n\n\n## Vue\n\nWe'd like to do the same for `Vue`.  Please let us know if you have interest.  [`vueR`](https://github.com/timelyportfolio/vueR) would be a good starting point.\n","funding_links":[],"categories":["Visualization"],"sub_categories":["Heatmap"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freact-R%2Fnivocal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freact-R%2Fnivocal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freact-R%2Fnivocal/lists"}