From 90ae274d0a54b0cae1770729569ab1a50c54ffc9 Mon Sep 17 00:00:00 2001 From: Teun van den Brand <49372158+teunbrand@users.noreply.github.com> Date: Mon, 16 Oct 2023 10:33:27 +0200 Subject: [PATCH 1/3] subclass inheritance --- R/theme.R | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/R/theme.R b/R/theme.R index 33cf0244cd..42fcb1363d 100644 --- a/R/theme.R +++ b/R/theme.R @@ -767,9 +767,21 @@ combine_elements <- function(e1, e2) { e1$linewidth <- e2$linewidth * unclass(e1$linewidth) } + # If e2 is 'richer' than e1, fill e2 with e1 parameters + if (is.subclass(e2, e1)) { + new <- defaults(e1, e2) + e2[names(new)] <- new + return(e2) + } + e1 } +is.subclass <- function(x, y) { + inheritance <- inherits(x, class(y), which = TRUE) + !any(inheritance == 0) && length(setdiff(class(x), class(y))) > 0 +} + #' Reports whether x is a theme object #' @param x An object to test #' @export From bcf2155d9681c5b691ad92ebe3e1f2b38ef5f84d Mon Sep 17 00:00:00 2001 From: Teun van den Brand <49372158+teunbrand@users.noreply.github.com> Date: Mon, 16 Oct 2023 10:33:33 +0200 Subject: [PATCH 2/3] add tests --- tests/testthat/test-theme.R | 45 +++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/tests/testthat/test-theme.R b/tests/testthat/test-theme.R index 7bf37c90e1..db239b710f 100644 --- a/tests/testthat/test-theme.R +++ b/tests/testthat/test-theme.R @@ -509,6 +509,51 @@ test_that("Theme validation behaves as expected", { expect_snapshot_error(validate_element("A", "aspect.ratio", tree)) }) +test_that("Element subclasses are inherited", { + + # `rich` is subclass of `poor` + poor <- element_line(colour = "red", linetype = 3) + rich <- element_line(linetype = 2, linewidth = 2) + class(rich) <- c("element_rich", class(rich)) + + # `poor` should acquire `rich` + test <- combine_elements(poor, rich) + expect_s3_class(test, "element_rich") + expect_equal( + test[c("colour", "linetype", "linewidth")], + list(colour = "red", linetype = 3, linewidth = 2) + ) + + # `rich` should stay `rich` + test <- combine_elements(rich, poor) + expect_s3_class(test, "element_rich") + expect_equal( + test[c("colour", "linetype", "linewidth")], + list(colour = "red", linetype = 2, linewidth = 2) + ) + + # `sibling` is not strict subclass of `rich` + sibling <- poor + class(sibling) <- c("element_sibling", class(sibling)) + + # `sibling` should stay `sibling` + test <- combine_elements(sibling, rich) + expect_s3_class(test, "element_sibling") + expect_equal( + test[c("colour", "linetype", "linewidth")], + list(colour = "red", linetype = 3, linewidth = 2) + ) + + # `rich` should stay `rich` + test <- combine_elements(rich, sibling) + expect_s3_class(test, "element_rich") + expect_equal( + test[c("colour", "linetype", "linewidth")], + list(colour = "red", linetype = 2, linewidth = 2) + ) + +}) + # Visual tests ------------------------------------------------------------ test_that("aspect ratio is honored", { From bef9bb37291058fffaf3e6a0fa57eb7e4e9e7972 Mon Sep 17 00:00:00 2001 From: Teun van den Brand <49372158+teunbrand@users.noreply.github.com> Date: Mon, 16 Oct 2023 11:01:03 +0200 Subject: [PATCH 3/3] add news bullet --- NEWS.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS.md b/NEWS.md index 254c49abd1..33c894caae 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # ggplot2 (development version) +* In the theme element hierarchy, parent elements that are a strict subclass + of child elements now confer their subclass upon the children (#5457). + * Legend titles no longer take up space if they've been removed by setting `legend.title = element_blank()` (@teunbrand, #3587).