I want to create a Shiny app that shows a lattice plot, together with selection menus for specifying the number of rows and columns. In the actual app, the lattice plot can be quite large and slow to appear so I want to use an action button to delay displaying the chart until that button is clicked.
library(shiny)
library(ggplot2)
ui <- fluidPage(tabsetPanel(id = "inTabset",
tabPanel(
"Lattice plot",
fluidRow(
column(
width = 2,
numericInput(
"nRows",
"Number of rows",
value = 5,
min = 1,
max = 12
)
),
column(
width = 2,
numericInput(
"nCols",
"Number of columns",
value = 4,
min = 1,
max = 12
)
),
actionButton(
inputId = "bttn1",
label = "Update Chart",
size = "sm",
color = "primary",
style = "jelly"
)
),
plotOutput(outputId = "overview")
)))
server <- function(input, output, session) {
# Generate some random data, 3 rows, 4 columns initially, 10 cases per dataset
getData <- reactive({
ranData <-
expand.grid(
x = 1:10,
rowvar = 1:input$nRows,
colvar = 1:input$nCols
)
ranData$y <- rnorm(nrow(ranData))
as.data.frame(ranData)
})
output$ui_rownr <- renderUI({
selectInput("rowVal",
label = "Row value",
choices = 1:input$nRows)
})
output$ui_colnr <- renderUI({
selectInput("colVal",
label = "Column value",
choices = 1:input$nCols)
})
displayOverviewChart <- reactiveVal(NULL)
observeEvent(input$bttn1, {
displayOverviewChart(input$bttn1[1])
})
output$overview <- renderPlot({
cat("Start: ", displayOverviewChart(), "\n")
if (is.null(displayOverviewChart()))
return()
# displayOverviewChart(NULL)
cat("End: ", displayOverviewChart(), "\n")
ggplot(getData(), aes(y = y, x = x)) +
geom_line() +
labs(y = "y") +
scale_x_discrete(name = "x", limits = factor(1:10)) +
theme_bw(base_size = 18) +
theme(aspect.ratio = 9 / 16) +
facet_grid(vars(rowvar), vars(colvar))
},
height = 600)
}
shinyApp(ui = ui, server = server)
The above code works partially. The lattice chart won't be displayed until the button is clicked. However, I can't seem to reset the button so I can change the number of rows or columns and then display the new chart. I use displayOverviewChart
, a reactiveval
object, to indicate when a button is clicked, and I thought I could reset that displayOverviewChart(NULL)
to reset the action button so the chart won't be updated until the button is clicked again.
Unfortunately, that doesn't work. If I uncomment displayOverviewChart(NULL)
, the cat
statements show that displayOverviewChart
is initially NULL. After clicking the button, it becomes 1 at the start of output$overview
, it is NULL at the end as can be expected. But then output$overview
runs again without displaying the chart and stops because displayOverviewChart
is NULL!
I guess that resetting displayOverviewChart
triggers a reaction in output$overview
. I've tried using isolate
with and without local
but that doesn't solve this issue. Can someone explain how to reset the action button so the plot appears only if the button is clicked?