Closed jhofman closed 3 years ago
Moving the htmlwidgets discussion to here @jhofman @giorgi-ghviniashvili so it doesn't get lost in a conversation about Shiny apps.
I overwrote the bar chart shiny app with one that takes datamations frames, but here is how it works in a static R script (with info on how to install/run the app if you want)
library(dplyr)
library(palmerpenguins)
# Install code from branch (or just check it out)
# devtools::install_github("jhofman/datamations", ref = "vegalite-shiny")
library(datamations)
# Run app with
datamations::run_app()
# Or just see output
mtcars %>%
count(disp, name = "y") %>%
rename(x = disp) %>%
vegaliteBar()
penguins %>%
count(species, name = "y") %>%
rename(x = species) %>%
vegaliteBar()
To explain the htmlwidgets structure....
vegaliteBar()
is an R function defined in R/vegaliteBar.R
that takes the data as an argument and passes it immediately to the htmlwidgets framework to create a widget (named "vegaliteBar")inst/htmlwidgets/vegaliteBar.js
is part of this framework - it takes the data passed from vegaliteBar()
, converts it to the correct format, calls the barChart()
js function on that data, and then embeds it in the element. The structure of this file is all predetermined by the htmlwidgets
framework. It is also named "vegaliteBar" which is how the R and JS functions are connected.inst/htmlwidgets/barChart/barChart.js
contains the barChart()
function to actually create the vegalite bar chart from the data. This code is short enough that it could just be contained within vegaliteBar.js
, but it'll probably be nice for us to separate out the code that creates the visualization from the code that creates the widget (above)inst/htmlwidgets/vegaliteBar.yaml
defines all of the dependencies for the widget. They are stores locally in inst/htmlwidgets/
When you call vegaliteBar()
, it renders the visualization in the RStudio viewer (a browser inside RStudio).
The ability to embed in a shiny app is just a given with the htmlwidgets structure - you create the widget with vegaliteBar()
, render it in the server function as a "vegaliteBar" type, then put the output as a vegaliteBar type output in the UI. This idea of "render in the server" and "output in the UI" is the same for all Shiny apps, and automatically provided by the htmlwidgets framework.
Hope that is clear! Let me know if there's any questions.
thanks for the great explanation of how this works @sharlagelfand!
@sharlagelfand I just saw that you integrated my code into the shiny app in datamations-widget
branch. Could you please help me run that shiny app locally (without devtools::install_github("jhofman/datamations", ref = "datamations-widget"
)?
@giorgi-ghviniashvili I'm still working on it, it's not fully functional yet unfortunately! But good spot 😄
This is just a widget that will be viewable in the RStudio viewer pane, not yet in any shiny app.
You can see where it is at so far though by running:
devtools::load_all() # to load the latest version of the code
datamationSandDance("test") # doesn't matter what the message is since it's not used, but has to have something
You can open it in your browser by clicking the button outlined in red.
The animating doesn't work yet, but in case it's easier for you to inspect in the browser and figure out why than it would be for me, the HTML is defined here (this is what gives the div where the chart actually is a random ID) and the JS is all defined here.
Thanks! I just did not know about devtools::load_all()
, I set working directory to datamations
and then it worked.
Let me try to fix that widget or at least see how it works.
Sounds good! If you open the datamations.Rproj
file, in RStudio it will set the working directory to be datamations by default when you are in that project, rather than having to set it
It says that play()
function not defined. If you call play() directly after init() datamationSandDance.js it will play it.
Have figured out getting the play()
button working in this widget! Updated code is in the [datamations-widget
branch]() - note that the JS for the widget is quite small, and it mostly calls external functions that do all the work. I've also updated init()
and play()
to take an ID so that we could have multiple widgets on a page, and the button would operate on the correct widget.
So this code produces a widget which can be played via the button:
datamationSandDance()
@sharlagelfand this PR includes the simplified version of js, only play button. Removed slider and dataset name.
Closing this since I think the new issues cover what comes next.
At some point we need to load the appropriate javascript libraries and pass data from R to html.
Can do so with files, but is there a better way (akin to r2d3)?