Skip to content

Commit bbcff4d

Browse files
committed
Dodge-stack with tidyverse.
1 parent 14a6b29 commit bbcff4d

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

R/position-dodge.R

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,11 @@
7979
#'
8080
#' ggplot(mtcars, aes(factor(cyl), fill = factor(vs))) +
8181
#' 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") {
8383
ggproto(NULL, PositionDodge,
8484
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"))
8687
)
8788
}
8889

@@ -93,6 +94,7 @@ position_dodge <- function(width = NULL, preserve = "total") {
9394
PositionDodge <- ggproto("PositionDodge", Position,
9495
width = NULL,
9596
preserve = "total",
97+
stackOverlap = "no",
9698
setup_params = function(self, data) {
9799
flipped_aes <- has_flipped_aes(data)
98100
data <- flip_data(data, flipped_aes)
@@ -113,6 +115,7 @@ PositionDodge <- ggproto("PositionDodge", Position,
113115

114116
list(
115117
width = self$width,
118+
stackOverlap = self$stackOverlap,
116119
n = n,
117120
flipped_aes = flipped_aes
118121
)
@@ -134,6 +137,7 @@ PositionDodge <- ggproto("PositionDodge", Position,
134137
name = "position_dodge",
135138
strategy = pos_dodge,
136139
n = params$n,
140+
stackOverlap = params$stackOverlap,
137141
check.width = FALSE
138142
)
139143
flip_data(collided, params$flipped_aes)
@@ -142,7 +146,7 @@ PositionDodge <- ggproto("PositionDodge", Position,
142146

143147
# Dodge overlapping interval.
144148
# 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") {
146150
if (is.null(n)) {
147151
n <- vec_unique_count(df$group)
148152
}
@@ -165,6 +169,16 @@ pos_dodge <- function(df, width, n = NULL) {
165169
df$x <- df$x + width * ((groupidx - 0.5) / n - .5)
166170
df$xmin <- df$x - d_width / n / 2
167171
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+
}
168182

169183
df
170184
}

0 commit comments

Comments
 (0)