Skip to content

Commit af8e236

Browse files
authored
Refactor facet panel drawing code (#5917)
* isolate wrap panel initialisation * isolate wrap axis attachment * isolate wrap strip attachment * isolate grid panel initialisation * isolate grid axis attachment * isolate grid strip attachment * eliminate need for strips to know about axis size * make formals consistent * include all cases of grid strip/axis interactions in tests * use `seam_table()` helper * fix bug * remove duplicate test from #4669 * share init_gtable method * share majority of `draw_panels()` * add news bullet * Update snapshots for cli 3.6.3 * fix note
1 parent ba0b18a commit af8e236

File tree

12 files changed

+415
-365
lines changed

12 files changed

+415
-365
lines changed

NEWS.md

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

3+
* (internal) rearranged the code of `Facet$draw_paensl()` method (@teunbrand).
34
* `geom_rug()` prints a warning when `na.rm = FALSE`, as per documentation (@pn317, #5905)
45
* `position_dodge(preserve = "single")` now handles multi-row geoms better,
56
such as `geom_violin()` (@teunbrand based on @clauswilke's work, #2801).

R/facet-.R

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,32 @@ Facet <- ggproto("Facet", NULL,
133133
draw_front = function(data, layout, x_scales, y_scales, theme, params) {
134134
rep(list(zeroGrob()), vec_unique_count(layout$PANEL))
135135
},
136-
draw_panels = function(panels, layout, x_scales, y_scales, ranges, coord, data, theme, params) {
137-
cli::cli_abort("Not implemented.")
136+
draw_panels = function(self, panels, layout, x_scales = NULL, y_scales = NULL,
137+
ranges, coord, data = NULL, theme, params) {
138+
139+
free <- params$free %||% list(x = FALSE, y = FALSE)
140+
space <- params$space_free %||% list(x = FALSE, y = FALSE)
141+
142+
if ((free$x || free$y) && !coord$is_free()) {
143+
cli::cli_abort(
144+
"{.fn {snake_class(self)}} can't use free scales with \\
145+
{.fn {snake_class(coord)}}."
146+
)
147+
}
148+
149+
aspect_ratio <- theme$aspect.ratio
150+
if (!is.null(aspect_ratio) && (space$x || space$y)) {
151+
cli::cli_abort("Free scales cannot be mixed with a fixed aspect ratio.")
152+
}
153+
154+
table <- self$init_gtable(
155+
panels, layout, theme, ranges, params,
156+
aspect_ratio = aspect_ratio %||% coord$aspect(ranges[[1]]),
157+
clip = coord$clip
158+
)
159+
160+
table <- self$attach_axes(table, layout, ranges, coord, theme, params)
161+
self$attach_strips(table, layout, params, theme)
138162
},
139163
draw_labels = function(panels, layout, x_scales, y_scales, ranges, coord, data, theme, labels, params) {
140164
panel_dim <- find_panel(panels)
@@ -173,6 +197,64 @@ Facet <- ggproto("Facet", NULL,
173197
finish_data = function(data, layout, x_scales, y_scales, params) {
174198
data
175199
},
200+
init_gtable = function(panels, layout, theme, ranges, params,
201+
aspect_ratio = NULL, clip = "on") {
202+
203+
# Initialise matrix of panels
204+
dim <- c(max(layout$ROW), max(layout$COL))
205+
table <- matrix(list(zeroGrob()), dim[1], dim[2])
206+
table[cbind(layout$ROW, layout$COL)] <- panels
207+
208+
# Set initial sizes
209+
widths <- unit(rep(1, dim[2]), "null")
210+
heights <- unit(rep(1 * abs(aspect_ratio %||% 1), dim[1]), "null")
211+
212+
# When space are free, let panel parameter limits determine size of panel
213+
space <- params$space_free %||% list(x = FALSE, y = FALSE)
214+
if (space$x) {
215+
idx <- layout$PANEL[layout$ROW == 1]
216+
widths <- vapply(idx, function(i) diff(ranges[[i]]$x.range), numeric(1))
217+
widths <- unit(widths, "null")
218+
}
219+
220+
if (space$y) {
221+
idx <- layout$PANEL[layout$COL == 1]
222+
heights <- vapply(idx, function(i) diff(ranges[[i]]$y.range), numeric(1))
223+
heights <- unit(heights, "null")
224+
}
225+
226+
# Build gtable
227+
table <- gtable_matrix(
228+
"layout", table,
229+
widths = widths, heights = heights,
230+
respect = !is.null(aspect_ratio),
231+
clip = clip, z = matrix(1, dim[1], dim[2])
232+
)
233+
234+
# Set panel names
235+
table$layout$name <- paste(
236+
"panel",
237+
rep(seq_len(dim[2]), dim[1]),
238+
rep(seq_len(dim[1]), each = dim[2]),
239+
sep = "-"
240+
)
241+
242+
# Add spacing between panels
243+
spacing <- lapply(
244+
c(x = "panel.spacing.x", y = "panel.spacing.y"),
245+
calc_element, theme = theme
246+
)
247+
248+
table <- gtable_add_col_space(table, spacing$x)
249+
table <- gtable_add_row_space(table, spacing$y)
250+
table
251+
},
252+
attach_axes = function(table, layout, ranges, coord, theme, params) {
253+
table
254+
},
255+
attach_strips = function(table, layout, params, theme) {
256+
table
257+
},
176258
vars = function() {
177259
character(0)
178260
}

0 commit comments

Comments
 (0)