--- title: "State-first composition with dragmapr" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{State-first composition with dragmapr} %\VignetteEngine{knitr::rmarkdown} \usepackage[utf8]{inputenc} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 5 ) have_dragmapr <- requireNamespace("dragmapr", quietly = TRUE) ``` `explodemap` computes the *geometry* of an exploded layout. Manual composition -- nudging regions and labels until the map reads well -- belongs to the [dragmapr](https://prigasg.github.io/dragmapr/) editor. The bridge between them is a single, reusable **composition object**: a `dragmapr_state`. The workflow is **compute once, then compose and render from the state**: ``` explode_grouped() -> as_dragmapr_state() -> dragmapr_edit() -> focus_map(state = ) (geometry) (handoff) (compose) render_dragged_map(state = ) ``` ## 1. Compute the layout ```{r compute} library(explodemap) # A few regions, each with several units. unit_square <- function(x0, y0, size = 40000) { sf::st_polygon(list(rbind( c(x0, y0), c(x0 + size, y0), c(x0 + size, y0 + size), c(x0, y0 + size), c(x0, y0) ))) } grid <- expand.grid(col = 0:2, row = 0:2) regions <- sf::st_sf( region = rep(c("A", "B", "C"), each = 3), unit = sprintf("u%02d", seq_len(9)), geometry = sf::st_sfc( lapply(seq_len(9), function(i) unit_square(grid$col[i] * 50000, grid$row[i] * 50000)), crs = 3857 ) ) layout <- explode_grouped(regions, region_col = "region") plot(layout) ``` ## 2. Hand the layout over as a state `as_dragmapr_state()` is the preferred handoff. It converts the exploded anchors into metre deltas and records the projected CRS plus a `geometry_id`, so the result is a durable, reproducible composition: ```{r handoff, eval = have_dragmapr} state <- as_dragmapr_state(layout) state ``` > The older `as_dragmapr()` returns a raw `dragmapr_layout` (geometry plus > offset tables). It remains supported as a low-level escape hatch, but > `as_dragmapr_state()` is the recommended entry point. ## 3. Compose Open the dragmapr editor seeded with the state. In Shiny, capture each edit back into a state with `dragmapr::dragmapr_widget_state()`: ```{r compose, eval = FALSE} dragmapr::dragmapr_edit(layout, state = state) ``` ## 4. Render the composed state Every downstream renderer accepts the state via `state =`. The interactive focus map can even reopen on a saved selection with `restore_selection = TRUE`: ```{r render-focus, eval = FALSE} state$selected_feature <- "B" focus_map(layout, state = state, group_col = "region", restore_selection = TRUE) ``` And the static renderer reproduces the composition from geometry plus state, with no recomputation: ```{r render-static, eval = FALSE} dragmapr::render_dragged_map( layout$sf_grouped, region_col = "region", state = state, file = "composed.png" ) ``` The state also flows through `update_exploded_layout()`, so an edited composition can be folded back onto the grouped layout object itself. For a complete runnable script, see `system.file("examples/state_first_workflow.R", package = "explodemap")`. For a fuller cross-package example that includes layout diagnostics, label-aware parameter search, a simulated editorial pass, JSON state persistence, `focus_map()`, and `dragmapr::render_dragged_map()`, run: ```{r full-cross-package, eval = FALSE} source(system.file( "examples/explodemap_dragmapr_pipeline.R", package = "explodemap" )) ```