Skip to content

Commit 8dda7b0

Browse files
committed
theme gains a new element panel.merge to control whether to merge panel area into single gTree
1 parent 183e7ad commit 8dda7b0

File tree

9 files changed

+109
-58
lines changed

9 files changed

+109
-58
lines changed

R/coord-.R

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -211,17 +211,7 @@ Coord <- ggproto("Coord",
211211
},
212212

213213
draw_panel = function(self, panel, params, theme) {
214-
fg <- self$render_fg(params, theme)
215-
bg <- self$render_bg(params, theme)
216-
if (isTRUE(theme$panel.ontop)) {
217-
panel <- list2(!!!panel, bg, fg)
218-
} else {
219-
panel <- list2(bg, !!!panel, fg)
220-
}
221-
gTree(
222-
children = inject(gList(!!!panel)),
223-
vp = viewport(clip = self$clip)
224-
)
214+
insert_vp(panel, viewport(clip = self$clip))
225215
}
226216
)
227217

R/coord-radial.R

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,6 @@ CoordRadial <- ggproto("CoordRadial", Coord,
370370
)
371371
},
372372

373-
374373
draw_panel = function(self, panel, params, theme) {
375374
clip_support <- check_device("clippingPaths", "test", maybe = TRUE)
376375
if (self$clip == "on" && !isFALSE(clip_support)) {
@@ -383,10 +382,7 @@ CoordRadial <- ggproto("CoordRadial", Coord,
383382
# Note that clipping path is applied to panel without coord
384383
# foreground/background (added in parent method).
385384
# These may contain decorations that needn't be clipped
386-
panel <- list(gTree(
387-
children = inject(gList(!!!panel)),
388-
vp = viewport(clip = clip_path)
389-
))
385+
panel <- insert_vp(panel, viewport(clip = clip_path))
390386
}
391387
ggproto_parent(Coord, self)$draw_panel(panel, params, theme)
392388
},

R/facet-.R

Lines changed: 88 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,12 @@ Facet <- ggproto("Facet", NULL,
155155
}
156156
}
157157

158+
facet_bg <- self$draw_back(data, layout, x_scales, y_scales, theme, params)
159+
facet_fg <- self$draw_front(data, layout, x_scales, y_scales, theme, params)
160+
158161
table <- self$init_gtable(
159-
panels, layout, theme, ranges, params,
162+
panels, facet_bg, facet_fg,
163+
coord, layout, theme, ranges, params,
160164
aspect_ratio = aspect_ratio %||% coord$aspect(ranges[[1]])
161165
)
162166

