简体   繁体   中英

Download plot using jqui_resizable in R shiny

Sorry for my poor English, I am not a native speaker.

I want to make download button that can download plot resized by jqui_resizable package. 在此处输入图像描述

I read these URLs for make this. download a plot without replotting in R shiny Shiny.setInputValue only works on the 2nd try

But I have a problem. Like the second URL above, Shiny.setinputvalue only updates the value on the second run.

This is minimum sample code. Can someone please modify this code so that the image can be downloaded on the first click? Or could you please share some information that could help us solve this problem? Thank you in advance.

library(shiny)
library(shinyjqui)
library(magick)
library(xfun)

js <- 'function get_img_src(){
    var src = document.getElementById("myPlot").childNodes[0].src;
    Shiny.setInputValue("img_src", src);
    }'

ui <- fluidPage(
  downloadButton("save_myPlot",onclick="get_img_src();"),
  # plot
  jqui_resizable(plotOutput("myPlot")),
  tags$script(HTML(js))
)

server <- function(input, output, session) {
  
  # downaload handler - save the image
  output$save_myPlot <- downloadHandler(
    filename = function() { 
      paste0("plot_", Sys.Date(), ".png") },
    content = function(file) {
      # get image code from URI
      img_src <- gsub("data:.+base64,", "", input$img_src)
      # decode the image code into the image
      img_src <- image_read(base64_decode(img_src))
      # save the image
      image_write(img_src, file)
    })
  
  # plot
  output$myPlot <- renderPlot(
    plot(rnorm(5), rnorm(5))
  )
}

shinyApp(ui = ui, server = server)

=======================================

(Editted) This problem does not seem to occur in Windows & Chrome environments.
This is my sessionInfo.

R version 4.0.2 (2020-06-22) Platform: x86_64-pc-linux-gnu (64-bit) Running under: Ubuntu 20.04.3 LTS

Matrix products: default BLAS/LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.8.so

locale: 1 LC_CTYPE=ja_JP.UTF-8 LC_NUMERIC=C LC_TIME=ja_JP.UTF-8 LC_COLLATE=ja_JP.UTF-8
[5] LC_MONETARY=ja_JP.UTF-8 LC_MESSAGES=C LC_PAPER=ja_JP.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C LC_MEASUREMENT=ja_JP.UTF-8 LC_IDENTIFICATION=C

attached base packages: 1 stats graphics grDevices utils datasets methods base

other attached packages: 1 xfun_0.31 magick_2.7.3 shinyjqui_0.4.1 wordcloud2_0.2.1 shiny_1.7.2

loaded via a namespace (and not attached): 1 tinytex_0.40 tidyselect_1.1.2 bslib_0.4.0 shinyjs_2.1.0 purrr_0.3.4 lattice_0.20-45
[7] vctrs_0.4.1 generics_0.1.2 htmltools_0.5.3 yaml_2.3.5 utf8_1.2.2 rlang_1.0.3
[13] later_1.3.0 pillar_1.7.0 jquerylib_0.1.4 glue_1.6.2 withr_2.5.0 DBI_1.1.3
[19] lifecycle_1.0.1 fontawesome_0.3.0 htmlwidgets_1.5.4 memoise_2.0.1 fastmap_1.1.0 Cairo_1.6-0
[25] httpuv_1.6.6 parallel_4.0.2 fansi_1.0.3 Rcpp_1.0.8.3 xtable_1.8-4 renv_0.15.5
[31] promises_1.2.0.1 DT_0.23 cachem_1.0.6 RcppParallel_5.1.4 OpenMx_2.20.6 jsonlite_1.8.0
[37] mime_0.12 digest_0.6.29 dplyr_1.0.9 grid_4.0.2 cli_3.3.0 tools_4.0.2
[43] magrittr_2.0.3 sass_0.4.2 tibble_3.1.7 crayon_1.5.1 pkgconfig_2.0.3 MASS_7.3-57
[49] ellipsis_0.3.2 Matrix_1.4-1 shinyBS_0.61.1 lubridate_1.8.0 assertthat_0.2.1 rstudioapi_0.13
[55] R6_2.5.1 compiler_4.0.2

I solved this problem by myself. I made two dummy download button.
This method may seem like a lot of hassle, but modularization would eliminate the hassle.

library(shiny)
library(shinyjqui)
library(shinyjs)
library(magick)
library(xfun)

ui <- fluidPage(
  useShinyjs(),
  actionButton("save_myPlot","download", icon = icon("download")),
  actionButton("save_myPlot2","download", icon = icon("download"), style = "visibility: hidden;"),
  downloadButton("save_myPlot_hidden",style = "visibility: hidden;"),
  # plot
  jqui_resizable(plotOutput("myPlot")),
)

server <- function(input, output, session) {
  # I could not get plot_src with Javascript in Linux environment. However, I found that I could get it by running it twice.
  # Therefore, I was able to solve the problem by inserting two dummy buttons: DL button -> DL button 2 -> real DL button.
  observeEvent(input$save_myPlot,{
    shinyjs::runjs("Shiny.setInputValue('plot_src', document.getElementById('myPlot').childNodes[0].src);
                   document.getElementById('save_myPlot2').click();
                   ")
  })
  observeEvent(input$save_myPlot2,{
    shinyjs::runjs("Shiny.setInputValue('plot_src',document.getElementById('myPlot').childNodes[0].src);
                   document.getElementById('save_myPlot_hidden').click();
                   ")
  })
  # downaload handler - save the image
  output$save_myPlot_hidden <- downloadHandler(
    filename = function() { 
      paste0("plot_", Sys.Date(), ".png") },
    content = function(file) {
      # get image code from URI
      plot_src <- gsub("^data.*base64,", "", input$plot_src)
      # decode the image code into the image
      plot_image <- image_read(base64_decode(plot_src))
      # save the image
      image_write(plot_image, file)
    })
  
  # plot
  output$myPlot <- renderPlot(
    plot(rnorm(5), rnorm(5))
  )
}

shinyApp(ui = ui, server = server)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM