I would like to update the selectModUI
from the mapedit
package for different leaflet
maps when using Shiny
. Below is a working example.
library(tidyverse)
library(shiny)
library(sf)
library(leaflet)
library(mapview)
library(mapedit)
library(DT)
library(viridis)
# Load the sf object
nc <- st_read(system.file("shape/nc.shp", package = "sf"))
# Project transformation
nc <- st_transform(nc, crs = 4326)
# Create a color function for the leaflet map
sid74_pal <- colorBin(palette = viridis(10), domain = nc$SID74, bins = 4)
# Create a leaflet map
sid74_map <- leaflet() %>%
addTiles(group = "OSM") %>%
addProviderTiles("CartoDB", group = "CartoDB") %>%
addProviderTiles("Esri.WorldImagery", group = "Esri.WorldImagery") %>%
addFeatures(nc,
color = ~sid74_pal(SID74),
label = ~htmltools::htmlEscape(NAME),
layerId = ~seq_len(length(st_geometry(nc)))) %>%
addLegend(position = "bottomright", pal = sid74_pal,
values = nc$SID74,
title = "SID74") %>%
addLayersControl(baseGroups = c("OSM", "CartoDB", "Esri.WorldImagery"))
ui <- fluidPage(
# Select Module Output
h3("Map"),
selectModUI(id = "Sel_Map"),
# Datatable Output
h3("Table"),
dataTableOutput(outputId = "Table")
)
server <- function(input, output) {
# Create selectMod
sel <- callModule(selectMod, "Sel_Map", sid74_map)
# Reactive values
rv <- reactiveValues(
selectnum = NULL,
sub_table = nc %>%
st_set_geometry(NULL) %>%
slice(0)
)
# Subset the table based on the selection
observe({
# the select module returns a reactive
gs <- sel()
# Filter for the county data
rv$selectnum <- as.numeric(gs[which(gs$selected == TRUE), "id"])
if (!is.null(rv$selectnum)){
rv$sub_table <- nc %>%
st_set_geometry(NULL) %>%
slice(rv$selectnum)
}
})
# Create a datatable
output$Table <- renderDataTable({
datatable(rv$sub_table, options = list(scrollX = TRUE))
})
}
# Run the application
shinyApp(ui = ui, server = server)
The idea is to create a map and users can select or unselect the polygons on the map. Based on the users' selection, a data table output would dynamically show which counties are selected and present the data, as the screenshot shows.
Now I want to add a select input so users can decide which parameter they want to visualize using the app. I feel like I can create some kinds of reactivities or reactive values to store the maps, and then update the Below is an example I created. Notice that compared to Example 1, I created a new leaflet map called sid79_map
in Example 2 and add a select input so people can select. However, this strategy is not working. It would be great if someone can point out a direction to go.
library(tidyverse)
library(shiny)
library(sf)
library(leaflet)
library(mapview)
library(mapedit)
library(DT)
library(viridis)
# Load the sf object
nc <- st_read(system.file("shape/nc.shp", package = "sf"))
# Project transformation
nc <- st_transform(nc, crs = 4326)
# Create a color function for the leaflet map
sid74_pal <- colorBin(palette = viridis(10), domain = nc$SID74, bins = 4)
sid79_pal <- colorBin(palette = viridis(10), domain = nc$SID79, bins = 4)
# Create a leaflet map
sid74_map <- leaflet() %>%
addTiles(group = "OSM") %>%
addProviderTiles("CartoDB", group = "CartoDB") %>%
addProviderTiles("Esri.WorldImagery", group = "Esri.WorldImagery") %>%
addFeatures(nc,
color = ~sid74_pal(SID74),
label = ~htmltools::htmlEscape(NAME),
layerId = ~seq_len(length(st_geometry(nc)))) %>%
addLegend(position = "bottomright", pal = sid74_pal,
values = nc$SID74,
title = "SID74") %>%
addLayersControl(baseGroups = c("OSM", "CartoDB", "Esri.WorldImagery"))
sid79_map <- leaflet() %>%
addTiles(group = "OSM") %>%
addProviderTiles("CartoDB", group = "CartoDB") %>%
addProviderTiles("Esri.WorldImagery", group = "Esri.WorldImagery") %>%
addFeatures(nc,
color = ~sid79_pal(SID79),
label = ~htmltools::htmlEscape(NAME),
layerId = ~seq_len(length(st_geometry(nc)))) %>%
addLegend(position = "bottomright", pal = sid79_pal,
values = nc$SID79,
title = "SID79") %>%
addLayersControl(baseGroups = c("OSM", "CartoDB", "Esri.WorldImagery"))
ui <- fluidPage(
# Select input
selectInput(inputId = "Selection", label = "Select Counties", choices = c("SID74", "SID79"), selected = "SID74"),
# Select Module Output
h3("Map"),
selectModUI(id = "Sel_Map"),
# Datatable Output
h3("Table"),
dataTableOutput(outputId = "Table")
)
server <- function(input, output) {
# Try to create reactivity based on the select input type, not working
sel_type <- reactive({
input$Selection
})
leafmap <- reactive({
if(sel_type() == "SID74"){
sid74_map
} else if (sel_type() == "SID79"){
sid79_map
}
})
# Create selectMod
sel <- callModule(selectMod, "Sel_Map", leafmap())
# Reactive values
rv <- reactiveValues(
selectnum = NULL,
sub_table = nc %>%
st_set_geometry(NULL) %>%
slice(0)
)
# Subset the table based on the selection
observe({
# the select module returns a reactive
gs <- sel()
# Filter for the county data
rv$selectnum <- as.numeric(gs[which(gs$selected == TRUE), "id"])
if (!is.null(rv$selectnum)){
rv$sub_table <- nc %>%
st_set_geometry(NULL) %>%
slice(rv$selectnum)
}
})
# Create a datatable
output$Table <- renderDataTable({
datatable(rv$sub_table, options = list(scrollX = TRUE))
})
}
# Run the application
shinyApp(ui = ui, server = server)
leafletProxy
to update your map? Then you only have to create a single map. To check which polygons users clicked you can checkinput$yourmapid_shape_click
. – Wilmar van OmmerenleafletProxy
but not sure how to useleafletProxy
to modifyselectMod
. I will further look into this when I have time. – www