R leaflet - предотвратить map_marker_click на определенном слое, но разрешить метку - PullRequest
1 голос
/ 14 февраля 2020

У меня есть функция showPopup (), которая позволяет мне добавлять всплывающие окна на мою карту с помощью map_marker_click. Эта функция предназначена для работы с синим слоем (myData), а не с красным (myData). Я мог бы использовать option = interactive: False, чтобы красный слой не отображал всплывающее окно, но мне все еще нужен этот слой для отображения его метки.

Как я могу предотвратить интерактивный слой с его меткой, но не с событием map_marker_click? так как он применяется ко всем слоям моей карты?

Вот воспроизводимый пример:

library(tidyverse)
library(ggplot2)
library(shiny)
library(leaflet)
library(leafpop)
library(lattice)


id <- c(1,1,1,1,2,2,3,3,3,4)
lat <- c(49.823, 49.823, 49.823, 49.823, 58.478, 58.478, 57.478 , 57.478 , 57.478, 38.551)
lng <- c(-10.854, -10.854, -10.854, -10.854, -11.655, -11.655, 2.021 , 2.021 , 2.021, 5.256)
type <- c("A","C","B","B","C","A","B","A","C","B")
date <- c(152.5,307.5,145,481,152,109.5,258.5,107.5,186.5,150)
start <- c(123,235,135,192,149,101,205,75,155,100)
stop <- c(182,380,155,289,155,218,312,140,218,200)
myData <- data.frame(id,type,date,start,stop,lat,lng)

name <- c("AAA","BBB","CCC","DDD")
lat2 <- c(48,47,45,46)
lng2 <- c(-10,-12,-14,-16)
myData2 <- data.frame(name,lat2,lng2)

folder <- tempfile()
dir.create(folder)

chronogramme<- function(dataId){

  dataFiltered<-filter(myData,id==dataId)

  p<- ggplot(dataFiltered,aes(type,date))+
    geom_linerange(aes(ymin=start,ymax=stop),size=5)+
    coord_flip()
  return(p)
}


ui <- fluidPage(
  leafletOutput("map")
)


server <- function(input, output, session) {

  #Sortie map
  output$map <- renderLeaflet({
    leaflet()%>%
      addProviderTiles(providers$CartoDB.Positron) %>% 
      addCircleMarkers(
        layerId=~id,
        data = myData,
        lat = myData$lat,
        lng = myData$lng,
        radius = 5,
        color = 'blue',
        stroke = FALSE,
        fillOpacity = 1
      )%>% 
      addCircleMarkers(
        data = myData2,
        lat = myData2$lat,
        lng = myData2$lng,
        radius = 5,
        color = 'red',
        stroke = FALSE,
        fillOpacity = 1,
        label = ~as.character(name),
      )
  })

  # When map is clicked, show a popup with city info
  showPopup <- function(id, lat, lng) {
    chrngr <- chronogramme(id)
    svg(filename= paste(folder,"plot.svg", sep = "/"), 
        width = 500 * 0.005, height = 300 * 0.005)
    print(chrngr)
    dev.off()

    content <- paste(readLines(paste(folder,"plot.svg",sep="/")), collapse = "")

    leafletProxy("map") %>% addPopups(lng, lat, content, layerId = id)
  }

  observe({
    leafletProxy("map") %>% clearPopups()
    event <- input$map_marker_click
    if (is.null(event))
      return()

    isolate({
      showPopup(event$id, event$lat, event$lng)
    })
  })

}



# Create Shiny app ----
shinyApp(ui = ui, server = server)

1 Ответ

1 голос
/ 25 февраля 2020

Я думаю, что у вас уже есть 90% решения. Для синих круговых маркеров вы инициализировали слот id, используя строку кода:

addCircleMarkers(
  layerId=~id   ## Here!

, в то время как вы не добавили id к красным маркерам. Теперь, в реактивной части вашего кода, где вы наблюдаете щелчок, просто проверьте, является ли слот id NULL или нет:

observe({
  leafletProxy("map") %>% clearPopups()
  event <- input$map_marker_click
  if(is.null(event) || is.null(event$id))  # Here is the change.
    return()

Это работает для вас?


Кстати, я считаю ваш вопрос вдохновляющим для моей работы. Спасибо!

...