拆分一张传单图的代码(这样一部分的输入更新不会影响另一部分代码)

Split code of one leaflet map (so that input updates of one part does not affect other part of code)

是否可以拆分地图的代码,以便地图的一部分仅在其自身的输入发生更改时更新?

在下面的可重现示例中,当 select 使用“墨粉”图块并 select 使用新站时,整个传单地图将再次执行,因为 addLegend 需要更新。这使得磁贴跳回“OSM(默认)”磁贴。当我 select 其他车站时,我想留在我 select 的瓷砖。

library(leaflet)
library(shiny)
library(dplyr)

pal <- colorFactor(
  palette = "YlGnBu",
  domain = quakes$stations
)

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      checkboxGroupInput("stations", 
                  "Choose a station",
                  choices=sort(unique(quakes$stations)),
                  selected = c(10, 11))
    ),
    mainPanel(
      leafletOutput("map")
    )
  )
)

server <- function(input, output) {
  points <- reactive({
    quakes %>%
      filter(stations %in% input$stations)
  })
  
  output$map <- renderLeaflet({
    leaflet(quakes) %>%
      addTiles(group = "OSM (default)") %>%
      addProviderTiles(providers$Stamen.Toner, group = "Toner") %>%
      addLayersControl(
        baseGroups = c("OSM (default)", "Toner"),
        options = layersControlOptions(collapsed = FALSE)) %>%
      addLegend("Legend", position = "topleft", pal = pal, values = input$stations)
  })
  
  observe({
    if(nrow(points()) == 0) {
      leafletProxy("map", data = points()) %>%
        clearMarkers()
    } else {
      leafletProxy("map", data = points()) %>%
        clearMarkers() %>%
        addCircleMarkers(radius = 2)
    }
  })
}

shinyApp(ui, server)

我尝试了几种方法,包括将 addLegend 添加到 else 语句中,但效果并不理想。我是 leaflet/shiny 的新手,移动 addLegend 对我来说似乎最合乎逻辑。我非常感谢任何建议!

据我所知,您尝试将 addLegend 移动到观察者处是在正确的轨道上。这样做对我来说很好。

  1. addLegend 移动到 observe
  2. 在添加图例之前,请使用 clearControls 删除任何现有图例(否则您会得到多个图例)
  3. 我删除了 observe
  4. 中的重复代码
  5. 据我所知,条件 nrow(points()) > 0 只需要决定是否应该绘制图例。对于标记没关系。

    library(leaflet)
    library(shiny)
    library(dplyr)
    
    pal <- colorFactor(
      palette = "YlGnBu",
      domain = quakes$stations
    )
    
    ui <- fluidPage(
      sidebarLayout(
        sidebarPanel(
          checkboxGroupInput("stations", 
                             "Choose a station",
                             choices=sort(unique(quakes$stations)),
                             selected = c(10, 11))
        ),
        mainPanel(
          leafletOutput("map")
        )
      )
    )
    
    server <- function(input, output) {
      points <- reactive({
        quakes %>%
          filter(stations %in% input$stations)
      })
      
      output$map <- renderLeaflet({
        leaflet(quakes) %>%
          addTiles(group = "OSM (default)") %>%
          addProviderTiles(providers$Stamen.Toner, group = "Toner") %>%
          addLayersControl(
            baseGroups = c("OSM (default)", "Toner"),
            options = layersControlOptions(collapsed = FALSE))
      })
      
      observe({
        proxy <- leafletProxy("map", data = points()) %>%
          clearMarkers() %>% 
          clearControls() %>% 
          addCircleMarkers(radius = 2)
        
        if (nrow(points()) > 0) 
          proxy <- proxy %>% addLegend("Legend", position = "topleft", pal = pal, values = input$stations)
        
        proxy
      })
    
    }
    
    shinyApp(ui, server)