diff --git a/DESCRIPTION b/DESCRIPTION index da78c46c3d..c2116522eb 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -177,7 +177,6 @@ Collate: 'ggplot2-package.R' 'grob-absolute.R' 'grob-dotstack.R' - 'grob-null.R' 'grouping.R' 'properties.R' 'margins.R' diff --git a/NAMESPACE b/NAMESPACE index ce32705b6d..bf4d62e93a 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -20,7 +20,6 @@ S3method(as.list,ggproto) S3method(autolayer,default) S3method(autoplot,default) S3method(c,mapped_discrete) -S3method(drawDetails,zeroGrob) S3method(format,ggproto) S3method(format,ggproto_method) S3method(format,rd_section_aesthetics) @@ -52,9 +51,7 @@ S3method(ggplot,default) S3method(ggplot_add,default) S3method(grid.draw,absoluteGrob) S3method(grobHeight,absoluteGrob) -S3method(grobHeight,zeroGrob) S3method(grobWidth,absoluteGrob) -S3method(grobWidth,zeroGrob) S3method(grobX,absoluteGrob) S3method(grobY,absoluteGrob) S3method(guide_gengrob,default) @@ -63,7 +60,6 @@ S3method(guide_merge,default) S3method(guide_train,default) S3method(guide_transform,default) S3method(heightDetails,titleGrob) -S3method(heightDetails,zeroGrob) S3method(limits,Date) S3method(limits,POSIXct) S3method(limits,POSIXlt) @@ -117,7 +113,6 @@ S3method(vec_ptype2,mapped_discrete.factor) S3method(vec_ptype2,mapped_discrete.integer) S3method(vec_ptype2,mapped_discrete.mapped_discrete) S3method(widthDetails,titleGrob) -S3method(widthDetails,zeroGrob) export("%+%") export("%+replace%") export(.data) diff --git a/NEWS.md b/NEWS.md index 829d029bb5..7fab21a27a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,6 @@ # ggplot2 (development version) +* (internal) `zeroGrob()` now returns a `grid::nullGrob()` (#6390). * `stat_ydensity()` now only requires the `x` or `y` aesthetic. The other will be populated with 0, similar to `stat_boxplot()` (@teunbrand, #6600) * Implemented `as.list()` and `S7::convert()` methods for lists and classes in ggplot2 diff --git a/R/aes-variants.R b/R/aes-variants.R index 264151f2bb..12851c5cd6 100644 --- a/R/aes-variants.R +++ b/R/aes-variants.R @@ -113,8 +113,7 @@ aes_all <- function(vars) { # Quosure the symbols in the empty environment because they can only # refer to the data mask x <- class_mapping(lapply(vars, function(x) new_quosure(as.name(x), emptyenv()))) - class(x) <- union("unlabelled", class(x)) - x + add_class(x, "unlabelled") } #' Automatic aesthetic mapping diff --git a/R/grob-null.R b/R/grob-null.R deleted file mode 100644 index da32009b3b..0000000000 --- a/R/grob-null.R +++ /dev/null @@ -1,26 +0,0 @@ -#' The zero grob draws nothing and has zero size. -#' -#' @keywords internal -#' @export -zeroGrob <- function() .zeroGrob - -.zeroGrob <- NULL -on_load(.zeroGrob <- grob(cl = "zeroGrob", name = "NULL")) - -#' @export -#' @method widthDetails zeroGrob -widthDetails.zeroGrob <- function(x) unit(0, "cm") -#' @export -#' @method heightDetails zeroGrob -heightDetails.zeroGrob <- function(x) unit(0, "cm") -#' @export -#' @method grobWidth zeroGrob -grobWidth.zeroGrob <- function(x) unit(0, "cm") -#' @export -#' @method grobHeight zeroGrob -grobHeight.zeroGrob <- function(x) unit(0, "cm") -#' @export -#' @method drawDetails zeroGrob -drawDetails.zeroGrob <- function(x, recording) {} - -is_zero <- function(x) is.null(x) || inherits(x, "zeroGrob") diff --git a/R/theme.R b/R/theme.R index 79143ec0b5..d263ff0fe6 100644 --- a/R/theme.R +++ b/R/theme.R @@ -501,7 +501,7 @@ theme <- function(..., } t <- class_theme(elements, complete = complete, validate = validate) - class(t) <- union("theme", class(t)) + t <- add_class(t, "theme") t } diff --git a/R/utilities-grid.R b/R/utilities-grid.R index 4713d62893..a6fdf81fed 100644 --- a/R/utilities-grid.R +++ b/R/utilities-grid.R @@ -53,6 +53,17 @@ gg_par <- function(..., stroke = NULL, pointsize = NULL) { inject(gpar(!!!args)) } +#' The zero grob draws nothing and has zero size. +#' +#' @keywords internal +#' @export +zeroGrob <- function() .zeroGrob + +.zeroGrob <- NULL +on_load(.zeroGrob <- add_class(nullGrob(), "zeroGrob")) + +is_zero <- function(x) is.null(x) || inherits(x, "null") + width_cm <- function(x) { if (is.grob(x)) { convertWidth(grobWidth(x), "cm", TRUE) diff --git a/R/utilities.R b/R/utilities.R index 93464a89af..e42a72c8cb 100644 --- a/R/utilities.R +++ b/R/utilities.R @@ -942,6 +942,15 @@ compute_data_size <- function(data, size, default = 0.9, data } +add_class <- function(x, new_class) { + new_class <- setdiff(new_class, class(x)) + if (length(new_class) < 1) { + return(x) + } + class(x) <- union(new_class, class(x)) + x +} + try_prop <- function(object, name, default = NULL) { if (!S7::S7_inherits(object)) { return(default) diff --git a/man/zeroGrob.Rd b/man/zeroGrob.Rd index e4aac88eb0..6fcfe56218 100644 --- a/man/zeroGrob.Rd +++ b/man/zeroGrob.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/grob-null.R +% Please edit documentation in R/utilities-grid.R \name{zeroGrob} \alias{zeroGrob} \title{The zero grob draws nothing and has zero size.} diff --git a/tests/testthat/_snaps/theme-elements.md b/tests/testthat/_snaps/theme-elements.md index f3931ef6b0..936112d821 100644 --- a/tests/testthat/_snaps/theme-elements.md +++ b/tests/testthat/_snaps/theme-elements.md @@ -64,10 +64,8 @@ --- Code - element_grob(el, label = element_blank()) + x <- element_grob(el, label = element_blank()) Condition Warning: `label` cannot be a object. - Output - zeroGrob[NULL] diff --git a/tests/testthat/test-facet-.R b/tests/testthat/test-facet-.R index b93b8237ab..e09caa2d99 100644 --- a/tests/testthat/test-facet-.R +++ b/tests/testthat/test-facet-.R @@ -160,7 +160,7 @@ test_that("strips can be removed", { theme(strip.background = element_blank(), strip.text = element_blank()) g_grobs <- ggplotGrob(g) strip_grobs <- g_grobs$grobs[grepl('strip-', g_grobs$layout$name)] - expect_true(all(sapply(strip_grobs, inherits, 'zeroGrob'))) + expect_true(all(sapply(strip_grobs, inherits, 'null'))) }) test_that("strip clipping can be set from the theme", { diff --git a/tests/testthat/test-stat-density2d.R b/tests/testthat/test-stat-density2d.R index 43a99e9513..2e2896cc47 100644 --- a/tests/testthat/test-stat-density2d.R +++ b/tests/testthat/test-stat-density2d.R @@ -100,5 +100,5 @@ test_that("stat_density_2d handles faulty bandwidth", { p <- ggplot(faithful, aes(eruptions, waiting)) + stat_density_2d(h = c(0, NA)) expect_snapshot_warning(b <- ggplot_build(p)) - expect_s3_class(layer_grob(b)[[1]], "zeroGrob") + expect_s3_class(layer_grob(b)[[1]], "null") }) diff --git a/tests/testthat/test-theme-elements.R b/tests/testthat/test-theme-elements.R index d74b35b5c3..76ef1ae7cd 100644 --- a/tests/testthat/test-theme-elements.R +++ b/tests/testthat/test-theme-elements.R @@ -100,7 +100,7 @@ test_that("element_text throws appropriate conditions", { # labs(y = element_blank()) for some reason el <- theme_get()$text expect_snapshot( - element_grob(el, label = element_blank()) + x <- element_grob(el, label = element_blank()) ) })