I think I found a nice example that can be considered for the book. From R 4.2+, the {grid} package has added the option to do outline strokes for text. The example defines a new text element that draws outlined text instead of regular text.
For the class constructor, it shows how to (1) allow alternate spellings of color/colour (2) how to structure a class and (3) how to inherit from element_text.
library(ggplot2)
library(grid)
library(rlang)
element_text_outline <- function(
family = NULL, face = NULL, colour = NULL, fill = NULL,
size = NULL, hjust = NULL, vjust = NULL, angle = NULL,
lineheight = NULL, linewidth = NULL,
color = NULL, margin = NULL, inherit.blank = FALSE
) {
# Allow both spellings of colo(u)r
if (!is.null(color)) {
colour <- color
}
structure(
# The core of the class is a list of parameters
list(
family = family,
face = face,
colour = colour,
fill = fill,
size = size,
hjust = hjust,
vjust = vjust,
angle = angle,
lineheight = lineheight,
linewidth = linewidth,
margin = margin,
inherit.blank = inherit.blank
),
# The class should inherit from one of the existing classes
class = c("element_text_outline", "element_text", "element")
)
}
The grob drawing code avoids getting into the nitty {grid}dy of margins and such by recycling the element_text's code with NextMethod(). It also shows the override rules that arguments provided to element_grob() should override those provided by the element itself.
element_grob.element_text_outline <- function(
element,
# If we're using the parent's method, we can save ourselves
# some space by using the ellipsis.
...,
fill = NULL,
linewidth = NULL
) {
# You can use the parent class' method to draw the basic grob
text <- NextMethod()
# Provided arguments should override the element's settings
fill <- fill %||% element$fill
linewidth <- linewidth %||% element$linewidth
gp <- gpar(fill = fill, lwd = linewidth)
# Wrap every textGrob inside a fillStrokeGrob
text$children <- lapply(text$children, fillStrokeGrob, gp = gp)
text
}
Finally, an example plot to show that the new element can be used in various places.
It was pointed out to me that the ggplot2 book might look for an example of extending theme elements,
https://github.com/hadley/ggplot2-book/blob/01734fa9361eb1ce6ff954d77fa2d6c01f10430b/extensions.Rmd#L21
I think I found a nice example that can be considered for the book. From R 4.2+, the {grid} package has added the option to do outline strokes for text. The example defines a new text element that draws outlined text instead of regular text.
For the class constructor, it shows how to (1) allow alternate spellings of color/colour (2) how to structure a class and (3) how to inherit from
element_text
.The grob drawing code avoids getting into the nitty {grid}dy of margins and such by recycling the
element_text
's code withNextMethod()
. It also shows the override rules that arguments provided toelement_grob()
should override those provided by the element itself.Finally, an example plot to show that the new element can be used in various places.
Created on 2022-08-10 by the reprex package (v2.0.1)
One drawback is that {ragg} does not (yet) support these R 4.2 features, so this reprex was rendered with: