Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

353
Vistas
R - Plots without Shiny - Create with JavaScript and produce screenshot

I have a Shiny application that generates one image after clicking an action button, and saves the screenshot of that image after pressing on another action button. The code is working, but I now need to do the same in a loop for 500 cases, in R but without Shiny, automatically, without clicking between plots, saving the screenshots in a folder. (I don't need to see the plots being generated but, for debugging purposes, it might help initially to see them.)

Currently the image is generated with a commercial plotting library, called by the nice.js files. The js files and the library are in the ./www folder.

I cannot put a proper reproducible example because of the commercial library.

Based on Stéphane's answer, I modified the question.

The code now reads ...

library(htmltools)

dep <- htmlDependency(
  name      = "html2canvas",
  version   = "1.4.1",
  src       = list(paste0(getwd(),"/www")),
  script    = "html2canvas.js",
  all_files = FALSE
)

myscript <- HTML('
function takeshot(i) {
  var captureElement = document.getElementById("myframe");
  html2canvas(captureElement)
    .then(function (canvas) {
      canvas.style.display = "none";
      document.body.appendChild(canvas);
      return canvas;
    })
    .then(function (canvas) {
      var image = canvas
        .toDataURL("image/png")
        .replace("image/png", "octet-stream");
      var a = document.createElement("a");
      a.setAttribute("download", "./www/my-image-" + i + ".png");
      a.setAttribute("href", image);
      a.click();
      canvas.remove();
    });
}
')

for(i in 1:500){
  print(
      browsable(
      tagList(
        dep,
        tags$div(
          #xxxxx plot goes here xxxxx
            tags$script(src='commercial library goes here.js'),
            id = 'myframe',                                           
            htmltools::includeScript(paste0(getwd(),'/www/nice_',i,'.js')),
        ),
        # tags$button( 'Take screenshot', onclick = 'takeshot();' ),
        # tags$h1('Screenshot:'),
        
        tags$div(id = 'output'),
        tags$script(myscript)  # tags$script('takeshot(i);'), # <======= calling takeshot(i) here?
      ) # closes tagList
     ) # closes browsable
    ) # closes print
  
  Sys.sleep(2)
}

The plotting part of the code works well and, if one has a single plot, will download the image after one clicks the "Take screenshot" button.

However, I have to do this for 500 files. Is there a way of downloading the screenshots automatically, without clicking? (Perhaps there must be some delay between the generation of the image and the screenshot.)

I tried to modify the 'takeshot' function to save the files as my-image-1.png, my-image-2.png, ..., my-image-500.png, but it doesn't download anything.

Thanks

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

You can do something like this:

library(htmltools)

# html2canvas: https://html2canvas.hertzen.com/

dep <- htmlDependency(
  name = "html2canvas",
  version = "1.4.1",
  src = "path/to/html2canvas",
  script = "html2canvas.js",
  all_files = FALSE
)

myscript <- HTML('
function takeshot() {
  var div = document.getElementById("myframe");
  html2canvas(div).then(function (canvas) {
    document.getElementById("output").appendChild(canvas);
  });
}
')

app <- tagList(
  dep,
  tags$div(
    id = "myframe",
    #xxxxx plot goes here xxxxx
  ),
  tags$button(
    "Take screenshot",
    onclick = "takeshot();"
  ),
  tags$h1("Screenshot:"),
  tags$div(id = "output"),
  tags$script(myscript)
)

browsable(app)

You'll have to include the JavaScript library you use as dependency as well, and a script which generates your plot.


EDIT

Sorry, rather use this function for the automatic download:

function takeshot() {
  var captureElement = document.getElementById("myframe");
  html2canvas(captureElement)
    .then(function (canvas) {
      canvas.style.display = "none";
      document.body.appendChild(canvas);
      return canvas;
    })
    .then(function (canvas) {
      var image = canvas
        .toDataURL("image/png")
        .replace("image/png", "image/octet-stream");
      var a = document.createElement("a");
      a.setAttribute("download", "my-image.png");
      a.setAttribute("href", image);
      a.click();
      canvas.remove();
    });
}
about 4 years ago · Juan Pablo Isaza Denunciar

0

Based on my tests this doesn't seem to function without the "click". Any way to automate it, seems this has not be resolved across multiple forums.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda