在非焦点选项卡上绘制背景中反应值变化的ggplot

时间:2018-06-05 23:23:16

标签: r ggplot2 shiny shinydashboard

目标

通过减少等待时间来增加UX流动性。

问题

我正在构建数据探索仪表板。有两个选项卡:1)(默认选项卡)显示数据表的选项卡,以及2)显示ggplots的选项卡。用户可以通过从侧栏选择选项来浏览数据(例如,选择要显示的点数)。该表会根据更改进行反应性更新,但另一个选项卡上的ggplot不会 - 直到选中该选项卡, 才会绘制ggplot

这很烦人,因为已经指定了数据,但是在用户点击绘图选项卡之前,流程才会启动...因此浪费时间在大型数据集上。

我尝试了什么

我试着查看SO和google以了解此问题的提示,但我一定不能正确搜索,因为这似乎是一个简单的问题。我已经考虑过实现一个函数,在指定一个值来强制绘制之后,它会在一瞬间切换到每个非焦点选项卡,但这对于这样一个小问题来说是非常友好且非常难以理解的。

MCVE

# Load libraries
library(shiny)
library(shinydashboard)
library(DT)
library(ggplot2)
library(ggthemes)

# Set seed to arbitrary value for reproducibility
set.seed(1)

# Create random dataset of 100K points
test.df <- data.frame(a = 1:100000, b = rnorm(n = 100000, mean= 2, sd=1))

# Create ui
ui <- dashboardPage(dashboardHeader(),
                    dashboardSidebar(
                      sidebarMenu(
                        id = "tabs",
                        # Tab to show table
                        menuItem("Tab 1", tabName = "item1"),
                        # Tab to show plot
                        menuItem("Tab 1", tabName = "item2"),
                        numericInput("numeric", "Length of data", value = 1)
                    )),
                    dashboardBody(
                      tabItems(
                        tabItem("item1", dataTableOutput("table")),
                        tabItem("item2", plotOutput("plot"))
                      )
                    )
                  )

server <- function(input, output) {

  # Get first n rows
  test.df.sample <- reactive({
    head(test.df, n=input$numeric)
  })

  # Render table
  output$table <- DT::renderDataTable({
    datatable(test.df.sample())
  })

  # Render ggplot
  output$plot <-  renderPlot({
    ggplot(test.df.sample()) +
      geom_point(aes(x=a, y=b)) +
      theme_tufte()
  })
}

shinyApp(ui = ui, server = server)

进度更新

更新1 - 过帐日期+ 2

在时间的压力下,我决定实施hacky方法,使updateTabItems()调用瞬间在标签之间切换。此方法有效,因为它触发闪亮以更新每个tabItem内容但留下不需要的视觉效果(例如,我使用googleway绘制地图,但它会以最大级别缩小,因此您会看到重复世界地图的条带4次,如果它在这个hacky方法中得到更新)

1 个答案:

答案 0 :(得分:2)

我认为您可以使用outputOptions中的suspendWhenHidden选项来获取您要查找的行为。但是,这本身并不足够,因为要使其工作,用户必须通过转到第二个选项卡来初始化一次。我们可以通过将绘图的高度和宽度设置为非零值来解决此问题,请参阅here

请注意,现在表格只在表格和绘图完成渲染后才会渲染,因此需要更长时间。因此,用户必须等待60秒而不是等待10秒六次。新行为的优点在于,至少用户可以喝一杯咖啡,并且知道当他回来时一切都准备就绪。我希望这是你想要的行为。如果你的目标是按顺序呈现所有内容 - 我不确定这是否可能与Shiny我害怕......

下面给出了一个工作示例,希望这有帮助!

# Load libraries
library(shiny)
library(shinydashboard)
library(DT)
library(ggplot2)
library(ggthemes)

# Set seed to arbitrary value for reproducibility
set.seed(1)

# Create random dataset of 100K points
test.df <- data.frame(a = 1:100000, b = rnorm(n = 100000, mean= 2, sd=1))

# Create ui
ui <- dashboardPage(dashboardHeader(),
                    dashboardSidebar(
                      sidebarMenu(
                        id = "tabs",
                        # Tab to show table
                        menuItem("Tab 1", tabName = "item1"),
                        # Tab to show plot
                        menuItem("Tab 1", tabName = "item2"),
                        numericInput("numeric", "Length of data", value = 1)
                      )),
                    dashboardBody(
                      tabItems(
                        tabItem("item1", dataTableOutput("table")),
                        tabItem("item2", plotOutput("plot"))
                      )
                    )
)

server <- function(input, output) {

  # Get first n rows
  test.df.sample <- reactive({
    head(test.df, n=input$numeric)
  })

  # Render table
  output$table <- DT::renderDataTable({
    datatable(test.df.sample())
  })

  # Render ggplot
  output$plot <-  renderPlot({
    ggplot(test.df.sample()) +
      geom_point(aes(x=a, y=b))
    }, height = 450, width = 800)
  outputOptions(output, "plot", suspendWhenHidden = FALSE)
}

shinyApp(ui = ui, server = server)