如何在 Shiny 中跨选项卡持久化 event_data?

Posted

技术标签:

【中文标题】如何在 Shiny 中跨选项卡持久化 event_data?【英文标题】:How to persist event_data across tabs in Shiny? 【发布时间】:2018-10-17 17:08:08 【问题描述】:

我有一个闪亮的应用程序,我想在其中捕获用户单击的哪个栏并将该值存储在反应式表达式中,以便在其他地方引用以进行过滤。问题是当我切换选项卡时反应表达式会重新运行,因此两个选项卡之间的值不会同步。

我在下面有一个可重现的示例。

当您加载应用程序并单击 Goats 栏时,底部的选择会更改为“Goats”,但如果您随后将选项卡更改为 Bar2,则反应式表达式会重新运行,因此会再次返回 Giraffes。因此,我最终为不同选项卡中的反应式表达式提供了两个单独的值。如果我在第一个选项卡上选择山羊,我希望它在我切换到 Bar2 选项卡时保留,并且仅在我再次单击时更新。

请注意,我意识到我可以在此示例中通过从 event_data 函数中删除源参数来解决此问题,但在我的应用程序中,我有其他图表我不希望用户能够点击,所以我需要设置仅这些图表的来源。

library(shiny)
library(plotly)
library(ggplot2)
library(shinydashboard)

df_test <- data.frame(c("Giraffes","Goats"),c(1,4))
df_test <- setNames(df_test,c("species","amount"))

ui <- dashboardPage(

  dashboardHeader(title = "Click Example",
                  titleWidth = 300),
  dashboardSidebar(
    width = 300,
    sidebarMenu(
      menuItem("Tab", tabName = "tab")
    )
  ),
  dashboardBody(
    tabItems(
      tabItem(tabName = "tab",
              fluidRow(
                column(12, tabBox(
                  title = "",
                  id = "tabSet",
                  width = 12,
                  height = 500,
                  tabPanel("Bar1", plotlyOutput(outputId="bar_one")),
                  tabPanel("Bar2", plotlyOutput(outputId="bar_two"))
                )
                ),
                column(12,textOutput(outputId = "selection")))
      )
    )
  )
)

server <- function(input, output, session) 

  click_reactive = reactive(
    d <- event_data("plotly_click",source=input$tabSet)
    if (length(d) == 0) species = as.vector(df_test$species[1])
    else species = as.character(d[4])
    return(species)
  )

  output$bar_one <- renderPlotly(
    p <- plot_ly(data = df_test, x = ~amount, y = ~species, type = 'bar', orientation = 'h', source = "Bar1")
  )

  output$bar_two <- renderPlotly(
    p <- plot_ly(data = df_test, x = ~amount, y = ~species, type = 'bar', orientation = 'h', source = "Bar2")
  )


  output$selection <- renderText(
    species <- click_reactive()
    return(species)
  )



shinyApp(ui, server)

【问题讨论】:

【参考方案1】:

您需要将source 更改为一个名称:

library(shiny)
library(plotly)
library(ggplot2)
library(shinydashboard)

df_test <- data.frame(c("Giraffes","Goats"),c(1,4))
df_test <- setNames(df_test,c("species","amount"))

ui <- dashboardPage(

  dashboardHeader(title = "Click Example",
                  titleWidth = 300),
  dashboardSidebar(
    width = 300,
    sidebarMenu(
      menuItem("Tab", tabName = "tab")
    )
  ),
  dashboardBody(
    tabItems(
      tabItem(tabName = "tab",
              fluidRow(
                column(12, tabBox(
                  title = "",
                  id = "tabSet",
                  width = 12,
                  height = 500,
                  tabPanel("Bar1", plotlyOutput(outputId="bar_one")),
                  tabPanel("Bar2", plotlyOutput(outputId="bar_two"))
                )
                ),
                column(12,textOutput(outputId = "selection")))
      )
    )
  )
)

server <- function(input, output, session) 

  v <- reactiveValues()

  observe(
    d <- event_data("plotly_click",source="Bar1")
    if (length(d) == 0) species = as.vector(df_test$species[1])
    else species = as.character(d[4])
    v$click <- species
  )

  output$bar_one <- renderPlotly(
    p <- plot_ly(data = df_test, x = ~amount, y = ~species, type = 'bar', orientation = 'h', source = "Bar1")
  )

  output$bar_two <- renderPlotly(
    p <- plot_ly(data = df_test, x = ~amount, y = ~species, type = 'bar', orientation = 'h', source = "Bar1")
  )

  output$selection <- renderText(
    v$click
  )



shinyApp(ui, server)

【讨论】:

我要试试这个!谢谢 谢谢猪排,成功了!我什至没有想到您可以为多个绘图使用相同的来源,但这是有道理的。你有什么理由选择使用观察值和反应值而不仅仅是反应值? 我想我想让你在监控点击事件时有更大的灵活性,所以我使用了reactiveValues。而且我使用了观察,因为我不是 100% 两个情节如何反应,所以我想同时捕捉它

以上是关于如何在 Shiny 中跨选项卡持久化 event_data?的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中跨多个选项卡访问相同的视图模型

R Shiny:如何将数据表添加到动态创建的选项卡

Shiny 应用程序仅在一个选项卡中显示绘图。是啥原因?

是否可以在 2 个选项卡 [Shiny] 中使用相同的 actionButton?

基于选项卡面板选择在 R Shiny 中显示/隐藏 selectinput

在 R Shiny 中使用 ActionButton 跳转到选项卡项