@@ -55,6 +55,15 @@ GeomCurve <- ggproto("GeomCurve", GeomSegment,
5555
5656 trans <- coord $ transform(data , panel_params )
5757
58+ flip <- flip_curve(trans , coord , panel_params )
59+ if (flip ) {
60+ trans <- rename(trans , c(x = " xend" , xend = " x" , y = " yend" , yend = " y" ))
61+ if (! is.null(arrow )) {
62+ # Flip end where arrow appears (2 = last, 1 = first, 3 = both)
63+ arrow $ ends <- match(arrow $ ends , c(2 , 1 , 3 ))
64+ }
65+ }
66+
5867 arrow.fill <- arrow.fill %|| % trans $ colour
5968
6069 curveGrob(
@@ -72,3 +81,41 @@ GeomCurve <- ggproto("GeomCurve", GeomSegment,
7281 )
7382 }
7483)
84+
85+ # Helper function for determining whether curves should swap segment ends to
86+ # keep curvature consistent over transformations
87+ flip_curve <- function (data , coord , params ) {
88+ flip <- FALSE
89+
90+ # Figure implicit flipping transformations in coords
91+ if (inherits(coord , " CoordFlip" )) {
92+ flip <- ! flip
93+ } else if (inherits(coord , " CoordTrans" )) {
94+ if (identical(coord $ trans $ x $ name , " reverse" )) {
95+ flip <- ! flip
96+ }
97+ if (identical(coord $ trans $ y $ name , " reverse" )) {
98+ flip <- ! flip
99+ }
100+ }
101+
102+ # We don't flip when none or both directions are reversed
103+ if ((coord $ reverse %|| % " none" ) %in% c(" x" , " y" )) {
104+ flip <- ! flip
105+ }
106+
107+ # Check scales for reverse transforms
108+ # Note that polar coords do not have x/y scales, but these are unsupported
109+ # anyway
110+ fn <- params $ x $ get_transformation
111+ if (is.function(fn ) && identical(fn()$ name , " reverse" )) {
112+ flip <- ! flip
113+ }
114+
115+ fn <- params $ y $ get_transformation
116+ if (is.function(fn ) && identical(fn()$ name , " reverse" )) {
117+ flip <- ! flip
118+ }
119+
120+ flip
121+ }
0 commit comments