@@ -74,7 +74,79 @@ new_guide <- function(..., available_aes = "any", super) {
7474# ' To create a new type of Guide object, you typically will want to override
7575# ' one or more of the following:
7676# '
77- # ' TODO: Fill this in properly
77+ # ' Properties:
78+ # '
79+ # ' - `available_aes` A `character` vector with aesthetics that this guide
80+ # ' supports. The value `"any"` indicates all non-position aesthetics.
81+ # '
82+ # ' - `params` A named `list` of parameters that the guide needs to function.
83+ # ' It has the following roles:
84+ # '
85+ # ' - `params` provides the defaults for a guide.
86+ # ' - `names(params)` determines what are valid arguments to `new_guide()`.
87+ # ' Some parameters are *required* to render the guide. These are: `title`,
88+ # ' `name`, `position`, `direction`, `order` and `hash`.
89+ # ' - During build stages, `params` holds information about the guide.
90+ # '
91+ # ' - `elements` A named list of `character`s, giving the name of theme elements
92+ # ' that should be retrieved automatically, for example `"legend.text"`.
93+ # '
94+ # ' - `hashables` An `expression` that can be evaluated in the context of
95+ # ' `params`. The hash of the evaluated expression determines the merge
96+ # ' compatibility of guides, and is stored in `params$hash`.
97+ # '
98+ # ' Methods:
99+ # '
100+ # ' - `extract_key()` Returns a `data.frame` with (mapped) breaks and labels
101+ # ' extracted from the scale, which will be stored in `params$key`.
102+ # '
103+ # ' - `extract_decor()` Returns a `data.frame` containing other structured
104+ # ' information extracted from the scale, which will be stored in
105+ # ' `params$decor`. The `decor` has a guide-specific meaning: it is the bar in
106+ # ' `guide_colourbar()`, but specifies the `axis.line` in `guide_axis()`.
107+ # '
108+ # ' - `extract_params()` Updates the `params` with other, unstructured
109+ # ' information from the scale. An example of this is inheriting the guide's
110+ # ' title from the `scale$name` field.
111+ # '
112+ # ' - `transform()` Updates the `params$key` based on the coordinates. This
113+ # ' applies to position guides, as it rescales the aesthetic to the \[0, 1\]
114+ # ' range.
115+ # '
116+ # ' - `merge()` Combines information from multiple guides with the same
117+ # ' `params$hash`. This ensures that e.g. `guide_legend()` can display both
118+ # ' `shape` and `colour` in the same guide.
119+ # '
120+ # ' - `get_layer_key()` Extract information from layers. This can be used to
121+ # ' check that the guide's aesthetic is actually in use, or to gather
122+ # ' information about how legend keys should be displayed.
123+ # '
124+ # ' - `setup_params()` Set up parameters at the beginning of drawing stages.
125+ # ' It can be used to overrule user-supplied parameters or perform checks on
126+ # ' the `params` property.
127+ # '
128+ # ' - `override_elements()` Take populated theme elements derived from the
129+ # ' `elements` property and allows overriding these theme settings.
130+ # '
131+ # ' - `build_title()` Render the guide's title.
132+ # '
133+ # ' - `build_labels()` Render the guide's labels.
134+ # '
135+ # ' - `build_decor()` Render the `params$decor`, which is different for every
136+ # ' guide.
137+ # '
138+ # ' - `build_ticks()` Render tick marks.
139+ # '
140+ # ' - `measure_grobs()` Measure dimensions of the graphical objects produced
141+ # ' by the `build_*()` methods to be used in the layout or assembly.
142+ # '
143+ # ' - `arrange_layout()` Set up a layout for how graphical objects produced by
144+ # ' the `build_*()` methods should be arranged.
145+ # '
146+ # ' - `assemble_drawing()` Take the graphical objects produced by the `build_*()`
147+ # ' methods, the measurements from `measure_grobs()` and layout from
148+ # ' `arrange_layout()` to finalise the guide.
149+ # '
78150# ' @rdname ggplot2-ggproto
79151# ' @format NULL
80152# ' @usage NULL
@@ -117,14 +189,15 @@ Guide <- ggproto(
117189 return (NULL )
118190 }
119191 params $ decor <- inject(self $ extract_decor(scale , !!! params ))
120- self $ extract_params(scale , params , self $ hashables , ... )
192+ params <- self $ extract_params(scale , params , ... )
193+ # Make hash
194+ # TODO: Maybe we only need the hash on demand during merging?
195+ params $ hash <- hash(lapply(unname(self $ hashables ), eval_tidy , data = params ))
196+ params
121197 },
122198
123199 # Setup parameters that are only available after training
124- # TODO: Maybe we only need the hash on demand during merging?
125- extract_params = function (scale , params , hashables , ... ) {
126- # Make hash
127- params $ hash <- hash(lapply(unname(hashables ), eval_tidy , data = params ))
200+ extract_params = function (scale , params , ... ) {
128201 params
129202 },
130203
@@ -137,13 +210,18 @@ Guide <- ggproto(
137210
138211 mapped <- scale $ map(breaks )
139212 labels <- scale $ get_labels(breaks )
213+ # {vctrs} doesn't play nice with expressions, convert to list.
214+ # see also https://github.com/r-lib/vctrs/issues/559
215+ if (is.expression(labels )) {
216+ labels <- as.list(labels )
217+ }
140218
141219 key <- data_frame(mapped , .name_repair = ~ aesthetic )
142220 key $ .value <- breaks
143221 key $ .label <- labels
144222
145223 if (is.numeric(breaks )) {
146- key [ is.finite(breaks ), , drop = FALSE ]
224+ vec_slice( key , is.finite(breaks ))
147225 } else {
148226 key
149227 }
@@ -342,3 +420,14 @@ flip_names = c(
342420# Shortcut for position argument matching
343421.trbl <- c(" top" , " right" , " bottom" , " left" )
344422
423+ # Ensure that labels aren't a list of expressions, but proper expressions
424+ validate_labels <- function (labels ) {
425+ if (! is.list(labels )) {
426+ return (labels )
427+ }
428+ if (any(vapply(labels , is.language , logical (1 )))) {
429+ do.call(expression , labels )
430+ } else {
431+ unlist(labels )
432+ }
433+ }
0 commit comments