I'm trying to use plotly click events in the context of a shiny app. Following the official demo I'm using this bit of code to update a date picker and jump to another tab in my app on click:
observe({
d <- event_data("plotly_click", source = 'plot')
if(!is.null(d) & (input$navPanel == 'overview')) {
d %>% filter(curveNumber == 0) %>% select(x) -> selected_date
updateDateInput(session, "date", value = lubridate::ymd(selected_date$x))
updateTabsetPanel(session, "navPanel", selected = "details")
}
However, when I then try to switch back from the details
to the overview
tab, I get immediately thrown back to the details
tab. I'm assuming that this happens because the event is never cleared, i.e. d
is not null
when the tab gets changed and so the condition in the if
-clause evaluates to TRUE
.
So, how do I clear the click event programmatically? Adding d <- NULL
to the end of the conditional doesn't seem to do it.
I have same problem, and the workaround I've found is to store the old state in a global variable, and do the updates only when that variable changes and not on the !is.null()
selected_date <- 0 # declare outside the server function
server <- function(input, output, session) {
observe({
d <- event_data("plotly_click")
new_value <- ifelse(is.null(d),"0",d$x) # 0 if no selection
if(selected_date!=new_value) {
selected_date <<- new_value
if(selected_date !=0 && input$navPanel == 'overview')
updateDateInput(session, "date", value = lubridate::ymd(selected_date))
}
})
...
}
This also allows you to add a behaviour whenever the element is unselected
I solved this by using shinyjs
and manually resetting the event_data("plotly_click")
with the help of the Shiny.onInputChange
function, which sets values in the input
vector manually:
library(shiny)
library(plotly)
library(shinyjs)
ui <- shinyUI(
fluidPage(
useShinyjs(),
# code to reset plotlys event_data("plotly_click", source="A") to NULL -> executed upon action button click
# note that "A" needs to be replaced with plotly source string if used
extendShinyjs(text = "shinyjs.resetClick = function() { Shiny.onInputChange('.clientValue-plotly_click-A', 'null'); }"),
actionButton("reset", "Reset plotly click value"),
plotlyOutput("plot"),
verbatimTextOutput("clickevent")
)
)
server <- shinyServer(function(input, output) {
output$plot <- renderPlotly({
plot_ly(mtcars, x=~cyl, y=~mpg)
})
output$clickevent <- renderPrint({
event_data("plotly_click")
})
observeEvent(input$reset, {
js$resetClick()
})
})
shinyApp(ui, server)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With