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
-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.
There are some amazing React
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 set of components. I’d like to
use the Github-style calendar.
usethis
allows us to create a
package in one line of code. Let’s begin our journey here.
usethis::create_package("nivocal")
Once 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–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/. Remember the /
. Try
https://unpkg.com/@nivo/calendar to see the difference.
scaffoldReactWidget(
"nivocal",
npmPkgs = c("@nivo/calendar" = "0.52.1")
)
Now we have all the files we need for a working htmlwidget
but
unfortunately not working in the way we want.
In 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.
import { ResponsiveCalendar } from '@nivo/calendar'
The 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
and
yarn
. 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.
yarn install
yarn run webpack
The built JavaScript will be copied into the /inst/htmlwidgets
directory ready for use in our R htmlwidget
.
We 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
devtools::document()
devtools::install(quick = TRUE)
If all goes well, then our package is working, but as I said just not quite in the way we want.
Now 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.
The scaffold uses div
, but we want to use the ResponsiveCalendar
component. React
components are always
capitalized.
There 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.
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
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
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
.
Without 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.
Now we have a working htmlwidget
. Build the package with
CTRL+Shift+B
or
devtools::document()
devtools::install(quick = TRUE)
Give it some data and see an interactive calendar.
library(nivocal)
# fake data of 500 records/days starting 2017-03-15
df <- data.frame(
day = seq.Date(
from = as.Date("2017-03-15"),
length.out = 500,
by = "days"
),
value = round(runif(500)*1000, 0)
)
nivocal(df)
Remember we added ...
for further customization. Let’s see how this
works.
library(nivocal)
# fake data of 500 records/days starting 2017-03-15
df <- data.frame(
day = seq.Date(
from = as.Date("2017-03-15"),
length.out = 500,
by = "days"
),
value = round(runif(500)*1000, 0)
)
nivocal(
df,
direction = "vertical",
colors = RColorBrewer::brewer.pal(n=9, "Blues")
)
Even 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 is intended to be a friendly central location for all things R + React. Please join in the fun.
-
Alan Dipert rstudio::conf 2019 Video hear from the creator himself
-
react-sparklines example package great first example package
-
office-fabric-ui example package widget example with no JavaScript build steps
-
MapboxGL example package package discussed in the rstudio::conf 2019 video
-
forcer
react-force-graph
example package for2d
,3d
, and virtual reality force directed network graphs.
We’d like to do the same for Vue
. Please let us know if you have
interest. vueR
would be a
good starting point.