Reputation: 372
Overview: I'm using a reactive component to update the data set dynamically based on user input. This works without any issue.
Additional requirement: I want to color the plot only on click of a button. Current setting: After I click 'Color' button, the color remains even if I change the data set.
I defined the same output element inside an observeEvent block to override the default element defined in server. However, this override is permanent.
library(shiny)
shinyApp(ui = fluidPage(
sidebarPanel(
selectInput(inputId = "dropdown", label = "Select data set:",
choices = c("iris", "mtcars"), selected = "iris")
),
mainPanel(fluidPage(
fluidRow(plotOutput("plot"),
actionButton("color", "Color"))
))
), server = function(input, output) {
get_data <- reactive({
if(input$dropdown == "iris") {
return(list(dat = iris, x = "Sepal.Length", color = "Species"))
} else {
return(list(dat = mtcars, x = "mpg", color = "cyl"))
}
})
output$plot <- renderPlot({
dat <- get_data()
return(plot(dat$dat[, dat$x]))
})
observeEvent(input$color, {
output$plot <- renderPlot({
dat <- get_data()
return(plot(dat$dat[, dat$x], col = dat$dat[, dat$color]))
})
})
})
Actual result: Color appears every time clicking "Color" button even if I change the data set. Expected result: Color should appear after clicking "Color" for the current data set. It should not appear once I change the data set. It should reappear only when I click "Color" button again.
Upvotes: 2
Views: 769
Reputation: 7908
You can explicitly observe the event that is triggered by input$dropdown
:
function(input, output) {
get_data <- reactive({
if(input$dropdown == "iris") {
return(list(dat = iris, x = "Sepal.Length", color = "Species"))
} else {
return(list(dat = mtcars, x = "mpg", color = "cyl"))
}
})
observeEvent(input$dropdown, {
output$plot <- renderPlot({
dat <- get_data()
return(plot(dat$dat[, dat$x]))
})
})
observeEvent(input$color, {
output$plot <- renderPlot({
dat <- get_data()
return(plot(dat$dat[, dat$x], col = dat$dat[, dat$color]))
})
})
}
Upvotes: 1
Reputation: 206242
It seems like you want to be tracking state. You can't really "un-click" a button so it would be better just to store a reactive value to indicate whether or not you want colors and you can reset that when the dataset changes. Here's such a server function
function(input, output) {
showColor <- reactiveVal(FALSE)
get_data <- reactive({
if(input$dropdown == "iris") {
return(list(dat = iris, x = "Sepal.Length", color = "Species"))
} else {
return(list(dat = mtcars, x = "mpg", color = "cyl"))
}
})
output$plot <- renderPlot({
dat <- get_data()
if (showColor()) {
plot(dat$dat[, dat$x], col = dat$dat[, dat$color])
} else {
plot(dat$dat[, dat$x])
}
})
observeEvent(input$dropdown, {
showColor(FALSE)
})
observeEvent(input$color, {
showColor(TRUE)
})
}
You see we added the showColor <- reactiveVal(FALSE)
part so it won't show colors by default and reset it to FALSE
when the dropdown changes. We set it to TRUE
when you press the "color" button.
Upvotes: 2