对于普通的
leaflet
地图,我们可以使用 htmlwidgets::onRender()
以便在地图完成渲染时执行操作。
使用
leafletProxy()
更新地图时,有什么方法可以知道更新的渲染何时完成?
这是一个闪亮的应用程序示例,当您按下按钮时,它会添加多边形。客户端渲染完成后如何回调?
library(shiny)
library(leaflet)
library(sf)
polys <- st_sf(
geometry = st_sfc(
st_polygon(list(rbind(
c(-101.744384765625, 39.32155002466662),
c(-101.5521240234375, 39.330048552942415),
c(-101.40380859375, 39.330048552942415),
c(-101.33239746093749, 39.364032338047984),
c(-101.041259765625, 39.36827914916011),
c(-100.975341796875, 39.30454987014581),
c(-101.0399169921875, 39.24501680713314),
c(-101.243896484375, 39.16414104768742),
c(-101.455078125, 39.11125631228113),
c(-101.737060546875, 39.13006024213511),
c(-101.77825927734375, 39.16839962520706),
c(-101.734619140625, 39.254884981213734),
c(-101.744384765625, 39.32155002466662)
)))
)
)
ui <- fluidPage(
leafletOutput("map"),
actionButton("go", "go")
)
server <- function(input, output, session) {
output$map <- renderLeaflet({
leaflet() %>%
addTiles() %>%
setView(-101, 39, 8)
})
observeEvent(input$go, {
leafletProxy("map") %>%
addPolygons(data = polys)
})
}
shinyApp(ui, server)
我有一个可行的解决方案,但它不是很干净,所以我正在等待看看其他人是否有更好的解决方案。
在此解决方案中,我向初始传单对象添加了一个
onRender()
,并在其中添加了地图上 layeradd
事件的侦听器。每当该事件触发时,我都会向shiny发送一条消息来触发输入(leaflet_complete
)。因为 layeradd
事件会触发多次(在我的实际用例中,它会触发 100 次),并且我不想多次将输入发送到闪亮,所以我添加了一些代码以确保只触发该事件每次调用 leafletProxy 时一次。
这不是一个超级干净的方法,我希望有一个来自 leafletProxy 或传单的更明确的一般信号,只说一次“我完成了”。
library(shiny)
library(leaflet)
library(sf)
polys <- st_sf(
geometry = st_sfc(
st_polygon(list(rbind(
c(-101.744384765625, 39.32155002466662),
c(-101.5521240234375, 39.330048552942415),
c(-101.40380859375, 39.330048552942415),
c(-101.33239746093749, 39.364032338047984),
c(-101.041259765625, 39.36827914916011),
c(-100.975341796875, 39.30454987014581),
c(-101.0399169921875, 39.24501680713314),
c(-101.243896484375, 39.16414104768742),
c(-101.455078125, 39.11125631228113),
c(-101.737060546875, 39.13006024213511),
c(-101.77825927734375, 39.16839962520706),
c(-101.734619140625, 39.254884981213734),
c(-101.744384765625, 39.32155002466662)
)))
)
)
ui <- fluidPage(
tags$head(tags$script(
"let leafletComplete = false;
Shiny.addCustomMessageHandler('leafletRender', function(message) { leafletComplete = false; });"
)),
leafletOutput("map"),
actionButton("go", "go")
)
server <- function(input, output, session) {
output$map <- renderLeaflet({
leaflet() %>%
addTiles() %>%
setView(-101, 39, 8) %>%
htmlwidgets::onRender("
function(el, x) {
this.on('layeradd', function() {
if (!leafletComplete) {
leafletComplete = true;
Shiny.setInputValue('leaflet_complete', true, {priority: 'event'});
}
});
}
")
})
observeEvent(input$go, {
session$sendCustomMessage("leafletRender", TRUE)
leafletProxy("map") %>%
addPolygons(data = polys)
})
observeEvent(input$leaflet_complete, {
print("complete")
})
}
shinyApp(ui, server)