walkerke / mapgl

R interface to Mapbox GL JS v3 and Maplibre GL JS
https://walker-data.com/mapgl
Other
91 stars 5 forks source link

Feature Request: Update tooltip with `set_*` function #42

Open stefanlinner opened 2 months ago

stefanlinner commented 2 months ago

Hi,

I have the following use case: A user can change the fill_color variable by clicking a button. This already works fine using the set_paint_property() function. However, I would also like to set a new tooltip variable (as suggested by the outcommented code). It would be great if this could be done using a set_*() function that does not require redrawing the fill_layer. Currently I'm accomplishing this by first clear_layer("fill") and then again add_fill_layer(...) with the updated tooltip. However, this results in redrawing the fill_layer and with a set-update it would be much nicer and more performant.

library(mapgl)
library(sf)
library(shiny)

nc <- st_read(system.file("shape/nc.shp", package="sf"))

ui <-
  fluidPage(
    actionButton("click", "Click"),
    mapboxglOutput("map")
  )

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

  output$map <- renderMapboxgl({
    mapboxgl() %>%
      fit_bounds(
        nc,
        animate = FALSE
      ) |>
      add_fill_layer(
        "fill",
        source = nc,
        fill_color = interpolate(
          column = "AREA",
          values = c(min(nc[["AREA"]]), max(nc[["AREA"]])),
          stops = c("#f7fbff", "#08306b"),
          na_color = "lightgrey"
        ),
        tooltip = "AREA"
      )
  })

  myMapProxy <- mapboxgl_proxy("map", session)

  observeEvent(input$click, {
    myMapProxy |>
      set_paint_property(
        "fill",
        "fill-color",
        interpolate(
          column = "PERIMETER",
          values = c(min(nc[["PERIMETER"]]), max(nc[["PERIMETER"]])),
          stops = c("#f7fbff", "#08306b"),
          na_color = "lightgrey"
        )
      ) #|>
      # set_*_property(
      #   "fill",
      #   "tooltip",
      #   "PERIMETER"
      # )
  })
}

shinyApp(
  ui = ui,
  server = server
)

Out of curiosity: Is it generally also possible to update the source dataset using a set_* function?

Thanks again for your great work, very appreaciated!

kmcd39 commented 4 weeks ago

Would also appreciate this! I was playing a bit with adding an invisible other layer that ONLY has tooltips+ popups so that the re-drawing is at least invisible, but using a set_* function for tooltips or popups would be preferable

stefanlinner commented 4 weeks ago

Interesting idea of adding an invisible layer! Would you have an example for me? How exactly do you make it "invisible"?

kmcd39 commented 4 weeks ago

I just set opacity to 0!

mapgl::add_fill_layer(
    id = "tooltips"
    ,source =
      data
    ,fill_opacity = 0
    ,popup = 
      "infoboxes"
    ,tooltip =
      "rounded.vals"
  )
stefanlinner commented 4 weeks ago

That's a clever workaround! Thanks!

kmcd39 commented 4 weeks ago

Thanks -- though it still slows down app b/c it is redrawing the invisible layer :. But allows a fast option w/o tooltips and a slower one with them.