Non-position scales (colour, size, shape) are always shared across facets. Only
position scales can be freed, with facet_*(scales = "free_x"/"free_y"), so a
per-panel colour or size legend cannot diverge. This is the riskiest of the
remaining grammar gaps because it reworks the flat layout model that facet and
axis alignment rely on, so it should sit behind the existing resolve_scale()
opt-in and leave the shared default untouched.
Implementation, vellumplot only (no vellum change):
resolve_scale() (R/facet.R) allows only x/y today. Widen it to accept
colour/size/shape; .resolve_for() and the resolve slot are already
generic, so this part is small.
.build_panels() (R/compile-facet.R) needs a per-panel (wrap) or per-strip
(grid) training branch for non-position scales, mirroring the free-position path
and storing p$color_sc and friends, threaded through the seam with
p$color_sc %||% built$scales$color.
- The hard part is the legend layout.
.build_layout() (R/compile-layout.R)
emits one legend track spanning the whole grid, drawn once with
rowspan = nrow_total in R/seam.R. A free non-position scale needs a legend
beside each panel: a per-panel legend cell with its own width and guide list.
Guides already stack in millimetres within a cell (compile-guides.R), so the
work is the track model, not the stacking.
Size L, most of it the per-panel legend layout; the training and API changes are
small. Gate it behind resolve_scale(colour = "independent") so the shared-scale
default output is unchanged. Snapshot-heavy.
Non-position scales (colour, size, shape) are always shared across facets. Only
position scales can be freed, with
facet_*(scales = "free_x"/"free_y"), so aper-panel colour or size legend cannot diverge. This is the riskiest of the
remaining grammar gaps because it reworks the flat layout model that facet and
axis alignment rely on, so it should sit behind the existing
resolve_scale()opt-in and leave the shared default untouched.
Implementation, vellumplot only (no vellum change):
resolve_scale()(R/facet.R) allows onlyx/ytoday. Widen it to acceptcolour/size/shape;.resolve_for()and theresolveslot are alreadygeneric, so this part is small.
.build_panels()(R/compile-facet.R) needs a per-panel (wrap) or per-strip(grid) training branch for non-position scales, mirroring the free-position path
and storing
p$color_scand friends, threaded through the seam withp$color_sc %||% built$scales$color..build_layout()(R/compile-layout.R)emits one legend track spanning the whole grid, drawn once with
rowspan = nrow_totalinR/seam.R. A free non-position scale needs a legendbeside each panel: a per-panel legend cell with its own width and guide list.
Guides already stack in millimetres within a cell (
compile-guides.R), so thework is the track model, not the stacking.
Size L, most of it the per-panel legend layout; the training and API changes are
small. Gate it behind
resolve_scale(colour = "independent")so the shared-scaledefault output is unchanged. Snapshot-heavy.