79
79
# '
80
80
# ' ggplot(mtcars, aes(factor(cyl), fill = factor(vs))) +
81
81
# ' geom_bar(position = position_dodge2(preserve = "total"))
82
- position_dodge <- function (width = NULL , preserve = " total" ) {
82
+ position_dodge <- function (width = NULL , preserve = " total" , stackOverlap = " no " ) {
83
83
ggproto(NULL , PositionDodge ,
84
84
width = width ,
85
- preserve = arg_match0(preserve , c(" total" , " single" ))
85
+ preserve = arg_match0(preserve , c(" total" , " single" )),
86
+ stackOverlap = arg_match0(stackOverlap , c(" no" ," byExtent" ," byCenter" ))
86
87
)
87
88
}
88
89
@@ -93,6 +94,7 @@ position_dodge <- function(width = NULL, preserve = "total") {
93
94
PositionDodge <- ggproto(" PositionDodge" , Position ,
94
95
width = NULL ,
95
96
preserve = " total" ,
97
+ stackOverlap = " no" ,
96
98
setup_params = function (self , data ) {
97
99
flipped_aes <- has_flipped_aes(data )
98
100
data <- flip_data(data , flipped_aes )
@@ -113,6 +115,7 @@ PositionDodge <- ggproto("PositionDodge", Position,
113
115
114
116
list (
115
117
width = self $ width ,
118
+ stackOverlap = self $ stackOverlap ,
116
119
n = n ,
117
120
flipped_aes = flipped_aes
118
121
)
@@ -134,6 +137,7 @@ PositionDodge <- ggproto("PositionDodge", Position,
134
137
name = " position_dodge" ,
135
138
strategy = pos_dodge ,
136
139
n = params $ n ,
140
+ stackOverlap = params $ stackOverlap ,
137
141
check.width = FALSE
138
142
)
139
143
flip_data(collided , params $ flipped_aes )
@@ -142,7 +146,7 @@ PositionDodge <- ggproto("PositionDodge", Position,
142
146
143
147
# Dodge overlapping interval.
144
148
# Assumes that each set has the same horizontal position.
145
- pos_dodge <- function (df , width , n = NULL ) {
149
+ pos_dodge <- function (df , width , n = NULL , stackOverlap = " no " ) {
146
150
if (is.null(n )) {
147
151
n <- vec_unique_count(df $ group )
148
152
}
@@ -165,6 +169,16 @@ pos_dodge <- function(df, width, n = NULL) {
165
169
df $ x <- df $ x + width * ((groupidx - 0.5 ) / n - .5 )
166
170
df $ xmin <- df $ x - d_width / n / 2
167
171
df $ xmax <- df $ x + d_width / n / 2
172
+
173
+ if (stackOverlap == " byExtent" ) {
174
+ tmp = df %> % group_by(group ) %> % mutate(ymaxx = cumsum(ymax )) %> % mutate(ymin = ymaxx - ymax , ymax = ymaxx )
175
+ df $ ymin = tmp $ ymin
176
+ df $ ymax = tmp $ ymax
177
+ } else if (stackOverlap == " byCenter" ) {
178
+ tmp = df %> % group_by(group ) %> % mutate(extent = ymax - ymin , ymaxx = cumsum((ymax + ymin )/ 2 )) %> % mutate(ymin = ymaxx - extent / 2 , ymax = ymaxx + extent / 2 )
179
+ df $ ymin = tmp $ ymin
180
+ df $ ymax = tmp $ ymax
181
+ }
168
182
169
183
df
170
184
}
0 commit comments