@@ -200,13 +204,12 @@ Facet <- ggproto("Facet", NULL,
200204
finish_data = function(data, layout, x_scales, y_scales, params) {
201205
data
202206
},
203-
init_gtable = function(panels, layout, theme, ranges, params,
207+
init_gtable = function(panels, facet_bg, facet_fg,
208+
coord, layout, theme, ranges, params,
204209
aspect_ratio = NULL) {
205210

206-
# Initialise matrix of panels
211+
# gtable dimentions
207212
dim <- c(max(layout$ROW), max(layout$COL))
208-
table <- matrix(list(zeroGrob()), dim[1], dim[2])
209-
table[cbind(layout$ROW, layout$COL)] <- panels
210213

211214
# Set initial sizes
212215
widths <- unit(rep(1, dim[2]), "null")
@@ -227,20 +230,56 @@ Facet <- ggproto("Facet", NULL,
227230
}
228231

229232
# Build gtable
230-
table <- gtable_matrix(
231-
"layout", table,
232-
widths = widths, heights = heights,
233-
respect = !is.null(aspect_ratio),
234-
clip = "off", z = matrix(1, dim[1], dim[2])
235-
)
236-
237-
# Set panel names
238-
table$layout$name <- paste(
239-
"panel",
240-
rep(seq_len(dim[2]), each = dim[1]),
241-
rep(seq_len(dim[1]), dim[2]),
242-
sep = "-"
233+
table <- gtable(widths = widths, heights = heights,
234+
name = "layout", respect = !is.null(aspect_ratio)
243235
)
236+
if (isTRUE(theme$panel.merge %||% TRUE)) {
237+
panels <- merge_panels(panels, facet_bg, facet_fg, ranges, theme, coord)
238+
table <- gtable_add_grob(
239+
table, panels,
240+
t = layout$ROW,
241+
l = layout$COL,
242+
z = 1,
243+
name = paste("panel", layout$COL, layout$ROW, sep = "-")
244+
)
245+
} else {
246+
coord_fg <- lapply(seq_along(panels[[1]]), function(i) {
247+
coord_fg <- coord$render_fg(ranges[[i]], theme)
248+
ggproto_parent(Coord, coord)$draw_panel(coord_fg, ranges[[i]], theme)
249+
})
250+
coord_bg <- lapply(seq_along(panels[[1]]), function(i) {
251+
coord_bg <- coord$render_bg(ranges[[i]], theme)
252+
ggproto_parent(Coord, coord)$draw_panel(coord_bg, ranges[[i]], theme)
253+
})
254+
names <- paste("layer", seq_along(panels), sep = "-")
255+
panels <- c(list(facet_bg), panels, list(facet_fg))
256+
names <- c("facet-bg", names, "facet-fg")
257+
panels <- lapply(panels, function(panel) {
258+
# let Coord modify the panel
259+
lapply(seq_along(panel), function(i) {
260+
coord$draw_panel(panel[[i]], ranges[[i]], theme)
261+
})
262+
})
263+
264+
if (isTRUE(theme$panel.ontop)) {
265+
panels <- c(panels, list(coord_bg), list(coord_fg))
266+
names <- c(names, "coord-bg", "coord-fg")
267+
} else {
268+
panels <- c(list(coord_bg), panels, list(coord_fg))
269+
names <- c("coord-bg", names, "coord-fg")
270+
}
271+
for (i in seq_along(panels)) {
272+
table <- gtable_add_grob(
273+
table, panels[[i]],
274+
t = layout$ROW,
275+
l = layout$COL,
276+
# when drawing, the grob with the same `z` will be drawn in the
277+
# ordering they added
278+
z = 1,
279+
name = paste("panel", layout$COL, layout$ROW, names[[i]], sep = "-")
280+
)
281+
}
282+
}
244283

245284
# Add spacing between panels
246285
spacing <- lapply(
@@ -898,7 +937,7 @@ map_facet_data <- function(data, layout, params) {
898937
# Compute faceting values
899938
facet_vals <- eval_facets(vars, data, params$.possible_columns)
900939

901-
include_margins <- !isFALSE(params$margin %||% FALSE) &&
940+
include_margins <- !isFALSE(params$margins %||% FALSE) &&
902941
nrow(facet_vals) == nrow(data) && grid_layout
903942
if (include_margins) {
904943
# Margins are computed on evaluated faceting values (#1864).
@@ -964,3 +1003,33 @@ map_facet_data <- function(data, layout, params) {
9641003

9651004
data
9661005
}
1006+
1007+
merge_panels <- function(panels, facet_bg, facet_fg, ranges, theme, coord) {
1008+
lapply(seq_along(panels[[1]]), function(i) {
1009+
# merge panel
1010+
panel <- lapply(panels, `[[`, i)
1011+
panel <- c(facet_bg[i], panel, facet_fg[i])
1012+
panel <- gTree(children = inject(gList(!!!panel)))
1013+
1014+
# let Coord modify the panel
1015+
panel <- coord$draw_panel(panel, ranges[[i]], theme)
1016+
1017+
# in the end, we add foreground and background
1018+
# we always ensure the `fg` and `bg` follow the Coord `clip` argument
1019+
coord_fg <- coord$render_fg(ranges[[i]], theme)
1020+
coord_fg <- ggproto_parent(Coord, coord)$draw_panel(
1021+
coord_fg, ranges[[i]], theme
1022+
)
1023+
coord_bg <- coord$render_bg(ranges[[i]], theme)
1024+
coord_bg <- ggproto_parent(Coord, coord)$draw_panel(
1025+
coord_bg, ranges[[i]], theme
1026+
)
1027+
if (isTRUE(theme$panel.ontop)) {
1028+
panel <- list(panel, coord_bg, coord_fg)
1029+
} else {
1030+
panel <- list(coord_bg, panel, coord_fg)
1031+
}
1032+
panel <- gTree(children = inject(gList(!!!panel)))
1033+
ggname(paste("panel", i, sep = "-"), panel)
1034+
})
1035+
}

R/facet-null.R

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,13 @@ FacetNull <- ggproto("FacetNull", Facet,
4242
data$PANEL <- factor(1)
4343
data
4444
},
45-
draw_panels = function(panels, layout, x_scales, y_scales, ranges, coord, data, theme, params) {
45+
draw_panels = function(self, panels, layout, x_scales, y_scales, ranges, coord, data, theme, params) {
4646

47+
facet_bg <- self$draw_back(data, layout, x_scales, y_scales, theme, params)
48+
facet_fg <- self$draw_front(data, layout, x_scales, y_scales, theme, params)
49+
50+
# For FacetNull, we always merege the panel area
51+
panels <- merge_panels(panels, facet_bg, facet_fg, ranges, theme, coord)
4752
range <- ranges[[1]]
4853

4954
# Figure out aspect ratio

R/layout.R

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -60,29 +60,7 @@ Layout <- ggproto("Layout", NULL,
6060
# Assemble the facet fg & bg, the coord fg & bg, and the layers
6161
# Returns a gtable
6262
render = function(self, panels, data, theme, labels) {
63-
facet_bg <- self$facet$draw_back(data,
64-
self$layout,
65-
self$panel_scales_x,
66-
self$panel_scales_y,
67-
theme,
68-
self$facet_params
69-
)
70-
facet_fg <- self$facet$draw_front(
71-
data,
72-
self$layout,
73-
self$panel_scales_x,
74-
self$panel_scales_y,
75-
theme,
76-
self$facet_params
77-
)
78-
7963
# Draw individual panels, then assemble into gtable
80-
panels <- lapply(seq_along(panels[[1]]), function(i) {
81-
panel <- lapply(panels, `[[`, i)
82-
panel <- c(facet_bg[i], panel, facet_fg[i])
83-
panel <- self$coord$draw_panel(panel, self$panel_params[[i]], theme)
84-
ggname(paste("panel", i, sep = "-"), panel)
85-
})
8664
plot_table <- self$facet$draw_panels(
8765
panels,
8866
self$layout,

R/theme-defaults.R

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ theme_grey <- function(base_size = 11, base_family = "",
231231
panel.spacing.x = NULL,
232232
panel.spacing.y = NULL,
233233
panel.ontop = FALSE,
234+
panel.merge = TRUE,
234235

235236
strip.background = element_rect(fill = col_mix(ink, paper, 0.854), colour = NA),
236237
strip.clip = "on",
@@ -567,6 +568,7 @@ theme_void <- function(base_size = 11, base_family = "",
567568
strip.switch.pad.wrap = rel(0.5),
568569
strip.background = element_blank(),
569570
panel.ontop = FALSE,
571+
panel.merge = TRUE,
570572
panel.spacing = NULL,
571573
panel.background = element_blank(),
572574
panel.border = element_blank(),
@@ -713,6 +715,7 @@ theme_test <- function(base_size = 11, base_family = "",
713715
panel.spacing.x = NULL,
714716
panel.spacing.y = NULL,
715717
panel.ontop = FALSE,
718+
panel.merge = TRUE,
716719

717720
strip.background = element_rect(
718721
fill = col_mix(ink, paper, 0.851),

R/theme-elements.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,7 @@ el_def <- function(class = NULL, inherit = NULL, description = NULL) {
758758
panel.grid.minor.x = el_def("element_line", "panel.grid.minor"),
759759
panel.grid.minor.y = el_def("element_line", "panel.grid.minor"),
760760
panel.ontop = el_def("logical"),
761+
panel.merge = el_def("logical"),
761762
panel.widths = el_def("unit"),
762763
panel.heights = el_def("unit"),
763764

R/theme.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ theme <- function(...,
439439
panel.grid.minor.x,
440440
panel.grid.minor.y,
441441
panel.ontop,
442+
panel.merge,
442443
panel.widths,
443444
panel.heights,
444445
plot.background,

R/utilities-grid.R

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,11 @@ height_cm <- function(x) {
7070
cli::cli_abort("Don't know how to get height of {.cls {class(x)}} object")
7171
}
7272
}
73+
74+
insert_vp <- function(grob, vp) {
75+
if (is.null(grob$vp)) {
76+
grid::editGrob(grob, vp = vp)
77+
} else {
78+
grid::editGrob(grob, vp = grid::vpStack(grob$vp, vp))
79+
}
80+
}

0 commit comments

Comments
 (0)