Reconstruct static code from shiny apps
scriptgloss
exposes functionality for building static code to recreate outputs
built in a shiny context. Construct something in shiny and generate the code
needed to produce it without needing to trudge through the app code.
For now, due to a dependency on the graph
package in Bioconductor by way of
CodeDepends
, this package will fail to install via the typical devtools
mechanisms. Instead, please use BiocManager
and follow any prompts to install
the package, pulling from Bioconductor when necessary. I'll be working to reduce
this impedence.
install.packages("BiocManager") # R (>3.5.0)
BiocManager::install("dgkf/scriptgloss")
Developer Note
This was my first foray into advising installation viaBiocManager
. If you run into issues, please report them and I'll work to make the installation seamless until this dependency requirement has been resolved.
Let's say we're building a shiny app to explore the mtcars
dataset. We might
start with something like this:
library(shiny)
ui <- fluidPage(
selectInput('x', 'x axis', choices = names(mtcars)),
selectInput('y', 'y axis', choices = names(mtcars)),
plotOutput('plot'))
srv <- function(input, output, session) {
output$plot <- renderPlot({
plot(x = mtcars[[input$x]], y = mtcars[[input$y]],
xlab = input$x, ylab = input$y)
})
}
shinyApp(ui, srv)
If you run the code above, you'll see that it's quite simple; just two drop down menus to pick an x and y variable which will update a plot to compare the two.
In order to add static code output, there are just a few small steps that need to be taken.
- The JavaScript dependencies need to be added to the webpage header. This can
be done easily by adding the UI element,
scriptglossJS()
. - A UI button needs to be added to export the code. For this,
scriptgloss
provides the functionsshowCodeButton()
andclipCodeButton()
for showing code in a modal window or copying to clipboard respectively. - An observer of the UI button needs to be added to prepare the code.
A minimal example showing how you would use the
showCodeButton()
UI element. Not the most interesting code in the world, but operational!
library(shiny)
library(scriptgloss)
ui <- fluidPage(
scriptglossJS(),
showCodeButton("show_code"))
srv <- function(input, output, session) {
# ui observer to display a modal code window when the button is pressed
observeEvent(input$show_code, show_code_modal(srv))
}
shinyApp(ui, srv)
A minimal example of how you would add a button to copy static code to the clipboard. Again, nothing too exciting, but hopefully enough to build it into your own work.
library(shiny)
library(scriptgloss)
ui <- fluidPage(
scriptglossJS(),
uiOutput('copy_code_btn'))
srv <- function(input, output, session) {
# ui observer to copy code to the user's clipboard
output$copy_code_btn <- renderUI(clipCodeButton(srv))
}
shinyApp(ui, srv)
Just by following the steps above, we can quickly add a button to show off our code!
library(shiny)
library(scriptgloss)
ui <- fluidPage(
selectInput('x', 'x axis', choices = names(mtcars)),
selectInput('y', 'y axis', choices = names(mtcars)),
plotOutput('plot'),
# add our UI elements ...
scriptglossJS(), # <-- don't forget the JavaScript part!
showCodeButton("show_code"), # button to show code as a pop-up
uiOutput("clip_code_btn")) # button to copy to clipboard
srv <- function(input, output, session) {
output$plot <- renderPlot({
plot(x = mtcars[[input$x]], y = mtcars[[input$y]],
xlab = input$x, ylab = input$y)
})
# observer for our modal button
observeEvent(input$show_code, show_code_modal(srv, "plot"))
# button renderer for our copy-to-clipboard button
output$clip_code_btn <- renderUI(clipCodeButton(text = get_code(srv, "plot")))
}
shinyApp(ui, srv)
Early prototypes developed at Genentech. Many thanks to my employer for their encouragement and accommodation in allowing me to release this work publicly.