Skip to content

Commit b1d20a0

Browse files
author
Yunuuuu
committed
feat: add metadata to store any additional parameters for $gtable method
1 parent 9e6df2c commit b1d20a0

2 files changed

Lines changed: 61 additions & 43 deletions

File tree

R/alignpatch-alignpatches.R

Lines changed: 57 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,9 @@ TAGS_Z <- 5L
170170
#' - `tag`: Either `NULL` (no tag), a single string, or a `LayoutTagger` object
171171
#' that provides a `$tag()` method to generate a tag string for tagging each
172172
#' plot individually.
173+
#' - `metadata`: A list of additional metadata. This can store any extra
174+
#' information relevant to the patch, such as custom parameters or auxiliary
175+
#' data that do not fit into the other categories.
173176
#'
174177
#' @keywords internal
175178
patch_options <- S7::new_class("patch_options",
@@ -186,7 +189,8 @@ patch_options <- S7::new_class("patch_options",
186189
return("must be a single string or `LayoutTagger` object")
187190
}
188191
}
189-
)
192+
),
193+
metadata = S7::class_list
190194
)
191195
)
192196

@@ -239,8 +243,11 @@ PatchAlignpatches <- ggproto(
239243

240244
# if no plots, we do nothing --------------------------
241245
options <- options %||% patch_options()
242-
self$patches <- patches # should be a list
243-
if (is_empty(patches)) return(options) # styler: off
246+
metadata <- list(patches = patches)
247+
if (is_empty(patches)) {
248+
prop(options, "metadata", check = FALSE) <- metadata
249+
return(options)
250+
}
244251

245252
# add borders to patch --------------------------------
246253
area <- vec_slice(area, keep)
@@ -268,10 +275,10 @@ PatchAlignpatches <- ggproto(
268275
if (is.null(theme <- prop(options, "theme"))) {
269276
# by default, we use ggplot2 default theme
270277
theme <- prop(self$plot, "theme")
271-
self$top_level <- TRUE
278+
metadata$top_level <- TRUE
272279
} else {
273280
theme <- theme + prop(self$plot, "theme")
274-
self$top_level <- FALSE
281+
metadata$top_level <- FALSE
275282
}
276283
prop(options, "theme", check = FALSE) <- complete_theme(theme)
277284

@@ -292,19 +299,22 @@ PatchAlignpatches <- ggproto(
292299
prop(self$plot, "tags"),
293300
prop(options, "tag")
294301
)
295-
out <- options
296302

297303
#######################################################
298304
# define the options for the sub-plots ----------------
299305
# the `alignpatches` tag is a string, it means regarding the
300306
# alignpatches as a single plot, instead of tag each sub-plots, so we
301307
# remove the tag
302-
if (is_string(prop(options, "tag"))) prop(options, "tag") <- NULL
308+
subplots_options <- options
309+
if (is_string(prop(subplots_options, "tag"))) {
310+
prop(subplots_options, "tag") <- NULL
311+
}
303312

304313
# Let each patch to determine the options
305314
options_list <- lapply(patches, function(patch) {
306-
patch$setup_options(options)
315+
patch$setup_options(subplots_options)
307316
})
317+
308318
# Always ensure that plots placed in a border collect their guides, if
309319
# any guides are to be collected in that border.
310320
# This prevents overlap, unless the guides will be collected by the
@@ -326,14 +336,19 @@ PatchAlignpatches <- ggproto(
326336
})
327337

328338
#######################################################
329-
self$collected <- collected
330-
self$borders_list <- borders_list
331-
self$options_list <- options_list
332-
self$area <- area
333-
self$dims <- dims
334-
self$panel_widths <- panel_widths
335-
self$panel_heights <- panel_heights
336-
out
339+
prop(options, "metadata", check = FALSE) <- c(
340+
metadata,
341+
list(
342+
collected = collected,
343+
borders_list = borders_list,
344+
options_list = options_list,
345+
area = area,
346+
dims = dims,
347+
panel_widths = panel_widths,
348+
panel_heights = panel_heights
349+
)
350+
)
351+
options
337352
},
338353

