闪亮的leaflet easyPrint插件

7

我正在尝试将easyPrint插件集成到我的shiny leaflet应用程序中。 我想要的是像演示中的东西,但在shiny中。

我已经尝试模仿示例,但没有成功。

到目前为止,这是我的R代码:

    library(shiny)
    library(shinydashboard)
    library(shinyjs)
    library(htmlwidgets)
    library(htmltools)
    library(leaflet)
    library(leaflet.extras)
    library(sp)

    shinyApp(
  ui = fluidPage(
    leafletOutput("map", height = 750)
  ),
  server = function(input, output) {

    registerPlugin <- function(map, plugin) {
      map$dependencies <- c(map$dependencies, list(plugin))
      map
    }

    easyPrintPlugin <- htmlDependency("leaflet-easyprint", "2.1.8",
                                      src = c(href = "https://github.com/rowanwins/leaflet-easyPrint/blob/gh-pages/dist/"),
                                      script = "index.js")

    # Map
    output$map <- renderLeaflet({
      leaflet() %>%
        addProviderTiles(providers$CartoDB.Positron) %>%
        registerPlugin(easyPrintPlugin) %>%
        onRender("function(el, x) {
                 L.easyPrint({
                 position: 'topleft',
                 sizeModes: ['A4Portrait', 'A4Landscape']
                 }).addTo(map);}")
    })

  }
)

然而,什么也没有发生。屏幕上只是一片白色。如果我去掉onRender部分,leaflet就正常工作了。 不幸的是,我相对于Shiny、leaflet、.js和github来说比较新,在确定引起问题的方面方面遇到了困难。
1个回答

9
解决方案
  library(leaflet)
  library(shiny)
  library(htmlwidgets)

  jsfile <- "https://rawgit.com/rowanwins/leaflet-easyPrint/gh-pages/dist/bundle.js" 
  ui <- fluidPage(
    tags$head(tags$script(src = jsfile)),
    leafletOutput("map")
  )
  
  server <- function(input, output, session) {
    
    output$map <- renderLeaflet({
      leaflet() %>% 
        addProviderTiles("OpenStreetMap.Mapnik") %>%
        setView(-122.23, 37.75, zoom = 10) %>%
        onRender(
          "function(el, x) {
            L.easyPrint({
              sizeModes: ['Current', 'A4Landscape', 'A4Portrait'],
              filename: 'mymap',
              exportOnly: true,
              hideControlContainer: true
            }).addTo(this);
            }"
        )
      })
    
    }
  
  shinyApp(ui, server)

enter image description here

注意:leaflet-easyPrint 依赖于 dom-to-image。根据 dom-to-image Readme,Safari 和 Internet Explorer 不受支持。但是,在 Chrome 和 Firefox 中,打印按钮将起作用。

故障排除过程

如果我们运行应用程序并检查元素,则会看到以下错误:

enter image description here

让我们从第二个和第三个错误开始。 无法加载资源 这个错误很容易理解:URL https://github.com/rowanwins/leaflet-easyPrint/blob/gh-pages/dist//index.js 不存在。路径是错误的:index.jsdist 目录中不存在。
我们想要使用这个路径下的 bundle.js: https://github.com/rowanwins/leaflet-easyPrint/blob/gh-pages/dist/bundle.js未能加载脚本 GitHub使用严格的MIME类型检查,因此浏览器未按预期使用该文件。我们需要使用rawgit.com路径。在此处阅读更多here。要编写rawgit.com路径,请按照以下步骤操作(来自链接答案):
  1. 在GitHub上找到您的链接,并单击文件的“Raw”版本。
  2. 复制URL并链接到它。
  3. 将raw.githubusercontent.com更改为rawgit.com(非生产环境)或cdn.rawgit.com(生产环境)
我们应该使用此路径:https://rawgit.com/rowanwins/leaflet-easyPrint/gh-pages/dist/bundle.js TypeError:L.easyPrint不是函数 错误发生在加载 leaflet-easyPrint 之前。这告诉我们 onRenderleaflet-easyPrint 加载并附加到小部件之前被调用。根据Joe Cheng在此线程中的建议,运行时的html依赖注入可能是异步的。他建议不要使用 htmlDependency(src = c(href = "http://...")) 来处理任何旨在与Shiny一起使用的依赖项。
相反,我们可以在应用程序的 header 中直接包含远程JS文件。然后在调用 onRender 之前将加载 leaflet-easyPrint

首先,我非常感谢详细的故障排除过程描述。但是,当我尝试使用其他leaflet插件(restoreView、L.Map.Sync和leaflet-side-by-side)采用相同的方法时,我会收到错误消息“Uncaught ReferenceError: L is not defined”,这表明出现了相反的问题——插件在R-Shiny加载leaflet javascript之前被加载了。easyPrint插件的构建方式是否有什么特殊之处,使其引入了leaflet js? - Ryan
1
@Ryan 我无法重现这个问题 - 我可以使用leaflet-side-by-side得到一个小的示例。如果您打开一个新的问题并在此处链接它,我可以查看您的情况!也值得检查一下,在onRender函数中是否使用了map而不是this,因为那会导致问题。 - Hallie Swan
结果发现我在使用uiOutput和renderUI而不是leafletOutput和renderLeaflet时出了问题。你的反馈帮助我找到了错误,谢谢! - Ryan
@HallieSwan 这真的很好。你能帮我解决一个问题吗?当 leafletOutput("map")renderUI 中,例如 output$UI_map <- renderUI({leafletOutput("map")}),该怎么办呢?按钮将不会显示在地图上。 - Roman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接