Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

352
Views
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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!