在Shiny

时间:2017-08-01 15:46:10

标签: r shiny dygraphs

我正在构建一个Shiny应用程序,我希望使用dyRangeSelector中的dygraphs来提供输入周期。

我的问题是,我只希望在选择器收到“MouseUp”事件时触发响应式更改,即,当用户完成并选择周期时。现在,当移动选择器时调度事件,这导致应用程序滞后,因为每个周期的计算完成需要几秒钟。基本上,Shiny在这里对我的品味反应(我知道这是错误的方式 - 通常我们希望应用程序具有超级反应性。)

我可以修改何时发送被动请求?

这是一个显示问题的小例子。

library(quantmod)
library(shiny)
library(dygraphs)
library(magrittr)

# Create simple user interface
ui <- shinyUI(fluidPage(

    sidebarLayout(
    sidebarPanel(
            dygraphOutput("dygraph")
            ),    
    mainPanel(
            plotOutput("complicatedPlot")
            )
    )
))

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

    ## Read the data once.                                                                                       
    dataInput <- reactive({
    getSymbols("NASDAQ:GOOG", src = "google",
                   from = "2017-01-01",
                   auto.assign = FALSE)
    })

    ## Extract the from and to from the selector    
    values <- reactiveValues()    

    observe({
        if (!is.null(input$dygraph_date_window)) {
            rangewindow <- strftime(input$dygraph_date_window[[1]], "%Y-%m-%d")
            from <- rangewindow[1]
            to <- rangewindow[2]
        } else {
            from <- "2017-02-01"
            to <- Sys.Date()+1
        }
        values[["from"]] <- from
        values[["to"]] <- to
    })

    ## Render the range selector    
    output$dygraph <- renderDygraph({
        dygraph(dataInput()[,4]) %>% dyRangeSelector() %>% dyOptions(retainDateWindow = TRUE)
    })

    ## Render the "complicated" plot
    output$complicatedPlot <- renderPlot({
        plot(1,1)
        text(1,1, values[["from"]])
        Sys.sleep(1) ## Inserted to represent computing time
    })
})

## run app                                                                                                                                                                                                                         
runApp(list(ui=ui, server=server))

1 个答案:

答案 0 :(得分:5)

闪亮的名为debounce的功能可能非常适合您的需求。如果重写了反应式表达式的限制(而不是观察),则可以将其包含在debounce中,并在评估之前等待时间(以毫秒为单位)。这是一个1000ms的例子:

library(quantmod)
library(shiny)
library(dygraphs)
library(magrittr)

# Create simple user interface
ui <- shinyUI(fluidPage(

  sidebarLayout(
    sidebarPanel(
      dygraphOutput("dygraph")
    ),    
    mainPanel(
      plotOutput("complicatedPlot")
    )
  )
))

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

  ## Read the data once.                                                                                       
  dataInput <- reactive({
    getSymbols("NASDAQ:GOOG", src = "google",
               from = "2017-01-01",
               auto.assign = FALSE)
  })

  ## Extract the from and to from the selector    
  values <- reactiveValues()    

  limits <- debounce(reactive({
    if (!is.null(input$dygraph_date_window)) {
      rangewindow <- strftime(input$dygraph_date_window[[1]], "%Y-%m-%d")
      from <- rangewindow[1]
      to <- rangewindow[2]
    } else {
      from <- "2017-02-01"
      to <- Sys.Date()+1
    }
    list(from = from,
         to = to)
  }), 1000)

  ## Render the range selector    
  output$dygraph <- renderDygraph({
    dygraph(dataInput()[,4]) %>% dyRangeSelector() %>% dyOptions(retainDateWindow = TRUE)
  })

  ## Render the "complicated" plot
  output$complicatedPlot <- renderPlot({
    plot(1,1)
    text(1,1, limits()[["from"]])
    Sys.sleep(1) ## Inserted to represent computing time
  })
})

## run app                                                                                                                                                                                                                         
runApp(list(ui=ui, server=server))

这基本上意味着反应式表达式必须返回相同的值,至少1s才能发送到其依赖项。你可以试试最佳时间。