Reputation: 41
I have created an app where the user can modify a leaflet map and i would like to use this map in a pdf report. I have 1. installed packages leaflet, webshot and htmlwidget 2. installed PhantomJS
below is a simplified version of the code
server.R:
library(shiny)
library(leaflet)
library(htmlwidgets)
library(webshot)
shinyServer(function(input, output, session) {
output$amap <- renderLeaflet({
leaflet() %>%
addProviderTiles("Stamen.Toner",
options = providerTileOptions(noWrap = TRUE, reuseTiles=TRUE))
})
observe({
leafletProxy("amap") %>%
clearShapes() %>%
addCircles(lng = c(22,-2), lat = c(42,65))
})
observeEvent(input$saveButton,{
themap<- leafletProxy("amap")
saveWidget(themap, file="temp.html", selfcontained = F)
webshot("temp.html", file = "Rplot.png",
cliprect = "viewport")
})
})
ui.R:
fluidPage(
leafletOutput("amap", height="600px", width="600px"),
br(),
actionButton("saveButton", "Save")
)
I get this error message:
Warning: Error in system.file: 'package' must be of length 1 Stack trace (innermost first): 73: system.file 72: readLines 71: paste 70: yaml.load 69: yaml::yaml.load_file 68: getDependency 67: widget_dependencies 66: htmltools::attachDependencies 65: toHTML 64: saveWidget 63: observeEventHandler [C:\R files\test/server.R#24] 1: shiny::runApp
when the save button is activated. savewidget works fine when i define the save button like this:
observeEvent(input$saveButton,{
themap<-leaflet() %>%
addProviderTiles("Stamen.Toner",
options = providerTileOptions(noWrap = TRUE, reuseTiles=TRUE))
saveWidget(themap, file="temp.html", selfcontained = F)
webshot("temp.html", file = "Rplot.png",
cliprect = "viewport")
})
But i really want the changes that the user makes in the webshot. Can anyone help?
Upvotes: 4
Views: 1791
Reputation: 6579
This is not perfect, but here a solution using the library html2canvas. Please be careful of attribution, license, and copyright. Also, this won't work in RStudio Viewer, but there are ways to get it to work.
library(leaflet)
library(htmltools)
lf <- leaflet() %>%
addProviderTiles(
"Stamen.Toner",
options = providerTileOptions(
noWrap = TRUE,
reuseTiles=TRUE
)
)
# add the mapbox leaflet-image library
# https://github.com/mapbox/leaflet-image
#lf$dependencies[[length(lf$dependencies)+1]] <- htmlDependency(
# name = "leaflet-image",
# version = "0.0.4",
# src = c(href = "http://api.tiles.mapbox.com/mapbox.js/plugins/leaflet-image/v0.0.4/"),
# script = "leaflet-image.js"
#)
lf$dependencies[[length(lf$dependencies)+1]] <- htmlDependency(
name = "html2canvas",
version = "0.5.0",
src = c(href="https://cdn.rawgit.com/niklasvh/html2canvas/master/dist/"),
script = "html2canvas.min.js"
)
browsable(
tagList(
tags$button("snapshot",id="snap"),
lf,
tags$script(
'
document.getElementById("snap").addEventListener("click", function() {
var lf = document.querySelectorAll(".leaflet");
html2canvas(lf, {
useCORS: true,
onrendered: function(canvas) {
var url = canvas.toDataURL("image/png");
var downloadLink = document.createElement("a");
downloadLink.href = url;
downloadLink.download = "map.png"
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
}
});
});
'
)
)
)
Upvotes: 5