339354
#' @importFrom gtable gtable gtable_add_grob
@@ -342,25 +357,26 @@ PatchAlignpatches <- ggproto(
342357
#' @importFrom S7 prop prop<-
343358
#' @importFrom rlang arg_match0 is_empty
344359
gtable = function(self, options) {
345-
if (is.null(self$patches)) {
360+
metadata <- prop(options, "metadata")
361+
if (is.null(.subset2(metadata, "patches"))) {
346362
cli_abort("Run `$setup_options()` to initialize the patches first.")
347363
}
348364

349-
if (is_empty(self$patches)) {
365+
if (is_empty(.subset2(metadata, "patches"))) {
350366
return(make_patch_table())
351367
}
352368

353369
# prepare the output ---------------------------------
354370
gt <- gtable(
355-
unit(rep(0L, TABLE_COLS * self$dims[2L]), "null"),
356-
unit(rep(0L, TABLE_ROWS * self$dims[1L]), "null")
371+
unit(rep(0L, TABLE_COLS * metadata$dims[2L]), "null"),
372+
unit(rep(0L, TABLE_ROWS * metadata$dims[1L]), "null")
357373
)
358374

359375
# setup gtable list ----------------------------------
360-
gt_list <- guides_list <- vector("list", length(self$patches))
361-
for (i in seq_along(self$patches)) {
362-
patch_options <- .subset2(self$options_list, i)
363-
patch <- .subset2(self$patches, i)
376+
gt_list <- guides_list <- vector("list", length(metadata$patches))
377+
for (i in seq_along(metadata$patches)) {
378+
patch_options <- .subset2(metadata$options_list, i)
379+
patch <- .subset2(metadata$patches, i)
364380
components <- patch$decompose_guides(
365381
patch$gtable(patch_options),
366382
prop(patch_options, "guides")
@@ -387,7 +403,7 @@ PatchAlignpatches <- ggproto(
387403
1, 1, nrow(patch_gt), ncol(patch_gt), Inf
388404
)
389405
} else {
390-
loc <- vec_slice(self$area, i)
406+
loc <- vec_slice(metadata$area, i)
391407
l <- (field(loc, "l") - 1L) * TABLE_COLS + 1L
392408
r <- field(loc, "r") * TABLE_COLS
393409
t <- (field(loc, "t") - 1L) * TABLE_ROWS + 1L
@@ -400,26 +416,22 @@ PatchAlignpatches <- ggproto(
400416
}
401417
gt_list[i] <- list(patch_gt)
402418
}
403-
self$options_list <- NULL
404-
self$gt_list <- gt_list
405419

406420
# setup sizes for each row/column -----------------------
407421
gt <- self$set_sizes(
408-
self$patches, self$gt_list, self$area, self$dims,
409-
self$panel_widths, self$panel_heights,
422+
metadata$patches, gt_list,
423+
metadata$area, metadata$dims,
424+
metadata$panel_widths, metadata$panel_heights,
410425
gt = gt
411426
)
412-
self$panel_widths <- NULL
413-
self$panel_heights <- NULL
414427

415428
# add the panel position --------------------------------
416429
panel_pos <- list(
417430
t = TOP_BORDER + 1L,
418431
l = LEFT_BORDER + 1L,
419-
b = TABLE_ROWS * self$dims[1L] - BOTTOM_BORDER,
420-
r = TABLE_COLS * self$dims[2L] - RIGHT_BORDER
432+
b = TABLE_ROWS * metadata$dims[1L] - BOTTOM_BORDER,
433+
r = TABLE_COLS * metadata$dims[2L] - RIGHT_BORDER
421434
)
422-
self$dims <- NULL
423435

424436
# add guides into the final gtable ----------------------
425437
# Guide legends must be attached before calling `$set_grobs()`, because
@@ -429,16 +441,15 @@ PatchAlignpatches <- ggproto(
429441

430442
# Separate guide legends between those to be collected by the parent
431443
# `alignpatches()` and those that remain attached to this subplot.
432-
if (is.null(self$collected)) {
444+
if (is.null(metadata$collected)) {
433445
self$collected_guides <- list()
434446
} else {
435447
# Store guides to be collected by the parent `alignpatches()`
436-
self$collected_guides <- .subset(guides_list, self$collected)
448+
self$collected_guides <- .subset(guides_list, metadata$collected)
437449
guides_list <- .subset(
438450
guides_list,
439-
setdiff(names(guides_list), self$collected)
451+
setdiff(names(guides_list), metadata$collected)
440452
)
441-
self$collected <- NULL
442453
}
443454
theme <- prop(options, "theme")
444455
gt <- self$attach_guide_list(
@@ -471,12 +482,12 @@ PatchAlignpatches <- ggproto(
471482
)
472483

473484
# we only make the final grobs after sizes has been solved
474-
if (self$top_level) {
485+
if (metadata$top_level) {
475486
# we'll add background in ggalign_gtable() method
476487
self$set_grobs(
477-
patches = self$patches,
478-
gt_list = self$gt_list,
479-
area = self$area,
488+
patches = metadata$patches,
489+
gt_list = gt_list,
490+
area = metadata$area,
480491
gt = gt
481492
)
482493
} else {
@@ -488,6 +499,10 @@ PatchAlignpatches <- ggproto(
488499
name = "background", z = LAYOUT_BACKGROUND_Z
489500
)
490501
}
502+
self$patches <- metadata$patches
503+
self$gt_list <- gt_list
504+
self$borders_list <- metadata$borders_list
505+
self$area <- metadata$area
491506
gt
492507
}
493508
},

man/patch_options.Rd

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)