## ----include = FALSE---------------------------------------------------------- knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ## ----eval = FALSE------------------------------------------------------------- # if (interactive()) { # shiny::runApp(system.file("examples", "shiny_draggable_plot.R", package = "dragmapr")) # } ## ----eval = FALSE------------------------------------------------------------- # if (interactive()) { # shiny::runApp(system.file("examples", "shiny_custom_labels.R", package = "dragmapr")) # } ## ----eval = FALSE------------------------------------------------------------- # if (interactive()) { # shiny::runApp(system.file("examples", "shiny_draggable_export.R", package = "dragmapr")) # } ## ----eval = FALSE------------------------------------------------------------- # if (interactive()) { # shiny::runApp(system.file("examples", "shiny_static_export.R", package = "dragmapr")) # } ## ----eval = FALSE------------------------------------------------------------- # if (interactive()) { # shiny::runApp(system.file("examples", "shiny_spatial_studio.R", package = "dragmapr")) # } ## ----eval = FALSE------------------------------------------------------------- # render_dragmapr_project( # "dragmapr-project.zip", # file = "final-map.png", # width = 10, # height = 8, # dpi = 300 # ) ## ----eval = FALSE------------------------------------------------------------- # library(shiny) # library(dragmapr) # # ui <- fluidPage( # tags$head(tags$script(HTML(dragmapr_iframe_bridge()))), # uiOutput("helper") # ) # # server <- function(input, output, session) { # helper_dir <- tempfile("myapp_") # dir.create(helper_dir) # shiny::addResourcePath("myapp_static", helper_dir) # # x <- prepare_dragmapr_sf(my_sf) # drag_map_prototype(x, region_col = "region", # file = file.path(helper_dir, "helper.html")) # # output$helper <- renderUI( # tags$iframe(src = "myapp_static/helper.html", # style = "width:100%;height:700px;border:none;") # # ## Switching Grouping Columns in Spatial Studio # # Spatial Studio stores drag positions per region column and propagates them # when you change the **Group / region column** dropdown. This means you can # work at multiple levels of geographic hierarchy without losing your layout. # # ### How inheritance works # # Each column maintains its **own independent layout cache**. Switching columns # never displaces regions that you have not personally dragged in that column: # # - **Coarser → finer** (e.g. HHS region → state name): the finer column resumes # its own last saved layout. If you have not visited it before, all fine units # start at their natural geographic positions — they are **not** displaced by # the parent column's drag offsets. # # - **Finer → coarser** (e.g. state name → HHS region): each parent group is # placed at the **mean** of its member units' current positions, or (if you # choose "Restore parent's last position") at the position the parent had when # you last worked at that column. # # ### Example: HHS regions and state names # # The bundled HHS demo has both an `hhs_region` column (ten groups) and a `NAME` # column (individual states). A typical workflow: # # 1. Set **Group column** to `hhs_region`. Drag the ten regions into an exploded # layout. # 2. Switch to `NAME`. The states appear at their **natural positions** (first # visit) — ready for individual fine-tuning without any carry-over from the # HHS drag. # 3. Fine-tune individual states as needed. # 4. Switch back to `hhs_region`. Each region lands at the mean of its states' # current positions, reflecting any individual fine-tuning. # # ### What resets and what is preserved # # | On column switch | Behaviour | # |---|---| # | Region offsets (coarser→finer) | Restored to that column's last saved positions, or zero if never visited | # | Region offsets (finer→coarser) | Average of children's positions, or restored to parent's last position | # | Label offsets | Reset — label IDs are derived from the new column's region names | # | Undo / redo stack | Reset — new column starts with a clean history | # | Region palette | Preserved | # | Legend and label filter selections | Preserved | # # ### Round-trip precision # # The only step that involves averaging is **finer → coarser**. If all child # regions had identical offsets, the round-trip is lossless. Mixed individual child # moves are summarised into an average for the parent — or you can choose # **"Restore parent's last position"** to skip averaging and return the parent to # exactly where it was. # # Changing only the **Label column** while keeping the region column the same # leaves region offsets completely untouched. Only the label IDs change. #