R/geom_tiplab.R
14435e79
 ##' add tip label layer
 ##'
02392a7a
 ##'
 ##' @title geom_tiplab
14435e79
 ##' @param mapping aes mapping
 ##' @param hjust horizontal adjustment
90c9d156
 ##' @param offset tiplab offset
14435e79
 ##' @param align align tip lab or not, logical
 ##' @param linetype linetype for adding line if align = TRUE
 ##' @param linesize line size of line if align = TRUE
f35d40fd
 ##' @param geom one of 'text' and 'label'
14435e79
 ##' @param ... additional parameter
 ##' @return tip label layer
 ##' @importFrom ggplot2 geom_text
 ##' @export
 ##' @author Yu Guangchuang
 ##' @examples
 ##' require(ape)
 ##' tr <- rtree(10)
 ##' ggtree(tr) + geom_tiplab()
90c9d156
 geom_tiplab <- function(mapping=NULL, hjust = 0,  align = FALSE, linetype = "dotted", linesize=1, geom="text", offset = 0, ...) {
f35d40fd
     geom <- match.arg(geom, c("text", "label"))
90c9d156
     if (geom == "text") {
         text_geom <- geom_text2
     } else {
         text_geom <- geom_label2
     }
14435e79
     x <- y <- label <- isTip <- NULL
     if (align == TRUE) {
b0e1dc30
         self_mapping <- aes(x = max(x, na.rm=TRUE) + diff(range(x, na.rm=TRUE))/200, y = y, label = label, subset= isTip)
14435e79
     }
     else {
75f08f2b
         self_mapping <- aes(x = x + diff(range(x, na.rm=TRUE))/200, y= y, label = label, subset= isTip)
14435e79
     }
 
     if (is.null(mapping)) {
02392a7a
         text_mapping <- self_mapping
14435e79
     } else {
         text_mapping <- modifyList(self_mapping, mapping)
     }
 
02392a7a
 
90c9d156
     show_segment <- FALSE
     if (align && (!is.na(linetype) && !is.null(linetype))) {
         show_segment <- TRUE
02392a7a
     }
90c9d156
 
14435e79
     list(
02392a7a
         text_geom(mapping=text_mapping,
90c9d156
                   hjust = hjust, nudge_x = offset, ...)
         ,
         if (show_segment)
             geom_tipsegment(mapping = aes(subset=isTip),
                             offset = offset,
                             linetype = linetype,
                             size = linesize, ...)
f35d40fd
     )
14435e79
 }
 
 
9b8b0e98
 ##' add tip label for circular layout
 ##'
02392a7a
 ##'
9b8b0e98
 ##' @title geom_tiplab2
 ##' @param mapping aes mapping
2166288c
 ##' @param hjust horizontal adjustment
9b8b0e98
 ##' @param ... additional parameter, see geom_tiplab
 ##' @return tip label layer
 ##' @export
 ##' @author Guangchuang Yu
 ##' @references \url{https://groups.google.com/forum/#!topic/bioc-ggtree/o35PV3iHO-0}
2166288c
 geom_tiplab2 <- function(mapping=NULL, hjust=0, ...) {
14435e79
 
9b8b0e98
     angle <- NULL
02392a7a
     isTip <- NULL
4a860280
     ## m1 <- aes(subset=(abs(angle) < 90), angle=angle)
     ## m2 <- aes(subset=(abs(angle) >= 90), angle=angle+180)
02392a7a
     m1 <- aes(subset=(isTip & (angle < 90 | angle > 270)), angle=angle)
     m2 <- aes(subset=(isTip & (angle >= 90 & angle <=270)), angle=angle+180)
 
9b8b0e98
     if (!is.null(mapping)) {
         m1 <- modifyList(mapping, m1)
         m2 <- modifyList(mapping, m2)
     }
14435e79
 
2166288c
     list(geom_tiplab(m1, hjust=hjust, ...),
          geom_tiplab(m2, hjust=1-hjust, ...)
9b8b0e98
          )
 }
90c9d156
 
 geom_tipsegment <- function(mapping=NULL, data=NULL,
                             geom=GeomSegmentGGtree, position = "identity",
                             offset,  ...,
a92aaed1
                             show.legend=NA, inherit.aes=FALSE,
                             na.rm=TRUE) {
02392a7a
 
90c9d156
     default_aes <- aes_(x=~x, y=~y)
     if (is.null(mapping)) {
         mapping <- default_aes
     } else {
         mapping <- modifyList(default_aes, mapping)
     }
02392a7a
 
90c9d156
     layer(stat=StatTipSegment,
           data = data,
           mapping = mapping,
           geom = geom,
           position = position,
           show.legend = show.legend,
           inherit.aes = inherit.aes,
           params = list(offset = offset,
                         na.rm = na.rm,
a92aaed1
                         ...),
fad06b2b
           check.aes = FALSE
90c9d156
           )
 }
 
 StatTipSegment <- ggproto("StatTipSegment", Stat,
                         compute_group = function(self, data, scales, params, offset) {
                             get_tipsegment_position(data, offset)
                         },
                         required_aes = c("x", "y")
                         )
 
 
 get_tipsegment_position <- function(data, offset, adjustRatio=1/200) {
     adjust <- diff(range(data$x, na.rm=TRUE)) * adjustRatio
     xend <- data$x + adjust
     x <- max(data$x, na.rm = TRUE)  + offset
     y <- data$y
     data.frame(x=x, xend=xend, y=y, yend=y)
 }