Reputation: 12905
I'm trying to recreate https://gist.github.com/wch/5436415/ but by adding plots through a button. I think this needs me to modify the server.r
code on the link along these lines (the chartname related variable are created through reactiveValues
) -
observeEvent(
input$buttonAddData,
{
...
newchartname = c(newchartname,newchartname)
output[[newchartname]] = renderPlot({
...
})
}
)
output$plots = renderUI(
{
plot_output_list <- lapply(
seq(length(allthechartnames)),
function(i) {
plotname <- paste(
isolate(allthechartnames)[i]
)
plotOutput(plotname, height = 280, width = 250)
cat(plotname,'\n')
}
)
# Convert the list to a tagList - this is necessary for the list of items
# to display properly.
do.call(tagList, plot_output_list)
}
)
But this seems to not enter the original loop of creating the chart itself inside the observeEvent which results in no charts inside the renderUI block.
Any tips?
Upvotes: 3
Views: 7531
Reputation: 26363
I don't really understand the code in your question so I kind of ignored it and just took Winston's code from the gist and made it work with a button instead of a slider. I hope this is what you meant? Also, I did have to use render inside an observer which I'm not happy about :/
runApp(shinyApp(
ui = fluidPage(
headerPanel("Dynamic number of plots"),
mainPanel(
actionButton("addplot", "Add plot"),
uiOutput("plots")
)
),
server = function(input, output, session) {
# A variable that keeps track of the number of plots we have
values <- reactiveValues(
numPlots = 1
)
# Whenever the "add plot" button is pressed, increment num plots by 1
observeEvent(input$addplot, {
values$numPlots <- values$numPlots + 1
})
# Dynamically generate the UI that creates all the plots
output$plots <- renderUI({
# Create a list of `plotOutput` objects (for each plot, use a unique ID)
plot_output_list <- lapply(1:values$numPlots, function(i) {
plotname <- paste("plot", i, sep="")
plotOutput(plotname, height = 280, width = 250)
})
# Place all the plot outputs inside a shiny `tagList()`
do.call(tagList, plot_output_list)
})
# Every time the number of plots changes (button is clicked),
# re-generate the render functions for all the plots
observeEvent(values$numPlots, {
for (i in 1:values$numPlots) {
local({
my_i <- i
plotname <- paste("plot", my_i, sep="")
output[[plotname]] <- renderPlot({
plot(1:my_i, 1:my_i,
xlim = c(1, values$numPlots),
ylim = c(1, values$numPlots),
main = paste("1:", my_i, ". n is ", values$numPlots, sep = "")
)
})
})
}
})
}
))
Hope that helps
Upvotes: 8