如何在Shiny Leaflet中渲染对应单标记的带HTML样式的标签
问题根因
addCircleMarkers中带~前缀的参数(公式式传参),只会在传入的data数据集的列范围里查找变量,不会读取全局环境中单独定义的独立向量。
你当前的代码里,labelText是和coords平行定义的独立向量,不属于coords的列,leaflet解析参数时无法逐行匹配取值,直接把整个向量的全部内容当成了每个点的标签值,最终导致所有标记的标签都显示全量数据集的内容。
修复方案
方法1:将标签内容并入源数据集
把生成好的标签字符串作为新列存入coords,让leaflet可以逐行读取对应的值,这是最稳定的写法,修改后完整可运行代码如下:
library(shiny) library(leaflet) library(dplyr) library(sf) ui <- fluidPage( leafletOutput("map") ) server <- function(input, output, session) { coords <- quakes %>% sf::st_as_sf(coords = c("long","lat"), crs = 4326) # 生成逐行对应的标签内容 coords$labelText <- paste0("<b>Depth: </b>",coords$depth,"<br/>", "<b>Mag: </b>",coords$mag,"<br/>", "<b>Stations: </b>",coords$stations) output$map <- leaflet::renderLeaflet({ leaflet::leaflet() %>% leaflet::addTiles() %>% leaflet::setView(172.972965,-35.377261, zoom = 4) %>% leaflet::addCircleMarkers( data = coords, stroke = FALSE, radius = 6, label = ~htmltools::HTML(labelText) ) }) } shinyApp(ui, server)
方法2:直接在参数内构造标签,无需预定义变量
如果不想额外给数据集加列,直接在label的公式里基于数据集自带的列构造HTML内容即可,所有变量都会从当前行自动匹配取值,对应代码片段:
leaflet::addCircleMarkers( data = coords, stroke = FALSE, radius = 6, # 直接在公式内拼接内容,从当前行取depth/mag/stations的值 label = ~htmltools::HTML( paste0( "<b>Depth: </b>", depth, "<br/>", "<b>Mag: </b>", mag, "<br/>", "<b>Stations: </b>", stations ) ) )
注意事项
- 需要渲染HTML样式时用
htmltools::HTML包裹内容即可,不要用htmlEscape,否则HTML标签会被转成纯文本显示 - 公式式传参的作用域仅覆盖传入的
data数据集,跨环境引用独立向量一定会出现取值不匹配的问题 - 不需要复杂样式的纯文本标签,直接传对应列名即可,无需额外包装
内容的提问来源于stack exchange,提问作者mustafa00
相关产品推荐
相关产品推荐

