6
6
# #' @export
7
7
# #' @return list of geom info.
8
8
# #' @author Toby Dylan Hocking
9
- group2NA <- function (g , geom = " path " ){
9
+ group2NA <- function (g , geom ){
10
10
poly.list <- split(g $ data , g $ data $ group )
11
11
is.group <- names(g $ data ) == " group"
12
12
poly.na.df <- data.frame ()
13
13
for (i in seq_along(poly.list )){
14
14
no.group <- poly.list [[i ]][,! is.group ,drop = FALSE ]
15
- poly.na.df <- rbind(poly.na.df , no.group , NA )
15
+ na.row <- no.group [1 ,]
16
+ na.row [,c(" x" , " y" )] <- NA
17
+ poly.na.df <- rbind(poly.na.df , no.group , na.row )
16
18
}
17
- g $ data <- poly.na.df [ - nrow( poly.na.df ),]
19
+ g $ data <- poly.na.df
18
20
g $ geom <- geom
19
21
g
20
22
}
@@ -49,7 +51,7 @@ aes2marker <- c(alpha="opacity",
49
51
50
52
marker.defaults <- c(alpha = 1 ,
51
53
shape = " o" ,
52
- size = 5 ,
54
+ size = 1 ,
53
55
colour = " black" )
54
56
line.defaults <-
55
57
list (linetype = " solid" ,
@@ -111,23 +113,69 @@ toBasic <-
111
113
rbind(cbind(x , y , others ),
112
114
cbind(x = xend , y = yend , others ))
113
115
})
114
- g $ geom <- " path"
115
- group2NA(g )
116
- },polygon = group2NA ,line = function (g ){
116
+ group2NA(g , " path" )
117
+ },polygon = function (g ){
118
+ if (is.null(g $ params $ fill )){
119
+ g
120
+ }else if (is.na(g $ params $ fill )){
121
+ group2NA(g , " path" )
122
+ }else {
123
+ g
124
+ }
125
+ },path = function (g ){
126
+ group2NA(g , " path" )
127
+ },line = function (g ){
117
128
g $ data <- g $ data [order(g $ data $ x ),]
118
- group2NA(g )
129
+ group2NA(g , " path " )
119
130
},ribbon = function (g ){
120
131
stop(" TODO" )
121
132
})
122
133
134
+ # ' Convert basic geoms to traces.
135
+ geom2trace <-
136
+ list (path = function (data , params ){
137
+ list (x = data $ x ,
138
+ y = data $ y ,
139
+ name = params $ name ,
140
+ text = data $ text ,
141
+ type = " scatter" ,
142
+ mode = " lines" ,
143
+ line = paramORdefault(params , aes2line , line.defaults ))
144
+ },polygon = function (data , params ){
145
+ list (x = c(data $ x , data $ x [1 ]),
146
+ y = c(data $ y , data $ y [1 ]),
147
+ name = params $ name ,
148
+ text = data $ text ,
149
+ type = " scatter" ,
150
+ mode = " lines" ,
151
+ line = paramORdefault(params , aes2line , line.defaults ),
152
+ fill = " tonextx" ,
153
+ fillcolor = toRGB(params $ fill ))
154
+ },point = function (data , params ){
155
+ L <- list (x = data $ x ,
156
+ y = data $ y ,
157
+ name = params $ name ,
158
+ text = data $ text ,
159
+ type = " scatter" ,
160
+ mode = " markers" ,
161
+ marker = paramORdefault(params , aes2marker , marker.defaults ))
162
+ if (" size" %in% names(data )){
163
+ L $ marker $ sizeref <- min(data $ size )
164
+ L $ marker $ sizemode <- " area"
165
+ L $ marker $ size <- data $ size
166
+ }
167
+ L
168
+ })
169
+
123
170
# ' Convert ggplot2 aes to line parameters.
124
171
aes2line <- c(linetype = " dash" ,
125
172
colour = " color" ,
126
173
size = " width" )
127
174
128
175
markLegends <-
129
176
list (point = c(" colour" , " fill" , " shape" ),
130
- path = c(" linetype" , " size" , " colour" ))
177
+ path = c(" linetype" , " size" , " colour" ),
178
+ polygon = c(" colour" , " fill" , " linetype" , " size" , " group" ))
131
179
132
180
markUnique <- as.character(unique(unlist(markLegends )))
133
181
@@ -139,7 +187,15 @@ markUnique <- as.character(unique(unlist(markLegends)))
139
187
gg2list <- function (p ){
140
188
# # Always use identity size scale so that plot.ly gets the real
141
189
# # units for the size variables.
142
- p <- p + scale_size_identity()
190
+ p <- tryCatch({
191
+ # # this will be an error for discrete variables.
192
+ suppressMessages({
193
+ ggplot2 :: ggplot_build(p + scale_size_continuous())
194
+ p + scale_size_identity()
195
+ })
196
+ },error = function (e ){
197
+ p
198
+ })
143
199
layout <- list ()
144
200
trace.list <- list ()
145
201
# # Before building the ggplot, we would like to add aes(name) to
@@ -348,16 +404,23 @@ layer2traces <- function(l, d, misc){
348
404
# # legend entries.
349
405
data.list <- if (basic $ geom %in% names(markLegends )){
350
406
mark.names <- markLegends [[basic $ geom ]]
351
- to.erase <- names(misc $ is.continuous )[misc $ is.continuous ]
352
- mark.names <- mark.names [! mark.names %in% to.erase ]
407
+ # # However, continuously colored points are an exception: they do
408
+ # # not need a legend entry, and they can be efficiently rendered
409
+ # # using just 1 trace.
410
+
411
+ # # Maybe it is nice to show a legend for continuous points?
412
+ # # if(basic$geom == "point"){
413
+ # # to.erase <- names(misc$is.continuous)[misc$is.continuous]
414
+ # # mark.names <- mark.names[!mark.names %in% to.erase]
415
+ # # }
353
416
name.names <- sprintf(" %s.name" , mark.names )
354
417
is.split <- names(basic $ data ) %in% name.names
355
- data.i <- which(is.split )
356
- matched.names <- names(basic $ data )[data.i ]
357
- name.i <- which(name.names %in% matched.names )
358
- invariable.names <- cbind(name.names , mark.names )[name.i ,]
359
- other.names <- ! names(basic $ data ) %in% invariable.names
360
418
if (any(is.split )){
419
+ data.i <- which(is.split )
420
+ matched.names <- names(basic $ data )[data.i ]
421
+ name.i <- which(name.names %in% matched.names )
422
+ invariable.names <- cbind(name.names , mark.names )[name.i ,]
423
+ other.names <- ! names(basic $ data ) %in% invariable.names
361
424
vec.list <- basic $ data [is.split ]
362
425
df.list <- split(basic $ data , vec.list , drop = TRUE )
363
426
lapply(df.list , function (df ){
@@ -368,19 +431,17 @@ layer2traces <- function(l, d, misc){
368
431
})
369
432
}
370
433
}
371
- # # Case of no legend:
434
+ # # case of no legend, if either of the two ifs above failed.
372
435
if (is.null(data.list )){
373
- data.list <-
374
- structure(list (list (data = basic $ data , params = basic $ params )),
375
- names = basic $ params $ name )
436
+ data.list <- structure(list (list (data = basic $ data , params = basic $ params )),
437
+ names = basic $ params $ name )
376
438
}
377
439
378
440
getTrace <- geom2trace [[basic $ geom ]]
379
441
if (is.null(getTrace )){
380
442
stop(" conversion not implemented for geom_" ,
381
443
g $ geom , " (basic geom_" , basic $ geom , " )" )
382
444
}
383
-
384
445
traces <- NULL
385
446
for (data.i in seq_along(data.list )){
386
447
data.params <- data.list [[data.i ]]
@@ -391,7 +452,9 @@ layer2traces <- function(l, d, misc){
391
452
a <- sub(" [.]name$" , " " , a.name )
392
453
a.value <- as.character(data.params $ params [[a.name ]])
393
454
ranks <- misc $ breaks [[a ]]
394
- tr $ sort [[a.name ]] <- ranks [[a.value ]]
455
+ if (length(ranks )){
456
+ tr $ sort [[a.name ]] <- ranks [[a.value ]]
457
+ }
395
458
}
396
459
name.list <- data.params $ params [name.names ]
397
460
tr $ name <- paste(unlist(name.list ), collapse = " ." )
@@ -416,31 +479,6 @@ layer2traces <- function(l, d, misc){
416
479
no.sort
417
480
}
418
481
419
- geom2trace <-
420
- list (path = function (data , params ){
421
- list (x = data $ x ,
422
- y = data $ y ,
423
- name = params $ name ,
424
- text = data $ text ,
425
- type = " scatter" ,
426
- mode = " lines" ,
427
- line = paramORdefault(params , aes2line , line.defaults ))
428
- },point = function (data , params ){
429
- L <- list (x = data $ x ,
430
- y = data $ y ,
431
- name = params $ name ,
432
- text = data $ text ,
433
- type = " scatter" ,
434
- mode = " markers" ,
435
- marker = paramORdefault(params , aes2marker , marker.defaults ))
436
- if (" size" %in% names(data )){
437
- L $ marker $ sizeref <- min(data $ size )
438
- L $ marker $ sizemode <- " area"
439
- L $ marker $ size <- data $ size
440
- }
441
- L
442
- })
443
-
444
482
# #' convert ggplot params to plotly.
445
483
# #' @param params named list ggplot names -> values.
446
484
# #' @param aesVec vector mapping ggplot names to plotly names.
0 commit comments