【问题标题】:Shiny leaflet easyPrint plugin闪亮的传单easyPrint插件
【发布时间】:2024-01-02 23:15:01
【问题描述】:

我正在尝试将easyPrint plugin 合并到我闪亮的传单应用程序中。我想要的是看起来像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、leaflet、.js 和 github 还比较陌生,所以我很难确定是哪个方面导致了问题。

【问题讨论】:

    标签: r plugins shiny leaflet shinyjs


    【解决方案1】:

    解决方案

      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 中使用。

    故障排除过程

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

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

    加载资源失败

    这个错误是不言自明的:URL https://github.com/rowanwins/leaflet-easyPrint/blob/gh-pages/dist//index.js 不存在。路径错误:index.jsdist 目录中不存在。

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

    没有加载脚本

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

    1. 在 GitHub 上找到您的链接,然后单击文件的“原始”版本。
    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 in this thread,运行时的 html 依赖注入可以是异步的。他建议不要将 htmlDependency(src = c(href = "http://...")) 用于任何打算与 Shiny 一起使用的依赖项。

    相反,我们可以将远程 JS 文件包含在 header of the app 中。那么leaflet-easyPrint会在onRender被调用之前被加载。

    【讨论】:

    • 首先我非常感谢故障排除过程的详细描述,但是当我尝试使用其他传单插件(restoreView、L.Map.Sync 和传单并排)的相同方法时,我得到了错误“未捕获的 ReferenceError:L 未定义”,这表明了相反的问题 - 在 R-Shiny 加载传单 javascript 之前,插件加载得太早。是否有一些关于easyPrint 插件的构建方式使它能够拉入传单js?
    • @Ryan 我无法重现这个问题——我可以得到一个与传单并排工作的小例子。如果您打开一个新问题并将其链接到此处,我可以查看您的案例!可能还值得检查您在 onRender 函数中使用的是 this 而不是 map,因为这会导致问题。
    • 在我开始使用 uiOutput 和 renderUI 而不是 LeafletOutput 和 renderLeaflet 的过程中发现。您的反馈帮助我找到了错误。谢谢!