Skip to content

Commit 567006c

Browse files
authored
Element subclass inheritance (#5486)
* subclass inheritance * add tests * add news bullet
1 parent fc830ce commit 567006c

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

NEWS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# ggplot2 (development version)
22

3+
* In the theme element hierarchy, parent elements that are a strict subclass
4+
of child elements now confer their subclass upon the children (#5457).
5+
36
* `ggsave()` no longer sometimes creates new directories, which is now
47
controlled by the new `create.dir` argument (#5489).
58

R/theme.R

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,9 +783,21 @@ combine_elements <- function(e1, e2) {
783783
e1$linewidth <- e2$linewidth * unclass(e1$linewidth)
784784
}
785785

786+
# If e2 is 'richer' than e1, fill e2 with e1 parameters
787+
if (is.subclass(e2, e1)) {
788+
new <- defaults(e1, e2)
789+
e2[names(new)] <- new
790+
return(e2)
791+
}
792+
786793
e1
787794
}
788795

796+
is.subclass <- function(x, y) {
797+
inheritance <- inherits(x, class(y), which = TRUE)
798+
!any(inheritance == 0) && length(setdiff(class(x), class(y))) > 0
799+
}
800+
789801
#' Reports whether x is a theme object
790802
#' @param x An object to test
791803
#' @export

tests/testthat/test-theme.R

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,50 @@ test_that("Theme validation behaves as expected", {
509509
expect_snapshot_error(validate_element("A", "aspect.ratio", tree))
510510
})
511511

512+
test_that("Element subclasses are inherited", {
513+
514+
# `rich` is subclass of `poor`
515+
poor <- element_line(colour = "red", linetype = 3)
516+
rich <- element_line(linetype = 2, linewidth = 2)
517+
class(rich) <- c("element_rich", class(rich))
518+
519+
# `poor` should acquire `rich`
520+
test <- combine_elements(poor, rich)
521+
expect_s3_class(test, "element_rich")
522+
expect_equal(
523+
test[c("colour", "linetype", "linewidth")],
524+
list(colour = "red", linetype = 3, linewidth = 2)
525+
)
526+
527+
# `rich` should stay `rich`
528+
test <- combine_elements(rich, poor)
529+
expect_s3_class(test, "element_rich")
530+
expect_equal(
531+
test[c("colour", "linetype", "linewidth")],
532+
list(colour = "red", linetype = 2, linewidth = 2)
533+
)
534+
535+
# `sibling` is not strict subclass of `rich`
536+
sibling <- poor
537+
class(sibling) <- c("element_sibling", class(sibling))
538+
539+
# `sibling` should stay `sibling`
540+
test <- combine_elements(sibling, rich)
541+
expect_s3_class(test, "element_sibling")
542+
expect_equal(
543+
test[c("colour", "linetype", "linewidth")],
544+
list(colour = "red", linetype = 3, linewidth = 2)
545+
)
546+
547+
# `rich` should stay `rich`
548+
test <- combine_elements(rich, sibling)
549+
expect_s3_class(test, "element_rich")
550+
expect_equal(
551+
test[c("colour", "linetype", "linewidth")],
552+
list(colour = "red", linetype = 2, linewidth = 2)
553+
)
554+
})
555+
512556
test_that("Minor tick length supports biparental inheritance", {
513557
my_theme <- theme_gray() + theme(
514558
axis.ticks.length = unit(1, "cm"),

0 commit comments

Comments
 (0)