Open RWParsons opened 1 month ago
I've pushed a temporary fix here that allows set_filter()
to be used on a regular map object (within or outside of Shiny). So an app developer can hard-code the initial filter to correspond to the initial value of the slider and get the expected behavior. I'll keep looking into this solution as well though.
Example usage:
library(shiny)
library(bslib)
library(colourpicker)
library(dplyr)
library(sf)
library(shinyWidgets)
devtools::load_all()
ui <- bootstrapPage(
sliderInput("slider", "min value:", value = 0, min = -3, max = 3),
numericRangeInput("area_range", label = "numeric range input for area", value = c(0.03, 0.042), step = 0.01),
maplibreOutput("map")
)
server <- function(input, output, session) {
nc <- st_read(system.file("shape/nc.shp", package = "sf"))
nc$var1 <- rnorm(n = nrow(nc))
nc$CNTY_ID <- as.character(nc$CNTY_ID)
output$map <- renderMaplibre({
initial_ids <- nc |>
filter(
AREA >= 0.03,
AREA <= 0.042
) |>
pull(CNTY_ID)
maplibre() |>
fit_bounds(nc, animate = FALSE) |>
add_fill_layer(
id = "polygon_layer",
source = nc,
fill_color = "blue",
fill_opacity = 0.5,
tooltip = "AREA"
) |>
set_filter(
"polygon_layer",
c("in", "CNTY_ID", initial_ids)
)
})
observe({
ids <- nc |>
filter(
AREA >= min(input$area_range),
AREA <= max(input$area_range)
) |>
pull(CNTY_ID)
cat(length(ids))
maplibre_proxy("map") |>
set_filter(
"polygon_layer",
c("in", "CNTY_ID", ids)
)
})
}
shinyApp(ui, server)
This bug was identified in the discussions of #12.
Default values for shiny inputs that are observed to modify the map via proxy function are not currently applied. This is because they are not deferred until the shiny session is flushed as is the default by leaflet. See the that the proxy function includes a
deferUntilFlush
argument (https://github.com/rstudio/leaflet/blob/92bc272caa9a268140e75ede1966bcdc7d585636/R/utils.R#L136) and the invocation of this check this value and defers the change until the shiny session is flushed (https://github.com/rstudio/leaflet/blob/92bc272caa9a268140e75ede1966bcdc7d585636/R/utils.R#L194).reprex:
By default this app should show only one polygon on the map (with the current default inputs for the
'area_range'
. If you reduce the lower bound of the input range, it updates the map but this should happen for the default view of the map.I think the solution would be to make some wrapper, like leaflet has
invokeRemote()
which checks the shiny session and defers if necessary, rather than each shiny util, likeset_filter()
, directly callingproxy$session$sendCustomMessage()
.Thanks!
Rex