2016-04-08 9 views
3

Ich habe eine App erstellt, mit der der Benutzer eine Flugblattkarte ändern kann und ich möchte diese Karte in einem PDF-Bericht verwenden. Ich habe 1. installierten Pakete Faltblatt, webshot und htmlwidget 2. installiert PhantomJSSpeichern von Flugblättern in R shiny

unten ist eine vereinfachte Version des Codes

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") 
) 

Ich bekomme diese Fehlermeldung:

Warning: Fehler in system.file: 'Paket' muss die Länge 1 Stapel trace (innerste erste) sein: 73: system.file 72: Leseleitungen 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 \ Dateien test/server.R # 24] 1: glänzend :: runApp

wenn die Schaltfläche Speichern aktiviert ist. savewidget funktioniert gut, wenn ich auf die Schaltfläche wie folgt speichern definieren:

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") 

    }) 

Aber ich möchte wirklich die Änderungen, die der Benutzer in der webshot macht. Kann jemand helfen?

+0

Möchten Sie, dass der Benutzer die Datei speichern kann? Ich denke, das würde auf der JavaScript-Seite besser gehandhabt werden. Ich werde versuchen, ein Beispiel für dich zu finden. – timelyportfolio

+0

Nun, meine brillante Lösung verwickelt sich in ursprungsübergreifende Probleme. Ich werde versuchen, an eine andere Art zu denken zu denken. – timelyportfolio

Antwort

3

Dies ist nicht perfekt, aber hier eine Lösung mit der Bibliothek html2canvas. Bitte achten Sie auf die Quellenangabe, die Lizenz und das Urheberrecht. Auch diese wird nicht in RStudio Viewer arbeiten, aber es gibt Möglichkeiten, um es zum Laufen zu bringen.

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); 
    } 
    }); 
}); 
'  
    ) 
) 
) 
+0

Vielen Dank für die schnelle Antwort. Ich habe es noch nicht in meiner glänzenden App funktionieren lassen. Ich bin nicht zu stark in Javascript ..... muss später in dieser Woche zurückkommen. Danke für die bisherige Arbeit –