如何用Shiny按钮替换SelectInput实现地图目标国家切换
实现Shiny应用中按钮切换国家的地图展示
以下是修改后的完整代码,替换了原有的下拉选择框,改为点击按钮循环切换下一个国家:
library(shiny) library(leaflet) df <- structure(list(lng = c(101.901875, -95.712891, 108.339537, 37.618423 ), lat = c(35.486703, 37.09024, 14.315424, 55.751244), country = structure(c(1L, 3L, 4L, 2L), .Label = c("China", "Russia", "USA", "Vietnam"), class = "factor"), number = c(35500L, 6267L, 2947L, 3070L)), .Names = c("lng", "lat", "country", "number"), class = "data.frame", row.names = c(NA, -4L)) ui <- fluidPage( titlePanel(title = "countries"), sidebarLayout( sidebarPanel( # 显示当前选中的国家 h4(textOutput("current_country")), # 切换国家的按钮 actionButton("next_country", "切换到下一个国家") ), mainPanel(leafletOutput("mymap", height = "500")) ) ) server <- function(input, output){ # 存储当前国家的索引,初始为1 current_idx <- reactiveVal(1) # 获取去重后的国家列表 country_list <- as.character(unique(df$country)) # 监听按钮点击事件,更新索引 observeEvent(input$next_country, { new_idx <- current_idx() + 1 # 超过国家总数时重置为第一个 if(new_idx > length(country_list)){ new_idx <- 1 } current_idx(new_idx) }) # 渲染当前选中的国家文本 output$current_country <- renderText({ paste("当前国家:", country_list[current_idx()]) }) # 准备当前国家的地图数据 map_data <- reactive({ selected_country <- country_list[current_idx()] data <- df[df$country == selected_country, ] data$popup <- paste0(data$country, " ", data$number) data }) # 初始化地图 output$mymap <- renderLeaflet({ data <- map_data() leaflet(data = data) %>% setView(lng = data$lng, lat = data$lat, zoom = 4) %>% addProviderTiles(provider = "CartoDB.Positron") %>% addMarkers(lng = ~lng, lat = ~lat, popup = ~popup) }) # 点击按钮后更新地图(避免重新渲染整个地图,提升性能) observe({ data <- map_data() leafletProxy("mymap", data = data) %>% clearMarkers() %>% addMarkers(lng = ~lng, lat = ~lat, popup = ~popup) %>% setView(lng = data$lng, lat = data$lat, zoom = 4) }) } shinyApp(ui, server)
关键修改说明:
- 移除原有的
selectInput组件,改用reactiveVal跟踪当前选中的国家索引 - 按钮点击时自动更新索引,索引超出国家总数时重置为1,实现循环切换
- 新增当前国家文本展示,让用户直观了解当前视图对应的国家
- 使用
leafletProxy更新地图内容,避免每次点击都重新渲染整个地图,优化性能 - 切换国家时自动将地图视图定位到对应国家的坐标,提升交互体验
内容的提问来源于stack exchange,提问作者EnriqueGG
相关产品推荐
相关产品推荐

