Making a "Paintable" reactive map

What the reproducible code will produce is a map of North Carolina, broken out evenly to four geographically "even" regions. Imagine this is being used by a Sales Manager who is assigning territory to his salespeople.

What this does now: Right now, this map does the following: Allows you to select a region, which then creates two tables. The first is just a straight data dump of the accompanying features associated with that county. The second table then groups that data together to produce sums of the data for each region.

What I want this to do: Let's say the person using this wants to assign new territory. Each of those territories are assigned a color. A is red, B is blue, C is green, and D is yellow. So they select an input button for "A" and then he begins to click on counties, which turn red, and all do all the table aggregations at the bottom. Once they're done with that, they select "B", and so on. So then the table at the bottom looks like:

Territory Leads Sales
A selected agg value selected agg value
B selected agg value selected agg value
C selected agg value selected agg value
D selected agg value selected agg value

Does that make sense?

    library(tigris)
    library(mapview)
    library(mapedit)
    library(leaflet)
    library(dplyr)
    library(DT)
    
    north_carolina <- counties("north carolina") %>% st_as_sf() %>% arrange(INTPTLON, INTPTLAT) %>% dplyr::select(NAMELSAD, geometry) %>% rename(county_name = NAMELSAD) %>% 
      mutate(territory = rep(letters[1:4], each = 25), leads = sample(100:1000, 100, replace = TRUE), sales = sample(100:1000, 100, replace = TRUE))
    
    ui <- fluidPage(
      h3("Map"),
      selectModUI(id = "map_select"),
      # Datatable Output
      h3("Table"),
      dataTableOutput(outputId = "BaseTable"),
      h3("Reactive Output"),
      dataTableOutput(outputId = "ReactTable")
    )
    
    server <- function(input, output) {
      
    leafmap <- reactive({leaflet() %>%
      addProviderTiles(providers$Stamen.Toner) %>%
      addPolygons(data = north_carolina, fillOpacity = "red",
                  fillColor = "grey",
                  weight = 5,
                  opacity = 5,
                  color = "black") %>%
        leafem::addFeatures(data=north_carolina,label = ~htmltools::htmlEscape(territory),
                            layerId = ~seq_len(length(st_geometry(north_carolina))))
    
    })
    
    selectMod <- function(input, output, session, leafmap,
                          styleFalse = list(fillOpacity = 0.2, weight = 1, opacity = 0.4),
                          styleTrue = list(fillOpacity = 0.7, weight = 3, opacity = 0.7))
      
    {
      print("*** custom selectMod")
      output$map <- leaflet::renderLeaflet({
        mapedit:::add_select_script(leafmap, styleFalse = styleFalse, styleTrue = styleTrue,
                                    ns = session$ns(NULL))
      })
      id <- "mapedit"
      select_evt <- paste0(id, "_selected")
      df <- data.frame()
      selections <- reactive({
        id <- as.character(input[[select_evt]]$id)
        if (length(df) == 0) {
          # Initial case, first time module is called.
          # Switching map, i.e. subsequent calls to the module.
          # Note that input[[select_evt]] will always keep the last selection event,
          # regardless of this module being called again.
          df <<- data.frame(id = character(0), selected = logical(0),
                            stringsAsFactors = FALSE)
        } else {
          loc <- which(df$id == id)
          if (length(loc) > 0) {
            df[loc, "selected"] <<- input[[select_evt]]$selected
          } else {
            df[nrow(df) + 1, ] <<- c(id, input[[select_evt]]$selected)
          }
        }
        return(df)
      })
      return(selections)
    }
    
    rval <- reactiveValues(
      sel = reactive({}),
      selectnum = NULL,
      base_table = north_carolina %>%
        st_set_geometry(NULL) %>%
        dplyr::slice(0)
    )
    
    # Create selectMod
    observeEvent(leafmap(),
                 rval$sel <- callModule(selectMod, "map_select", leafmap())
    )
    
    # Subset the table based on the selection
    observeEvent(rval$sel(), {
      # The select module returns a reactive
      gs <- rval$sel()
      # Filter for the county data
      rval$selectnum <- as.numeric(gs[which(gs$selected == TRUE), "id"])
      
      rval$base_table <- north_carolina %>%
        st_set_geometry(NULL) %>%
        dplyr::slice(rval$selectnum)
      
      rval$react_table <- rval$base_table %>% group_by(territory) %>% summarise(leads = sum(leads), sales = sum(sales))
      
    })
    
    # Create a datatable
    output$BaseTable <- renderDataTable({
      datatable(rval$base_table, options = list(scrollX = TRUE))
      
    })
    
    output$ReactTable <- renderDataTable({
      datatable(rval$react_table)
      
    })
      
    }

    shinyApp(ui,server)

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.