I’m interested in demonstrating how two different sets of geography boundaries fit in between a higher level and lower level geography that they have in common. I want to do this by organizing the buttons in relation to each other and connect with arrows. Along the lines of this:
I’ve made a demonstration shiny app showing what I’ve tried to accomplish using bslibs layout_columns()
and cards()
, however at this point I’m stuck.
Any help/suggestions would be appreciated!
library(shiny)
library(bslib)
library(sf)
library(leaflet)
ui <- page_fluid(
layout_columns(
card(
card(
actionButton("btn1", "Button One")
),
layout_columns(
card(
actionButton("btn2", "Button Two"),
actionButton("btn3", "Button Three")
),
card(
actionButton("btn4", "Button Four")
)
),
card(
actionButton("btn5", "Button Five")
)
)
,
card(
p("Space for some important text")
),
col_widths = c(3,9)
),
layout_columns(
leafletOutput("main_map",
width = "50vw",
height = "30vw")
)
)
shinyApp(ui, function(input, output) {
file <- system.file("gpkg/nc.gpkg", package = "sf")
btn1 <- read_sf(file) %>%
st_transform(crs = 4326)
btn2 <- btn1 %>% filter(NAME %in% c("Ashe", "Alleghany"))
btn3 <- btn1 %>% filter(NAME %in% c("Camden", "Gates"))
btn4 <- btn1 %>% filter(NAME %in% c("Edgecombe", "Orange"))
btn5 <- btn1 %>% filter(NAME %in% c("Durham", "Martin"))
output$main_map <- renderLeaflet({
leaflet() %>%
addProviderTiles('CartoDB.Voyager', group = "Simple Street Map",
options = providerTileOptions(noWrap = TRUE)
) %>%
addPolygons(data = btn1,
group = "Button One",
stroke = TRUE,
weight = 1,
color = ~NAME,
opacity = 0.5,
fillColor = ~NAME,
fillOpacity = 0.3
) %>%
addLayersControl(
options = layersControlOptions(collapsed = FALSE)
)
})
selectedData <- reactiveValues(dataset = NULL)
observeEvent(input$btn1, {
selectedData <- btn1
leafletProxy("main_map") %>%
clearShapes() %>%
addPolygons(data = selectedData,
stroke = TRUE,
weight = 1,
color = ~NAME,
opacity = 0.5,
fillColor = ~NAME,
fillOpacity = 0.3)
})
observeEvent(input$btn2, {
selectedData <- btn2
leafletProxy("main_map") %>%
clearShapes() %>%
addPolygons(data = selectedData,
stroke = TRUE,
weight = 1,
color = ~NAME,
opacity = 0.5,
fillColor = ~NAME,
fillOpacity = 0.3)
})
observeEvent(input$btn3, {
selectedData <- btn3
leafletProxy("main_map") %>%
clearShapes() %>%
addPolygons(data = selectedData,
stroke = TRUE,
weight = 1,
color = ~NAME,
opacity = 0.5,
fillColor = ~NAME,
fillOpacity = 0.3)
})
observeEvent(input$btn4, {
selectedData <- btn4
leafletProxy("main_map") %>%
clearShapes() %>%
addPolygons(data = selectedData,
stroke = TRUE,
weight = 1,
color = ~NAME,
opacity = 0.5,
fillColor = ~NAME,
fillOpacity = 0.3)
})
observeEvent(input$btn5, {
selectedData <- btn5
leafletProxy("main_map") %>%
clearShapes() %>%
addPolygons(data = selectedData,
stroke = TRUE,
weight = 1,
color = ~NAME,
opacity = 0.5,
fillColor = ~NAME,
fillOpacity = 0.3)
})
})
This is how it currently looks for me. Generally the positioning is fine, but could be better. Don’t have a clue how to add arrows atm. Will keep searching for now.
Open to solutions using CSS as I have a stylesheet already going for my dashboard, but really anything that works would be great!
Note: in this example the buttons when clicked just highlight whatever sections of the map, didn’t want to figure out a fully fledged hierarchy!