You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shiny中Tab切换后Leaflet地图显示异常问题求助

Shiny中Tab切换后Leaflet地图显示异常的解决方案

问题解决说明

经ghybs的评论提示,该问题已解决,解决方案如下:

最终解决方案

在实际代码中,由于存在多个可修改地图数据的UI输入(部分为全局UI元素,可在站点其他部分修改),且使用leafletProxy添加标记,最终方案是创建一个观察者:

  • 先延迟100ms调用invalidateSize(),让Leaflet重新计算地图尺寸
  • 再至少延迟100ms后,通过leafletProxy执行fitBounds(),将地图居中到数据范围

原问题描述

我用Shiny开发了一个带有page_navbar和多个菜单选项的应用,其中一个菜单是「密度图」,核心是包含addCircleMarkers的Leaflet地图。为了对比同一物种不同时间段的密度数据,我设置了一个tabset,两个Tab分别对应不同时间段的Leaflet地图。

首次进入「密度图」菜单时一切正常,但切换到其他主菜单选项后再返回「密度图」,点击之前处于隐藏状态的Tab时,Leaflet地图会出现显示异常:地图区域有灰色块,且未自动居中到标记位置。

最简复现代码

library(shiny)
library(leaflet)
library(bslib)


ui <- tagList(
  page_navbar(
    id = "nav",
    
    title = "Leaflet Maps in Tabs",
    
    sidebar = sidebar(
      id = "global_sidebar",
      nav_panel("Placeholder")
    ),
    
    # Home tab
    nav_panel("Home",
              p("Welcome to the Home Page!")
    ),
    
    # Maps tab with tabset
    nav_panel("Maps",
              tabsetPanel(
                id = "map_tabs",
                tabPanel("Current",
                         leafletOutput("current_map")
                ),
                tabPanel("Previous",
                         leafletOutput("previous_map")
                )
              )
    )
  )
)

server <- function(input, output, session) {
  
  output$current_map <- renderLeaflet({

    current_markers <- data.frame(
      lat = c(37.7749, 34.0522),
      lng = c(-122.4194, -118.2437)
    )
    
    leaflet() %>%
      addTiles() %>%
      addMarkers(
        data = current_markers,
        lng = ~lng,
        lat = ~lat,
        popup = ~paste("Location:", lat, lng) 
      ) 
  })
  

  output$previous_map <- renderLeaflet({

    previous_markers <- data.frame(
      lat = c(40.7128, 42.3601),
      lng = c(-74.0060, -71.0589)
    )
    
    leaflet() %>%
      addTiles() %>%
      addMarkers(
        data = previous_markers,
        lng = ~lng,
        lat = ~lat,
        popup = ~paste("Location:", lat, lng) 
      ) 
  })
}

shinyApp(ui = ui, server = server)

复现步骤

含侧边栏场景

  • 点击「Maps」,确认两个Tab下的地图均正常显示
  • 隐藏全局侧边栏
  • 切换到「Home」菜单
  • 重新显示全局侧边栏
  • 切换回「Maps」菜单
  • 点击之前切换时处于隐藏状态的另一个地图Tab

此时地图会出现灰色区域,虽可手动拖动回到标记中心,但超出边界后灰色区域会覆盖地图,导致无法正常使用。

无需侧边栏场景

  • 点击「Maps」,确认两个Tab下的地图均正常显示
  • 按F12打开浏览器开发者工具
  • 切换到「Home」菜单
  • 按F12关闭开发者工具
  • 切换回「Maps」菜单
  • 点击之前切换时处于隐藏状态的另一个地图Tab

实际代码细节与异常表现

实际代码中还有以下差异:

  • 为地图高度设置了CSS样式
  • 使用leafletProxy更新地图内容,调用fitBounds()自动居中
  • 除addMarkers外,还使用了addCircleMarkers和addLegend

出现异常时,地图的图例和普通标记仍存在,但circlemarkers会消失,同时伴随灰色区域和未居中的问题。

我并非专业开发者,这是一个志愿项目。试过多种代码改写,上述是能复现问题的最简版本,也曾尝试监听Tab点击事件,调用update_density_map()函数(通过leafletProxy更新地图),但未能解决问题。想请教是否应该放弃Tab式的Leaflet地图布局,或者有其他可行的解决方法。

测试环境

  • 操作系统:Windows 11 23H2
  • 浏览器:Chrome 130.0.6723.70(64位)、Edge 130.0.2849.52(64位)
  • R版本:4.4.1
  • 包版本:leaflet 2.2.2,shiny 1.9.1

内容的提问来源于stack exchange,提问作者Blair

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 01:44:58