Search code examples
rshinyquantmodshiny-reactivityr-dygraphs

R Shiny reactive and new.env() - select group of stock symbols to get data and plot multiple dygraphs


I am trying to render multiple dygraphs using eapply. The data of the corresponding symbols comes via quantmod::getsymbols. The symbols (or varying groups of symbols) should be selectable via selectInput.

Unfortunately, I can't get the graph to update after selecting the selectInput. Does anyone here have an idea how this should be handled?

I would be grateful for any advice!

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


# just for illustration purpose, the symbols may vary and the number of select values may vary. The point is, that the input to the getsymbols function are multiple tickers, that can change

sym_bols1 <- c("TSLA", "EEM", "UBS")
sym_bols2 <- c("AAPL", "MSFT")


ui <- fluidPage(
  
  fluidPage(    
    titlePanel("Multiple Tickers"),
    
    sidebarLayout(
      sidebarPanel(selectInput("symbl", "Symbolliste", c("sym_bols1", "sym_bols2"))),

      mainPanel(uiOutput("ui"))
    )
  )
)


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

  data_env <- new.env(
    observe({
      quantmod::getSymbols(get(input$symbl),  from="2023-01-01", env=data_env)
    })
  )
  

  observe({
    
    dy_graph <- eapply(data_env, function(x_ts) {
      dygraphs::renderDygraph(dygraph(x_ts[, 1:4], group="multi",
                                      width=600, height=400))
    })
    
    output$ui <- renderUI(dy_graph)
  }, env=data_env)
}


shinyApp(ui = ui, server = server)


Solution

  • Here is a way:

    library(shiny)
    library(dygraphs)
    library(quantmod)
    
    
    # just for illustration purpose, the symbols may vary and the number of select values may vary. The point is, that the input to the getsymbols function are multiple tickers, that can change
    
    sym_bols1 <- c("TSLA", "EEM", "UBS")
    sym_bols2 <- c("AAPL", "MSFT")
    
    
    ui <- fluidPage(
      
      fluidPage(    
        titlePanel("Multiple Tickers"),
        
        sidebarLayout(
          sidebarPanel(selectInput("symbl", "Symbolliste", c("sym_bols1", "sym_bols2"))),
          
          mainPanel(uiOutput("ui"))
        )
      )
    )
    
    
    server <- function(input, output, session) {
      
      # reactive environment
      DataEnv <- reactive({
        data_env <- new.env()
        quantmod::getSymbols(get(input$symbl), from = "2023-01-01", env = data_env)
        data_env
      })
      
      Dygraphs <- reactive({
        eapply(DataEnv(), function(x_ts) {
          renderDygraph(dygraph(x_ts[, 1:4], group = "multi",
                                width = 600, height = 400))
        })
      })
      
      output$ui <- renderUI(do.call(tagList, Dygraphs()))
    
    }
    
    
    shinyApp(ui = ui, server = server)
    

    But the graphs are close to each other. You can separate them by using

      Dygraphs <- reactive({
        eapply(DataEnv(), function(x_ts) {
          tags$div(
            style = "margin-bottom: 60px;",
            renderDygraph({
              dygraph(
                x_ts[, 1:4], group = "multi", width = 600, height = 400
              )
            })
          )
        })
      })