Yes. This way is complicated but it allows the user to add new symbols from the web browser. Let's say you can have a textInput called "symbol" and an actionButton called "addSymbol". Then you could have something like this in server.R:
shinyServer(function(input, output) {
# Include the make_chart code, etc...
values <- reactiveValues()
values$stocks <- character(0)
observe({
if (input$addSymbol == 0)
return()
isolate({
if (!(input$symbol %in% values$stocks)) {
values$stocks <- c(values$stocks, input$symbol)
output[[paste0('plot_', input$symbol)]] <- renderPlot({ make_chart(input$symbol) })
}
})
})
output$plots <- renderUI({
lapply(values$stocks, function(symbol) {
list(
br(),
div(plotOutput(outputId = paste0('plot_', symbol)))
)
})
})
})
Then in ui.R you'd have to replace the contents of mainPanel with "uiOutput('plots')".
The observe/check-for-zero/isolate sequence probably looks strange, but it's a Shiny idiom that is used for responding to a button click. (We should wrap it up as a friendlier function, like handleButtonClick)
There are also examples of passing datasets or whatever in from the R console, here's an example:
If you execute that code, then run explore(df) where df is a dataframe of your choice, you'll see what I mean.