Shiny应用单运行按钮生成多图表及一键清空功能实现咨询
实现方案
1. 核心逻辑说明
- 单个运行按钮触发所有计算:通过
eventReactive将所有图表对应的数据源计算逻辑绑定到运行按钮,所有输出自动响应按钮点击事件 - 清空按钮功能:通过
update*系列函数重置所有输入组件,同时清空所有输出内容 - 下载功能:为每个图表配置独立的图片、数据下载按钮,通过
downloadHandler实现导出
2. 完整修改代码
2.1 调整绘图函数
首先修改plotinput函数,使其同时返回绘图所用的数值矩阵,方便后续导出CSV:
plotinput <- function(P){ PG <- as.matrix(P) A = PG[1,]; B = PG[2,]; C = PG[3,] Z = matrix(0,LDR,LRP) for (j in 1:LRP) { for (i in 1:LDR) { if (C[i] != 0) { Z[i,j] = A[i] +((B[i]/C[i])*(((-log(1-(1/RP[j])))^-C[i])-1)) } else { Z[i,j] = A[i] +((B[i])*(-log(-log(1-(1/RP[j]))))) } } } col_set <- rainbow(nrow(Z)) matplot(Z,type = "o", lty = "solid", lwd = 2, xlab = "Duration (hr)",ylab = "Intensity (mm/hr)", col = col_set, cex.lab = 1.5, cex.axis=1.5, cex.main=1.5, cex.sub=1.5, pch = 21, xaxt='n') # 返回数值矩阵用于导出 return(invisible(Z)) }
2.2 修改UI部分
在数据导入页添加运行/清空按钮,每个图表页添加下载按钮:
library(shiny) library(shinydashboard) ui <- dashboardPage(dashboardHeader(title = "IDF"), dashboardSidebar( sidebarMenu( menuItem("Data", tabName = "dataimport"), menuItem("Stationary IDF", tabName = "Stidf"), menuItem("Non-stationary IDF", tabName = "NStidf"), menuItem("IDF under climate change", tabName = "Gcmidf"))), dashboardBody( tabItems( tabItem(tabName = "dataimport", fileInput("file","Hourly precipitation data(.csv format)",accept = ".csv"), checkboxInput("header", "Header", TRUE), radioButtons('UserCov',"Mention if there is a local covariate to be added, if Yes add the file", choices = list("No" = 1,"Yes" = 2), inline = T), fileInput("cov","Local covariate data(.csv format)",accept = ".csv"), checkboxInput("head", "Header", TRUE), numericInput("lat","Latitude", value = c()), numericInput("lon","Longitude", value = c()), radioButtons('gcm', "Select the GCM", choices = list("MPI" = 1,"MRI" = 2,"CNRM"=3,"EC" =4,"MIR"=5), inline = T), sliderInput("fut", label = h4("Select the starting point of time period"),min = 2015, max = 2100, value = 2020), # 新增运行和清空按钮 br(), actionButton("run_btn", "生成所有图表", icon = icon("play"), style = "background: #00a65a; color: white; margin-right: 10px;"), actionButton("reset_btn", "重置所有内容", icon = icon("refresh"), style = "background: #dd4b39; color: white;") ), tabItem(tabName = "Stidf", # 新增下载按钮 downloadButton("dl_SIDF_plot", "下载图表", style = "margin-bottom: 10px; margin-right: 10px;"), downloadButton("dl_SIDF_data", "下载CSV数据", style = "margin-bottom: 10px;"), plotOutput('SIDF')), tabItem(tabName = "NStidf", downloadButton("dl_NIDF_plot", "下载图表", style = "margin-bottom: 10px; margin-right: 10px;"), downloadButton("dl_NIDF_data", "下载CSV数据", style = "margin-bottom: 10px;"), plotOutput('NIDF')), tabItem(tabName = "Gcmidf", tabsetPanel(type = "tabs", tabPanel("s1", downloadButton("dl_p1_plot", "下载图表", style = "margin-bottom: 10px; margin-right: 10px;"), downloadButton("dl_p1_data", "下载CSV数据", style = "margin-bottom: 10px;"), plotOutput('plot1')), tabPanel("s2", downloadButton("dl_p2_plot", "下载图表", style = "margin-bottom: 10px; margin-right: 10px;"), downloadButton("dl_p2_data", "下载CSV数据", style = "margin-bottom: 10px;"), plotOutput('plot2')), tabPanel("s3", downloadButton("dl_p3_plot", "下载图表", style = "margin-bottom: 10px; margin-right: 10px;"), downloadButton("dl_p3_data", "下载CSV数据", style = "margin-bottom: 10px;"), plotOutput('plot3')), tabPanel("s5", downloadButton("dl_p4_plot", "下载图表", style = "margin-bottom: 10px; margin-right: 10px;"), downloadButton("dl_p4_data", "下载CSV数据", style = "margin-bottom: 10px;"), plotOutput('plot4')))) )))
2.3 修改Server部分
绑定按钮事件,添加下载逻辑:
server <- function(input, output,session) { # --------------- 运行按钮绑定所有数据源计算 --------------- # 你原有逻辑中的plotSt、plotNSt、PCC1-PCC4都改为eventReactive绑定运行按钮 # 示例(替换为你原有计算逻辑即可): plotSt <- eventReactive(input$run_btn, { # 此处放你原本plotSt()的计算逻辑 req(input$file) # 原有逻辑保留 }) plotNSt <- eventReactive(input$run_btn, { # 此处放你原本plotNSt()的计算逻辑 req(input$file) # 原有逻辑保留 }) PCC1 <- eventReactive(input$run_btn, { # 此处放你原本PCC1()的计算逻辑 req(input$file, input$gcm) # 原有逻辑保留 }) PCC2 <- eventReactive(input$run_btn, { # 此处放你原本PCC2()的计算逻辑 req(input$file, input$gcm) # 原有逻辑保留 }) PCC3 <- eventReactive(input$run_btn, { # 此处放你原本PCC3()的计算逻辑 req(input$file, input$gcm) # 原有逻辑保留 }) PCC4 <- eventReactive(input$run_btn, { # 此处放你原本PCC4()的计算逻辑 req(input$file, input$gcm) # 原有逻辑保留 }) # --------------- 图表渲染逻辑保留,自动响应运行按钮 --------------- output$SIDF <- renderPlot({ req(plotSt()) # 保存绘图返回的数值矩阵用于导出 sidf_data <<- plotinput(plotSt()) }) output$NIDF <- renderPlot({ req(plotNSt()) nidf_data <<- plotinput(plotNSt()) }) output$plot1 <- renderPlot({ req(PCC1()) p1_data <<- plotinput(PCC1()) }) output$plot2 <- renderPlot({ req(PCC2()) p2_data <<- plotinput(PCC2()) }) output$plot3 <- renderPlot({ req(PCC3()) p3_data <<- plotinput(PCC3()) }) output$plot4 <- renderPlot({ req(PCC4()) p4_data <<- plotinput(PCC4()) }) # --------------- 下载逻辑 --------------- # SIDF下载 output$dl_SIDF_plot <- downloadHandler( filename = function() {paste0("固定IDF曲线_", Sys.Date(), ".png")}, content = function(file) { png(file, width = 10, height = 8, res = 300, units = "in") plotinput(plotSt()) dev.off() } ) output$dl_SIDF_data <- downloadHandler( filename = function() {paste0("固定IDF数据_", Sys.Date(), ".csv")}, content = function(file) { write.csv(sidf_data, file, row.names = FALSE, fileEncoding = "GBK") } ) # 剩余5个图表的下载逻辑和上面完全一致,替换对应的变量名和文件名即可,示例省略 # --------------- 清空按钮逻辑 --------------- observeEvent(input$reset_btn, { # 重置所有输入项 updateFileInput(session, "file", value = NULL) updateCheckboxInput(session, "header", value = TRUE) updateRadioButtons(session, "UserCov", selected = 1) updateFileInput(session, "cov", value = NULL) updateCheckboxInput(session, "head", value = TRUE) updateNumericInput(session, "lat", value = NA) updateNumericInput(session, "lon", value = NA) updateRadioButtons(session, "gcm", selected = 1) updateSliderInput(session, "fut", value = 2020) # 清空所有输出 output$SIDF <- renderPlot({NULL}) output$NIDF <- renderPlot({NULL}) output$plot1 <- renderPlot({NULL}) output$plot2 <- renderPlot({NULL}) output$plot3 <- renderPlot({NULL}) output$plot4 <- renderPlot({NULL}) # 清空缓存的数据 rm(list = c("sidf_data", "nidf_data", "p1_data", "p2_data", "p3_data", "p4_data"), envir = .GlobalEnv) }) } shinyApp(ui, server)
3. 注意事项
- 原代码中使用的
LRP、LDR、RP变量需要确保在应用运行环境中可访问,若为局部定义请调整作用域或作为参数传入plotinput函数 - 剩余5个图表的下载逻辑参考已给出的SIDF下载代码替换对应变量即可,无需额外修改逻辑
- 若需要导出PDF格式的图表,仅需将下载图片的
png()函数替换为pdf(),同时修改文件名后缀即可
内容的提问来源于stack exchange,提问作者Vishnupriya
相关产品推荐
相关产品推荐

