@@ -173,43 +173,61 @@ gg2list <- function(p, width = NULL, height = NULL, mapping = "all", source = "A
173173 panel $ layout $ x_max <- sapply(panel $ ranges , function (z ) max(z $ x.range ))
174174 panel $ layout $ y_min <- sapply(panel $ ranges , function (z ) min(z $ y.range ))
175175 panel $ layout $ y_max <- sapply(panel $ ranges , function (z ) max(z $ y.range ))
176-
177- # use aes mappings for the tooltip default
178- aesMap <- as.character(p $ mapping )
179- if (! identical(mapping , " all" )) {
180- aesMap <- aesMap [names(aesMap ) %in% mapping ]
181- aesMap <- aesMap [mapping ]
182- }
183- # tooltips for discrete positional scales are misleading
184- for (xy in c(" x" , " y" )) {
185- if (scales $ get_scales(xy )$ is_discrete()) {
186- aesMap <- aesMap [names(aesMap ) != xy ]
176+
177+ # --------------------------------------------------------------------
178+ # Use aes mappings for sensible tooltips
179+ # --------------------------------------------------------------------
180+
181+ aesMap <- lapply(p $ layers , function (x ) {
182+ map <- c(
183+ # plot level aes mappings
184+ as.character(p $ mapping ),
185+ # layer level mappings
186+ as.character(x $ mapping ),
187+ # stat specific mappings
188+ as.character(x $ stat $ default_aes )
189+ )
190+ # remove leading/trailing dots in "hidden" stat aes
191+ map <- sub(" ^\\ .\\ ." , " " , sub(" \\ .\\ .$" , " " , map ))
192+ # TODO: allow users to specify a _list_ of mappings?
193+ if (! identical(mapping , " all" )) {
194+ map <- map [names(map ) %in% mapping ]
187195 }
188- }
196+ # tooltips for discrete positional scales are misleading
197+ if (scales $ get_scales(" x" )$ is_discrete()) {
198+ map <- map [! names(map ) %in% " x" ]
199+ }
200+ if (scales $ get_scales(" y" )$ is_discrete()) {
201+ map <- map [! names(map ) %in% " y" ]
202+ }
203+ map
204+ })
189205
190- for (i in seq_along(aesMap )) {
191- aesName <- names(aesMap )[[i ]]
192- # TODO: should we be getting the name from scale_*(name) first?
193- varName <- aesMap [[i ]]
194- # by default assume the values don't need any formatting
195- forMat <- function (x ) if (is.numeric(x )) round(x , 2 ) else x
196- if (aesName %in% c(" x" , " y" )) {
197- scaleName <- scales $ get_scales(aesName )$ scale_name
198- # convert "milliseconds from the UNIX epoch" back to a date/datetime
199- # http://stackoverflow.com/questions/13456241/convert-unix-epoch-to-date-object-in-r
200- if (" date" %in% scaleName ) forMat <- function (x ) as.Date(as.POSIXct(x / 1000 , origin = " 1970-01-01" ))
201- if (" datetime" %in% scaleName ) forMat <- function (x ) as.POSIXct(x / 1000 , origin = " 1970-01-01" )
202- } else {
203- if (aesName != " text" ) aesName <- paste0(aesName , " _plotlyDomain" )
206+ # attach a new column (hovertext) to each layer of data that should get mapped
207+ # to the text trace property
208+ data <- Map(function (x , y ) {
209+ for (i in seq_along(y )) {
210+ aesName <- names(y )[[i ]]
211+ # TODO: should we be getting the name from scale_*(name) first?
212+ varName <- y [[i ]]
213+ # by default assume the values don't need any formatting
214+ forMat <- function (x ) if (is.numeric(x )) round(x , 2 ) else x
215+ if (aesName %in% c(" x" , " y" )) {
216+ scaleName <- scales $ get_scales(aesName )$ scale_name
217+ # convert "milliseconds from the UNIX epoch" back to a date/datetime
218+ # http://stackoverflow.com/questions/13456241/convert-unix-epoch-to-date-object-in-r
219+ if (" date" %in% scaleName ) forMat <- function (x ) as.Date(as.POSIXct(x / 1000 , origin = " 1970-01-01" ))
220+ if (" datetime" %in% scaleName ) forMat <- function (x ) as.POSIXct(x / 1000 , origin = " 1970-01-01" )
221+ } else {
222+ if (aesName != " text" ) aesName <- paste0(aesName , " _plotlyDomain" )
223+ }
224+ # add a line break if hovertext already exists
225+ if (" hovertext" %in% names(x )) x $ hovertext <- paste0(x $ hovertext , " <br>" )
226+ x $ hovertext <- paste0(x $ hovertext , varName , " : " , forMat(x [[aesName ]]))
204227 }
205-
206- data <- lapply(data , function (d ) {
207- if (! is.null(d $ hovertext )) d $ hovertext <- paste0(d $ hovertext , " <br>" )
208- d $ hovertext <- paste0(d $ hovertext , varName , " : " , forMat(d [[aesName ]]))
209- d
210- })
211- }
212-
228+ x
229+ }, data , aesMap )
230+
213231 # layers -> plotly.js traces
214232 traces <- layers2traces(
215233 data , prestats_data , layers , panel $ layout , scales , p $ labels
0 commit comments