@@ -133,8 +133,32 @@ Facet <- ggproto("Facet", NULL,
133
133
draw_front = function (data , layout , x_scales , y_scales , theme , params ) {
134
134
rep(list (zeroGrob()), vec_unique_count(layout $ PANEL ))
135
135
},
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 )
138
162
},
139
163
draw_labels = function (panels , layout , x_scales , y_scales , ranges , coord , data , theme , labels , params ) {
140
164
panel_dim <- find_panel(panels )
@@ -173,6 +197,64 @@ Facet <- ggproto("Facet", NULL,
173
197
finish_data = function (data , layout , x_scales , y_scales , params ) {
174
198
data
175
199
},
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
+ },
176
258
vars = function () {
177
259
character (0 )
178
260
}
0 commit comments