14
14
# ' @param n.dodge The number of rows (for vertical axes) or columns (for
15
15
# ' horizontal axes) that should be used to render the labels. This is
16
16
# ' useful for displaying labels that would otherwise overlap.
17
+ # ' @param cap A `character` to cut the axis line back to the last breaks. Can
18
+ # ' be `"none"` (default) to draw the axis line along the whole panel, or
19
+ # ' `"upper"` and `"lower"` to draw the axis to the upper or lower break, or
20
+ # ' `"both"` to only draw the line in between the most extreme breaks. `TRUE`
21
+ # ' and `FALSE` are shorthand for `"both"` and `"none"` respectively.
17
22
# ' @param order A positive `integer` of length 1 that specifies the order of
18
23
# ' this guide among multiple guides. This controls in which order guides are
19
24
# ' merged if there are multiple guides for the same position. If 0 (default),
37
42
# ' # can also be used to add a duplicate guide
38
43
# ' p + guides(x = guide_axis(n.dodge = 2), y.sec = guide_axis())
39
44
guide_axis <- function (title = waiver(), check.overlap = FALSE , angle = NULL ,
40
- n.dodge = 1 , order = 0 , position = waiver()) {
45
+ n.dodge = 1 , cap = " none" , order = 0 ,
46
+ position = waiver()) {
47
+
48
+ if (is.logical(cap )) {
49
+ check_bool(cap )
50
+ cap <- if (cap ) " both" else " none"
51
+ }
52
+ cap <- arg_match0(cap , c(" none" , " both" , " upper" , " lower" ))
53
+
54
+
41
55
new_guide(
42
56
title = title ,
43
57
44
58
# customisations
45
59
check.overlap = check.overlap ,
46
60
angle = angle ,
47
61
n.dodge = n.dodge ,
62
+ cap = cap ,
48
63
49
64
# parameter
50
65
available_aes = c(" x" , " y" ),
@@ -72,6 +87,7 @@ GuideAxis <- ggproto(
72
87
direction = NULL ,
73
88
angle = NULL ,
74
89
n.dodge = 1 ,
90
+ cap = " none" ,
75
91
order = 0 ,
76
92
check.overlap = FALSE
77
93
),
@@ -92,6 +108,25 @@ GuideAxis <- ggproto(
92
108
Guide $ extract_params(scale , params , hashables )
93
109
},
94
110
111
+ extract_decor = function (scale , aesthetic , position , key , cap = " none" , ... ) {
112
+
113
+ value <- c(- Inf , Inf )
114
+ if (cap %in% c(" both" , " upper" )) {
115
+ value [2 ] <- max(key [[aesthetic ]])
116
+ }
117
+ if (cap %in% c(" both" , " lower" )) {
118
+ value [1 ] <- min(key [[aesthetic ]])
119
+ }
120
+
121
+ opposite <- setdiff(c(" x" , " y" ), aesthetic )
122
+ opposite_value <- if (position %in% c(" top" , " right" )) - Inf else Inf
123
+
124
+ data_frame(
125
+ !! aesthetic : = value ,
126
+ !! opposite : = opposite_value
127
+ )
128
+ },
129
+
95
130
transform = function (self , params , coord , panel_params ) {
96
131
key <- params $ key
97
132
position <- params $ position
@@ -109,6 +144,8 @@ GuideAxis <- ggproto(
109
144
key <- coord $ transform(key , panel_params )
110
145
params $ key <- key
111
146
147
+ params $ decor <- coord_munch(coord , params $ decor , panel_params )
148
+
112
149
# Ported over from `warn_for_position_guide`
113
150
# This is trying to catch when a user specifies a position perpendicular
114
151
# to the direction of the axis (e.g., a "y" axis on "top").
@@ -228,11 +265,13 @@ GuideAxis <- ggproto(
228
265
229
266
# The decor in the axis guide is the axis line
230
267
build_decor = function (decor , grobs , elements , params ) {
231
- exec(
232
- element_grob ,
233
- element = elements $ line ,
234
- !! params $ aes : = unit(c(0 , 1 ), " npc" ),
235
- !! params $ orth_aes : = unit(rep(params $ orth_side , 2 ), " npc" )
268
+ if (empty(decor )) {
269
+ return (zeroGrob())
270
+ }
271
+ element_grob(
272
+ elements $ line ,
273
+ x = unit(decor $ x , " npc" ),
274
+ y = unit(decor $ y , " npc" )
236
275
)
237
276
},
238
277
@@ -347,7 +386,8 @@ GuideAxis <- ggproto(
347
386
},
348
387
349
388
draw_early_exit = function (self , params , elements ) {
350
- line <- self $ build_decor(elements = elements , params = params )
389
+ line <- self $ build_decor(decor = params $ decor , elements = elements ,
390
+ params = params )
351
391
absoluteGrob(
352
392
gList(line ),
353
393
width = grobWidth(line ),
@@ -385,11 +425,17 @@ draw_axis <- function(break_positions, break_labels, axis_position, theme,
385
425
position = axis_position )
386
426
params <- guide $ params
387
427
aes <- if (axis_position %in% c(" top" , " bottom" )) " x" else " y"
428
+ opp <- setdiff(c(" x" , " y" ), aes )
429
+ opp_value <- if (axis_position %in% c(" top" , " right" )) 0 else 1
388
430
key <- data_frame(
389
431
break_positions , break_positions , break_labels ,
390
432
.name_repair = ~ c(aes , " .value" , " .label" )
391
433
)
392
434
params $ key <- key
435
+ params $ decor <- data_frame0(
436
+ !! aes : = c(0 , 1 ),
437
+ !! opp : = opp_value
438
+ )
393
439
guide $ draw(theme , params )
394
440
}
395
441
0 commit comments