【问题标题】:Error in plotly graph download from a shiny app when using javascript使用 javascript 时从闪亮的应用程序下载绘图时出错
【发布时间】:2019-02-08 13:46:29
【问题描述】:

我在下面有一个闪亮的应用程序,它显示了一个绘图或一个表格。我对表格不感兴趣,我的 Q 只与情节部分有关。当我使用javascript solution 在浏览器中打开应用程序时,我正在尝试下载绘图。我不熟悉javascript,我想知道当我第一次按下“下载”按钮并只下载我根本没有下载的情节时,如何防止它下载这个空文件。

library(shiny)
library(plotly)

d <- data.frame(X1 = rnorm(50,mean=50,sd=10), 
                X2 = rnorm(50,mean=5,sd=1.5), 
                Y = rnorm(50,mean=200,sd=25))

ui <-fluidPage(
  title = 'Download Plotly',
  sidebarLayout(

    sidebarPanel(
      selectInput("S","SELECT",choices = c("Table","Plot"),selected = "Plot"),
      uiOutput('down'),
      tags$script('
              document.getElementById("down").onclick = function() {
                  var gd = document.getElementById("regPlot");
                  Plotly.Snapshot.toImage(gd, {format: "png"}).once("success", function(url) {
                  var a = window.document.createElement("a");
                  a.href = url; 
                  a.type = "image/png";
                  a.download = "plot.png";
                  document.body.appendChild(a);
                  a.click();
                  document.body.removeChild(a);                      
                  });
                  }
                  ')
    ),

    mainPanel(
      uiOutput('regPlot')

    )
  )
)

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

output$down<-renderUI({
  if(input$S=="Table"){

      output$downloadData <- downloadHandler(
        filename = function() {
          paste(input$filename, input$extension, sep = ".")
        },

        # This function writes data to a file given to it by the argument 'file'.
        content = function(file) {
          sep <- "txt"=","
          # Write to a file specified by the 'file' argument
          write.table(data.frame(mtcars), file, sep = sep,
                      row.names = FALSE)
        }

      )
      downloadButton("downloadData", "Download",class = "butt1")
  }
  else{
    output$downloadData <- downloadHandler(
      filename = function(){
        paste(paste("test",Sys.Date(),sep=""), ".png",sep="")},
      content = function(file) {
        temp_dir <- tempdir()
        tempImage <- file.path(temp_dir, 'out.png')
        file.copy('out.png', tempImage, overwrite = TRUE)
        png(file, width = 1200, height = 800, units = "px", pointsize = 12, bg = "white", res = NA)
        dev.off()
      })
    downloadButton("downloadData", "Download",class = "butt1")
  }
})  

output$regPlot<-renderUI({
  if(input$S=="Plot"){
    output$pl<-renderPlotly(
    plot_ly(d, x = d$X1, y = d$X2, mode = "markers"))
    plotlyOutput("pl")
  }
  else{
    output$tbl =  DT::renderDataTable(datatable(
      d
    ))
    dataTableOutput("tbl") 
  }
  })

}

shinyApp(ui = ui, server = server)

【问题讨论】:

    标签: javascript r download shiny plotly


    【解决方案1】:

    这是下载情节的代码。代码问题很少,

    在 ui.R 中定义下载按钮。并参考javascript代码中的下载按钮id。此外,regplotuiOutput 元素,而不是实际情节。在 javascript 代码中,该图由 pl 引用。

    这是修复了问题的示例代码。如果您使用 javascript 代码,则不需要闪亮的下载处理程序。如下所示,您可以在其中简单地从操作按钮下载。

    您可以在此基础上通过将 actionButton 替换为 downloadButton 并在服务器上添加相应代码来下载数据表。

    library(shiny)
    library(plotly)
    library(DT)
    
    ui <-fluidPage(
      title = 'Download Plotly',
      sidebarLayout(
    
        sidebarPanel(
          selectInput("S","SELECT",choices = c("Table","Plot"),selected = "Plot"),
          actionButton("downloadData", "Download",class = "butt1"),
          tags$script('
                      document.getElementById("downloadData").onclick = function() {
                      var gd = document.getElementById("pl");
                      Plotly.Snapshot.toImage(gd, {format: "png"}).once("success", function(url) {
                      var a = window.document.createElement("a");
                      a.href = url; 
                      a.type = "image/png";
                      a.download = "plot.png";
                      document.body.appendChild(a);
                      a.click();
                      document.body.removeChild(a);                      
                      });
                      }
                      ')
          ),
    
        mainPanel(
          uiOutput('regPlot')
    
        )
          )
        )
    
    server <- function(input, output, session) {
    
      d <- data.frame(X1 = rnorm(50,mean=50,sd=10), 
                      X2 = rnorm(50,mean=5,sd=1.5), 
                      Y = rnorm(50,mean=200,sd=25))
    
      output$regPlot<-renderUI({
        if(input$S=="Plot"){
          output$pl<-renderPlotly(
            plot_ly(d, x = d$X1, y = d$X2, mode = "markers"))
          plotlyOutput("pl")
        }
        else{
          output$tbl =  DT::renderDataTable(datatable(
            d
          ))
          dataTableOutput("tbl") 
        }
      })
    }
    
    shinyApp(ui = ui, server = server)
    

    【讨论】:

    • 因为我不希望这个动作按钮是永久性的,所以我想把它放在 uiOutput 中并在服务器中创建它。但是当我在服务器中添加 javascript 代码时,actionbutton 会丢失。
    • 这不能在没有 javascript 和使用下载处理程序的情况下实现吗?我在这里有一个问题stackoverflow.com/questions/54586780/…
    • 感谢我调整并做到了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-24
    • 2020-08-07
    • 2022-01-08
    • 2018-05-15
    • 2017-02-19
    • 1970-01-01
    相关资源
    最近更新 更多