Skip to content

All event_data() reactives needlessly fire whenever a new one is registered #2337

Closed
@dvg-p4

Description

@dvg-p4
Contributor

This appears to be due to this line, which (I presume unintentionally) creates a reactive dependency on the names of this reactiveValues list (not just the specific relevant value):

eventHasStorage <- eventID %in% names(session$userData$plotlyInputStore)

I believe this is a mainly an issue if you try to avoid the infamous "event tied a source ID" warning by preventing various event_data() calls from running until after their respective plots have (probably) rendered, as recommended.

Reprex

library(shiny)
library(plotly)
options(shiny.reactlog = TRUE)

ui <- fluidPage(
  fluidRow(
    column(4, checkboxInput("faithful_on", "Render `faithful` plot")),
    column(4, checkboxInput("iris_on", "Render `iris` plot")),
    column(4, checkboxInput("cars_on", "Render `cars` plot")),
  ),
  fluidRow(
    column(4, plotlyOutput("faithful_plot")),
    column(4, plotlyOutput("iris_plot")),
    column(4, plotlyOutput("cars_plot")),
  ),
  fluidRow(
    column(4, verbatimTextOutput("faithful_click")),
    column(4, verbatimTextOutput("iris_click")),
    column(4, verbatimTextOutput("cars_click")),
  )
)

server <- function(input, output, session) {

  output$faithful_plot <- renderPlotly({
    req(input$faithful_on)
    plot_ly(faithful, x=~eruptions, y=~waiting, type = "scatter", mode = "markers", source="faithful")
  })

  output$faithful_click <- renderPrint({
    req(input$faithful_on)
    list(
      updated_at = Sys.time(),
      data = event_data("plotly_click", source="faithful")
    )
  })

  output$iris_plot <- renderPlotly({
    req(input$iris_on)
    plot_ly(iris, x = ~Sepal.Length, y = ~Petal.Length, type = "scatter", mode = "markers", source = "iris")
  })

  output$iris_click <- renderPrint({
    req(input$iris_on)
    list(
      updated_at = Sys.time(),
      data = event_data("plotly_click", source="iris")
    )
  })

  output$cars_plot <- renderPlotly({
    req(input$cars_on)
    plot_ly(cars, x = ~speed, y = ~dist, type = "scatter", mode = "markers", source = "cars")
  })

  output$cars_click <- renderPrint({
    req(input$cars_on)
    list(
      updated_at = Sys.time(),
      data = event_data("plotly_click", source="cars")
    )
  })
}

shinyApp(ui = ui, server = server)

Click on one of the checkboxes to enable a plot and its respective event_data(). Then click on a second. Note the "time updated" on the second plot's output dump as you enable the third plot--it will change, as names(session$userData$plotlyInputStore) triggers a spurious update. (If you refresh and click on a point on the first plot before enabling the second, the first one will spuriously update as well). We can see this dependency in the reactlog:

image image

Activity

changed the title [-]This line creates an unnecessary reactive dependency that causes event_data() reactives to fire whenever a new handler is registered[/-] [+]`event_data()` reactives needlessly fire whenever a new handler is registered[/+] on Feb 1, 2024
changed the title [-]`event_data()` reactives needlessly fire whenever a new handler is registered[/-] [+]All `event_data()` reactives needlessly fire whenever a new one is registered[/+] on Feb 1, 2024
dvg-p4

dvg-p4 commented on Apr 26, 2024

@dvg-p4
ContributorAuthor

I've got a very simple PR that will fix this, if someone would be willing to take the time to review it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Participants

      @dvg-p4

      Issue actions

        All `event_data()` reactives needlessly fire whenever a new one is registered · Issue #2337 · plotly/plotly.R