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

如何在含响应式栅格的Leaflet中左对齐图例文本?

解决Leaflet图例标签左对齐问题(适配leafletProxy响应式场景)

核心方案:通过自定义CSS覆盖Leaflet默认的图例标签对齐样式,该方法完全兼容leafletProxy配合clearControls的动态更新场景。

修改步骤

1. 在UI中添加自定义CSS

在fluidPage内插入tags$style块,指定图例标签左对齐:

tags$style(HTML("
  .leaflet-control-legend .legend-label {
    text-align: left !important;
    padding-left: 6px; /* 可选:调整标签与颜色块的间距,优化视觉效果 */
  }
"))

2. 完整修改后的代码

以下是整合了CSS调整的完整可运行代码:

library(lubridate)
library(raster)
library(shiny)
library(leaflet)
library(leafem)

# Create example csv
params <- data.frame(summary = c("Mean", "Mean", "SD" , "SD"),
                     threshold = c(1, 2, 1, 2))

# Create raster brick (example)
raster_list <- list()
for (i in 1:4) {
  raster_list[[i]] <- raster(xmn=-90, xmx=-75, ymn=40, ymx=47, 
                             crs = "+proj=longlat +datum=NAD83 +no_defs ", 
                             resolution = 0.0416667)
}
raster_list[[1]] <- setValues(raster_list[[1]], 
                              sample(30:50, ncell(raster_list[[1]]), replace = TRUE))
raster_list[[2]] <- setValues(raster_list[[1]], 
                              sample(50:80, ncell(raster_list[[2]]), replace = TRUE))
raster_list[[3]] <- setValues(raster_list[[3]], 
                              sample(1:20, ncell(raster_list[[3]]), replace = TRUE))
raster_list[[4]] <- setValues(raster_list[[4]], 
                              sample(1:20, ncell(raster_list[[4]]), replace = TRUE))
all_rast <- stack(raster_list)
names(all_rast) <- paste0(tolower(params$summary), "_", params$threshold)
all_rast <- brick(all_rast)
all_rast <- projectRaster(all_rast, raster::projectExtent(all_rast, crs = "epsg:3857"))

# Modify function used to format legend labels so we can add dates
myLabelFormat <- function(..., dates = FALSE){ 
  if (dates) { 
    function(type = "numeric", cuts) { 
      dd <- parse_date_time(paste("2019", cuts), orders = "%Y %j")
      dd <- format(dd, "%d %B")
      paste0(cuts, " (", dd, ")")
    } 
  } else {
    labelFormat(...)
  }
}

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

ui <- fluidPage(
  tags$style(HTML("
    .leaflet-control-legend .legend-label {
      text-align: left !important;
      padding-left: 6px;
    }
  ")),
  
  titlePanel("Title"),
  
  sidebarLayout(
    
    sidebarPanel(
      
      selectInput(inputId = "threshold", 
                  label = "Threshold", 
                  choices = unique(params$threshold)),
      
      selectInput(inputId = "summary",
                  label = "Summary",
                  choices = unique(params$summary))

    ), # end sidebarPanel
    
    mainPanel(
      
      leafletOutput("map", height = "80vh")

    ) # end mainPanel
  ) # end sidebarLayout
) # end fluidPage

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

server <- shinyServer(function(input, output) {
  
  reacRaster <- reactive({all_rast[[paste0(tolower(input$summary), 
                                           "_", input$threshold)]]})
  
  legend_title <- reactive({ifelse(input$summary == "SD",
                                   "SD (days)", "Day of year")})
  
  legend_labels <- reactive({ifelse(input$summary == "SD",
                                    myLabelFormat(dates = FALSE),
                                    myLabelFormat(dates = TRUE))})
  
  output$map <- renderLeaflet({
    leaflet() %>%
      fitBounds(lng1 = -88, lat1 = 35, lng2 = -65, lat2 = 47) %>%
      addTiles()
  })
  
  observe({
    pal <- colorNumeric(palette = "viridis", 
                        domain = values(reacRaster()),
                        na.color = "transparent",
                        reverse = TRUE)
    
    leafletProxy("map") %>%
      clearImages() %>%
      clearControls() %>%
      addRasterImage(reacRaster(), 
                     colors = pal, 
                     group = "Value",
                     layerId = "Value",
                     opacity = 0.8, 
                     project = FALSE) %>%
      addLegend("bottomright", 
                pal = pal, 
                values = values(reacRaster()),
                labFormat = legend_labels(),
                title = legend_title(), 
                opacity = 0.8) %>%
      addImageQuery(reacRaster(),
                    digits = 2,
                    type = "click",
                    position = "bottomleft",
                    prefix = "",
                    layerId = "Value",
                    project = TRUE)   

  }) # end observe
}) # end server

# run app ---------------------------------------------------------------------#

shinyApp(ui = ui, server = server)

原理说明

  • Leaflet默认将图例标签设置为右对齐,通过CSS的!important强制覆盖该样式,确保每次通过leafletProxy更新图例时,新生成的标签依然保持左对齐。
  • 该方案不依赖于图例的生成方式,无论静态初始化还是动态更新都能稳定生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 20:23:14