I found two answers concerning saving Leaflet Maps in shiny:
The core idea of them is to use mapshot()
instead webshot()
. In this case for setting screenshot size used cliprect
parameter. It defines a clipping rectangle which matches the height & width from the viewing port. So, if cliprect = 'viewport'
, I thought, map on the screenshot will be looks like on my screen. But it isn't.
I tryed to use code from examples above and they have given the same result.
That's why my question is: Is it possible to change leaflet map screenshot size in R Shiny and if yes, how it can be done?
My screen in browser with map looks likes this
Edit: The original answer downloaded the map as rendered initially without taking user's interaction with the map into account. I updated my answer using this answer so the download reflects the map as it looks to the user.
div
(as based on this and this)vwidth
and vheight
Example based on this and this:
library(leaflet)
library(mapview)
library(shiny)
ui <- fluidPage(
# 1. js to get width/height of map div
tags$head(tags$script('
var dimension = [0, 0];
$(document).on("shiny:connected", function(e) {
dimension[0] = document.getElementById("map").clientWidth;
dimension[1] = document.getElementById("map").clientHeight;
Shiny.onInputChange("dimension", dimension);
});
$(window).resize(function(e) {
dimension[0] = document.getElementById("map").clientWidth;
dimension[1] = document.getElementById("map").clientHeight;
Shiny.onInputChange("dimension", dimension);
});
')),
leafletOutput("map"),
downloadButton("dl", "Download Map")
)
server <- function(input, output, session) {
# reactive values to store map
vals <- reactiveValues()
# create base map
output$map <- renderLeaflet({
vals$base <- leaflet() %>%
addProviderTiles(providers$OpenStreetMap) %>%
addTiles()
})
# create map as viewed by user
observeEvent({
input$map_zoom
input$map_center
}, {
vals$current <- vals$base %>%
setView(lng = input$map_center$lng,
lat = input$map_center$lat,
zoom = input$map_zoom)
}
)
# create download
output$dl <- downloadHandler(
filename = "map.png",
content = function(file) {
mapshot(vals$current, file = file,
# 2. specify size of map based on div size
vwidth = input$dimension[1], vheight = input$dimension[2])
}
)
}
shinyApp(ui = ui, server = server)