闪亮的传单 easyPrint 插件

Shiny leaflet easyPrint plugin

我正在尝试合并 easyPrint plugin into my shiny leaflet app. What I want is something that looks like the demo,但是很闪亮。

我试过模仿the examples,但没有成功。

到目前为止,这是我的 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 部分,传单将正常运行。

不幸的是,我对 Shiny、传单、.js 和 github 比较陌生,所以我很难确定是哪个方面导致了问题。

解决方案

  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)

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

故障排除过程

如果我们 运行 app 和 inspect 元素,我们会看到以下错误:

让我们从第二个和第三个错误开始。

加载资源失败

这个错误很漂亮 self-explanatory: URL https://github.com/rowanwins/leaflet-easyPrint/blob/gh-pages/dist//index.js 不存在。路径错误:index.js不存在于dist目录中。

我们想使用 bundle.js 这个路径:https://github.com/rowanwins/leaflet-easyPrint/blob/gh-pages/dist/bundle.js.

没有加载脚本

GitHub 使用严格的 MIME 类型检查,因此浏览器未按预期使用该文件。我们需要使用 rawgit.com path instead. Read more here。要编写 rawgit.com 路径,请按照以下步骤操作(来自链接的答案):

  1. Find your link on GitHub, and click to the "Raw" version of the file.
  2. Copy the URL, and link to it.
  3. Change raw.githubusercontent.com to rawgit.com (non-production) or cdn.rawgit.com (production)

我们应该使用这个路径:https://rawgit.com/rowanwins/leaflet-easyPrint/gh-pages/dist/bundle.js

TypeError: L.easyPrint 不是函数

错误发生在之前 加载错误leaflet-easyPrint。这告诉我们 onRenderleaflet-easyPrint 加载并附加到小部件之前被调用。根据 Joe Cheng in this thread,在 运行 时的 htmldependency 注入可以是异步的。他建议不要将 htmlDependency(src = c(href = "http://...")) 用于任何旨在与 Shiny 一起使用的依赖项。

相反,我们可以只在 中包含远程 JS 文件。然后 leaflet-easyPrint 将在调用 onRender 之前加载。