rshinyr-dygraphs

R shiny dygraph not rendering


I have decided to change my basic plot() for a dygraph() but the dygraph isn't rendering (even though there is no error message). I have tested dygraphs in R shiny using the documentation and it worked. Could someone help me? Note that if you replace the dygraph at the end of my function with a basic plot(c(1,2),c(2,3)) the plot will render.

UI

library(dygraphs)

shinyUI(fluidPage(
    
    titlePanel("test"),
    
    sidebarLayout(
        sidebarPanel(
            actionButton("action","Go")
        ),
        mainPanel(
            dygraphOutput("dygraph")
        )
    )
))

Server

library(shiny)
library(quantmod)                            
library(PerformanceAnalytics)
library(plyr)
library(dygraphs)

shinyServer(function(input, output) {
    
    observeEvent(input$action, { 
        showModal(modalDialog("Loading... Please Wait", footer=NULL))
        output$dygraph <- renderDygraph({
                 RunPlot("MSFT",5,as.Date("2019-12-31"),as.Date("2020-12-31"),NULL,NULL,NULL)
            removeModal()
        })
    })
    
    #Define Function 
    RunPlot <- function(tickers, sharesVec, FromDate, ToDate, tickersREB, SharesVecREB, DateREB){
        
        PortfolioPrices <- NULL 
        for (i in tickers){
            PortfolioPrices <- cbind(PortfolioPrices, 
                                     getSymbols.yahoo(i, from = FromDate, to = ToDate,             
                                                      auto.assign = F)[,6])  
        }  
        
        for (j in 1:ncol(PortfolioPrices)){   
            
            if (is.na(PortfolioPrices[1,j]) == TRUE){
                NEWFROM <- FromDate-4
                TOFROM <- ToDate-1
                TempData <- getSymbols.yahoo(tickers[j], from = NEWFROM, to = TOFROM,             
                                             auto.assign = F)[,6]
                PortfolioPrices[1,j] <- TempData[nrow(TempData),1]
                
                for (i in 1:nrow(PortfolioPrices)){
                    if (is.na(PortfolioPrices[i,j]) == TRUE){
                        PortfolioPrices[i,j] <- PortfolioPrices[i-1,j]
                    }
                }
            }
        }
        
        TempValue <- PortfolioPrices[1,]
        MarketValue <- sharesVec*TempValue
        Weights <- MarketValue/sum(MarketValue) 
        
        #### REBALANCING START ###
        
        if (length(tickersREB)>0){
            
            #Initialize 
            TEMPDF <- data.frame(tickersREB, SharesVecREB, DateREB)
            WeightREB <- fortify.zoo(Weights)
            
            for (i in tickersREB){
                PortfolioPrices <- cbind(PortfolioPrices, 
                                         getSymbols.yahoo(i, from = FromDate, to = ToDate,             
                                                          auto.assign = F)[,6])  
                
                for (j in 1:nrow(TEMPDF)){
                    if (TEMPDF[j,1]==i){
                        DateUsed <- TEMPDF[j,3]
                        SharesUsed <- TEMPDF[j,2]
                    }
                }
                
                TempValue <- PortfolioPrices[DateUsed]
                sharesVec <- c(sharesVec,SharesUsed)
                MarketValue <- sharesVec*TempValue
                TempWeights <- MarketValue/sum(MarketValue) 
                
                TempWeights <- fortify.zoo(TempWeights) 
                WeightREB <- rbind.fill(WeightREB, TempWeights) 
                
            }
            
            WeightREB[is.na(WeightREB)] <- 0
            TimeXTS <- WeightREB[,1]
            WeightsXTS <- WeightREB[,2:ncol(WeightREB)]
            WeightREB <- xts(WeightsXTS,TimeXTS)
            
            Weights <- WeightREB
        }
        
        for (j in 1:ncol(PortfolioPrices)){   
            
            if (is.na(PortfolioPrices[1,j]) == TRUE){
                NEWFROM <- FromDate-4
                TOFROM <- ToDate-1
                TempData <- getSymbols.yahoo(tickers[j], from = NEWFROM, to = TOFROM,             
                                             auto.assign = F)[,6]
                PortfolioPrices[1,j] <- TempData[nrow(TempData),1]
                
                for (i in 1:nrow(PortfolioPrices)){
                    if (is.na(PortfolioPrices[i,j]) == TRUE){
                        PortfolioPrices[i,j] <- PortfolioPrices[i-1,j]
                    }
                }
            }
        }
        
        ### REBALANCING END ###
        
        Rf <- getQuote("^TNX", src = "yahoo")[1,2]/100
        AssetsReturns <- na.omit(ROC(PortfolioPrices, type = "discrete"))                                  
        PortfolioReturns <- Return.portfolio(AssetsReturns, weights = Weights)                             
        PortfolioAnnualizedReturns <- table.AnnualizedReturns(PortfolioReturns, scale = nrow(PortfolioReturns)/(as.numeric(format(ToDate,'%Y')) - as.numeric(format(FromDate,'%Y'))), Rf = Rf/(nrow(PortfolioReturns)/(as.numeric(format(ToDate,'%Y')) - as.numeric(format(FromDate,'%Y')))))                       
        colnames(PortfolioAnnualizedReturns) <- "Portfolio"
        
        SP500 <- getSymbols.yahoo("SPY", from = FromDate, to = ToDate, auto.assign = F)[,6]       
        SP500Returns <- na.omit(ROC(SP500, type = "discrete"))                                             
        SP500AnnualizedReturns <- table.AnnualizedReturns(SP500Returns, scale = nrow(SP500Returns)/(as.numeric(format(ToDate,'%Y')) - as.numeric(format(FromDate,'%Y'))), Rf = Rf/(nrow(SP500Returns)/(as.numeric(format(ToDate,'%Y')) - as.numeric(format(FromDate,'%Y'))))) 
        colnames(SP500AnnualizedReturns) <- "S&P500"
        
        SPTSX <- getSymbols.yahoo("XIC.TO", from = FromDate, to = ToDate, auto.assign = F)[,6]   
        SPTSXReturns <- na.omit(ROC(SPTSX, type = "discrete"))                                             
        SPTSXAnnualizedReturns <- table.AnnualizedReturns(SPTSXReturns, scale = nrow(SPTSXReturns)/(as.numeric(format(ToDate,'%Y')) - as.numeric(format(FromDate,'%Y'))), Rf = Rf/(nrow(SPTSXReturns)/(as.numeric(format(ToDate,'%Y')) - as.numeric(format(FromDate,'%Y')))))  
        colnames(SPTSXAnnualizedReturns) <- "S&P/TSX"
        
        MSCIIMI <- getSymbols.yahoo("XEF.TO", from = FromDate, to = ToDate, auto.assign = F)[,6]   
        MSCIIMIReturns <- na.omit(ROC(MSCIIMI, type = "discrete"))                                             
        MSCIIMIAnnualizedReturns <- table.AnnualizedReturns(MSCIIMIReturns, scale = nrow(MSCIIMIReturns)/(as.numeric(format(ToDate,'%Y')) - as.numeric(format(FromDate,'%Y'))), Rf = Rf/(nrow(MSCIIMIReturns)/(as.numeric(format(ToDate,'%Y')) - as.numeric(format(FromDate,'%Y'))))) 
        colnames(MSCIIMIAnnualizedReturns) <- "MSCI EAFE IMI"
        
        MSCIEME <- getSymbols.yahoo("XEC.TO", from = FromDate, to = ToDate, auto.assign = F)[,6]   
        MSCIEMEReturns <- na.omit(ROC(MSCIEME, type = "discrete"))                                             
        MSCIEMEAnnualizedReturns <- table.AnnualizedReturns(MSCIEMEReturns, scale = nrow(MSCIEMEReturns)/(as.numeric(format(ToDate,'%Y')) - as.numeric(format(FromDate,'%Y'))), Rf = Rf/(nrow(MSCIEMEReturns)/(as.numeric(format(ToDate,'%Y')) - as.numeric(format(FromDate,'%Y')))))  
        colnames(MSCIEMEAnnualizedReturns) <- "MSCI Emerging Markets"
        
        PortfolioCumReturns <- fortify.zoo(PortfolioReturns+1)                                             
        SP500CumReturns <- fortify.zoo(SP500Returns+1)
        SPTSXCumReturns <- fortify.zoo(SPTSXReturns+1)
        MSCIIMICumReturns <- fortify.zoo(MSCIIMIReturns+1)
        MSCIEMECumReturns <- fortify.zoo(MSCIEMEReturns+1)
        
        for (j in 2:nrow(PortfolioCumReturns)){                                                            
            PortfolioCumReturns[j,2] <- PortfolioCumReturns[j-1,2]*PortfolioCumReturns[j,2]
        }
        for (j in 2:nrow(SP500CumReturns)){
            SP500CumReturns[j,2] <- SP500CumReturns[j-1,2]*SP500CumReturns[j,2]
        }
        for (j in 2:nrow(SPTSXCumReturns)){
            SPTSXCumReturns[j,2] <- SPTSXCumReturns[j-1,2]*SPTSXCumReturns[j,2]
        }
        for (j in 2:nrow(MSCIIMICumReturns)){
            MSCIIMICumReturns[j,2] <- MSCIIMICumReturns[j-1,2]*MSCIIMICumReturns[j,2]
        }
        for (j in 2:nrow(MSCIEMECumReturns)){
            MSCIEMECumReturns[j,2] <- MSCIEMECumReturns[j-1,2]*MSCIEMECumReturns[j,2]
        }
        
        PortfolioCumReturns <- PortfolioCumReturns - 1                                                      
        SP500CumReturns <- SP500CumReturns - 1
        SPTSXCumReturns <- SPTSXCumReturns - 1
        MSCIIMICumReturns <- MSCIIMICumReturns - 1
        MSCIEMECumReturns <- MSCIEMECumReturns - 1
        
        ReturnsTABLE <- cbind(PortfolioAnnualizedReturns,SP500AnnualizedReturns,SPTSXAnnualizedReturns,MSCIIMIAnnualizedReturns,MSCIEMEAnnualizedReturns)
        
        Benchmark <- getSymbols.yahoo("^GSPC", from = FromDate, to = ToDate, auto.assign = F)[,6]   
        BenchmarkReturns <- na.omit(ROC(Benchmark, type = "discrete"))  
        BETA <- CAPM.beta(PortfolioReturns, BenchmarkReturns, Rf/(nrow(BenchmarkReturns)/(as.numeric(format(ToDate,'%Y')) - as.numeric(format(FromDate,'%Y')))))
        ALPHA <- CAPM.jensenAlpha(PortfolioReturns, BenchmarkReturns, Rf/(nrow(BenchmarkReturns)/(as.numeric(format(ToDate,'%Y')) - as.numeric(format(FromDate,'%Y')))))
        
        #Interactive Plot
        #Portfolio
        PCR1 <- PortfolioCumReturns[,1]
        PCR2 <- PortfolioCumReturns[,2]
        PortfolioCumReturns <- xts(PCR2,PCR1)
        colnames(PortfolioCumReturns) <- "Portfolio"
        
        #S&P500
        SP1 <- SP500CumReturns[,1]
        SP2 <- SP500CumReturns[,2]
        SP500CumReturns <- xts(SP2,SP1)
        colnames(SP500CumReturns) <- "S&P500"
        
        #S&P/TSX
        TSX1 <- SPTSXCumReturns[,1]
        TSX2 <- SPTSXCumReturns[,2]
        SPTSXCumReturns <- xts(TSX2,TSX1)
        colnames(SPTSXCumReturns) <- "S&P/TSX"
        
        #MSCI EAFE IMI
        IMI1 <- MSCIIMICumReturns[,1]
        IMI2 <- MSCIIMICumReturns[,2]
        MSCIIMICumReturns <- xts(IMI2,IMI1)
        colnames(MSCIIMICumReturns) <- "MSCI EAFE IMI"
        
        #MSCI Emerging Markets
        EME1 <- MSCIEMECumReturns[,1]
        EME2 <- MSCIEMECumReturns[,2]
        MSCIEMECumReturns <- xts(EME2,EME1)
        colnames(MSCIEMECumReturns) <- "MSCI Emerging Markets"
        
        NEW <- cbind(PortfolioCumReturns,SP500CumReturns,SPTSXCumReturns,MSCIIMICumReturns,MSCIEMECumReturns)
        
        #Hotfix bug (365TD vs 252TD)
        if (is.na(NEW[1,2]) == TRUE){
            NEW <- NEW[-1,]
        }
        if (is.na(NEW[1,2]) == TRUE){
            NEW <- NEW[-1,]
        }
        if (is.na(NEW[1,2]) == TRUE){
            NEW <- NEW[-1,]
        }
        
        #Delete NAs
        for (j in 1:ncol(NEW)){   
            
            for (i in 1:nrow(NEW)){
                if (is.na(NEW[i,j]) == TRUE){
                    NEW[i,j] <- NEW[i-1,j]
                }
            }
        }
        
        #Output
        dygraph(NEW, xlab = "Time", ylab = "Returns",main = "Performance Overview") %>%
            dyRangeSelector() %>%
            dyOptions(colors = c("Navy","dodgerblue4","steelblue","lightblue","lightsteelblue")) %>%
            dyLegend(width = 450)
    }
})

Solution

  • The error here is because removeModal() is the last expression of the renderDygraph() block, so it's return in interpreted as the plot while it's the return of RunPlot(...) that contains the plot:

        output$dygraph <- renderDygraph({
          RunPlot("MSFT",5,as.Date("2019-12-31"),as.Date("2020-12-31"),NULL,NULL,NULL)
          removeModal()
        })
    

    Just put the removeModal() after the block fixes the issue

        output$dygraph <- renderDygraph({
          RunPlot("MSFT",5,as.Date("2019-12-31"),as.Date("2020-12-31"),NULL,NULL,NULL)
        })
        removeModal()