使用 shinyjs javascript 在闪亮的应用程序中操作现有的 Leaflet 地图

Manipulate existing Leaflet map in a shiny app with javascript using shinyjs

我有一个闪亮的应用程序,里面有一张现有的传单地图。我希望能够在渲染后操作此地图,通过 shinyjs 包使用自定义 javascript。下面是一个最小的例子:

app.R

# packages ----------------------------------------------------------------

library(dplyr)
library(leaflet)
library(shiny)
library(shinyjs)

# ui ----------------------------------------------------------------------

ui <- fluidPage(

  useShinyjs(),
  extendShinyjs(script = "my_js.js"),

  leafletOutput(outputId = "map", height = "80vh"),

  tags$hr(),
  tags$p("Button to run the JS code"),
  actionButton(inputId = "go", label = "Add a Marker")

)

# server ------------------------------------------------------------------

server <- function(input, output, session){

  # define a simple map
  output$map <- renderLeaflet({

    leaflet() %>%
      addProviderTiles("CartoDB.Positron")
  })

  # observe the go button and run the shinyjs.addMarker function
  observeEvent(
    eventExpr = input$go,
    handlerExpr = js$addMarker()
  )

}

# run ---------------------------------------------------------------------

shinyApp(ui = ui, server = server)

my_js.js

shinyjs.addMarker = function(){

  // get the map - this bit doesn't work!
  var map = document.getElementById('map');

  // create a marker and add to map
  var marker = new L.marker([53, -1]).addTo(map);

  // really I'd be going off and querying an API, or doing
  // something else for which there is no handy R function.

};

真正的问题是如何在创建地图对象后对其进行访问。显然,在这个示例中,我只是添加了一个标记,我可以用 leafletProxy() 来做,但实际上我想查询一个 API 并在用户执行操作时将额外的数据带到地图上。

任何关于其他方法的帮助或建议将不胜感激!

克里斯

您可以使用 htmlwidtgetonRender() 函数访问地图对象。然后,您可以将其保存到全局范围的变量中(通过在创建变量时跳过 var 关键字)。这在 JavaScript 代码中的任何地方都可用。

output$map <- renderLeaflet({
    leaflet() %>%
        addProviderTiles("CartoDB.Positron") %>%
        htmlwidgets::onRender("
            function(el,x) {
                map = this;
            }
        ")
})

您的 my_js.js 将如下所示:

shinyjs.addMarker = function(){

  // create a marker and add to map
  var marker = new L.marker([53, -1]).addTo(map);

  // really I'd be going off and querying an API, or doing
  // something else for which there is no handy R function.

};