Skip to content

Commit

Permalink
support gridtext
Browse files Browse the repository at this point in the history
  • Loading branch information
jokergoo committed Mar 21, 2020
1 parent e58d5e7 commit 784c44e
Show file tree
Hide file tree
Showing 10 changed files with 370 additions and 221 deletions.
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Package: ComplexHeatmap
Type: Package
Title: Make Complex Heatmaps
Version: 2.3.2
Date: 2020-03-05
Version: 2.3.3
Date: 2020-03-21
Author: Zuguang Gu
Maintainer: Zuguang Gu <[email protected]>
Depends: R (>= 3.1.2), methods, grid, graphics, stats, grDevices
Expand Down
3 changes: 3 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ S3method("[", "SingleAnnotation")
export("[.SingleAnnotation")
S3method("[", "comb_mat")
export("[.comb_mat")
S3method("[", "gridtext")
export("[.gridtext")
S3method("c", "ColorMapping")
export("c.ColorMapping")
S3method("c", "HeatmapAnnotation")
Expand Down Expand Up @@ -173,6 +175,7 @@ export("getXY_in_parent_vp")
export("grid.annotation_axis")
export("grid.boxplot")
export("grid.dendrogram")
export("gt_render")
export("ht_global_opt")
export("ht_opt")
export("is_abs_unit")
Expand Down
9 changes: 8 additions & 1 deletion NEWS
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
CHANGES in VERSION 2.3.3

* support **gridtext** package

========================

CHANGES in VERSION 2.3.2

* `anno_simple()`: fixed a bug when pch are all NA in a slice
* adjust code according to grid 4.0.
* move scripts in test_not_run/ to tests/ folder
* `Heatmap()`: `cluster_row_slice`/`cluster_column_slice` set to TRUE
by default for character matrix and when dendrogram is already provided.
* `smartAlign2()`: improved the code
* `smartAlign2()`: improved the code that positions are correctly calculated.
* row titles are in the correct order if they are set as "template".

========================

Expand Down
79 changes: 0 additions & 79 deletions R/AnnotationFunction-function.R
Original file line number Diff line number Diff line change
Expand Up @@ -2017,10 +2017,6 @@ anno_text = function(x, which = c("column", "row"), gp = gpar(),
rot = guess_rot(), just = guess_just(),
offset = guess_location(), location = guess_location(),
width = NULL, height = NULL) {

if(inherits(x, "richtext_grob")) {
return(anno_richtext(x, which = which, width = width, height = height))
}

ef = function() NULL
if(is.null(.ENV$current_annotation_which)) {
Expand Down Expand Up @@ -2154,81 +2150,6 @@ anno_text = function(x, which = c("column", "row"), gp = gpar(),
return(anno)
}

anno_richtext = function(x, which = c("column", "row"), width = NULL, height = NULL) {

# ef = function() NULL
# if(is.null(.ENV$current_annotation_which)) {
# which = match.arg(which)[1]
# dev.null()
# ef = dev.off2
# } else {
# which = .ENV$current_annotation_which
# }

# on.exit(ef())

# n = length(x)

# if(which == "column") {
# if(missing(height)) {
# height = grobHeight(x)
# height = convertHeight(height, "mm")
# }
# if(missing(width)) {
# width = unit(1, "npc")
# }
# }
# if(which == "row") {
# if(missing(width)) {
# width = grobWidth(x)
# width = convertWidth(width, "mm")
# }
# if(missing(height)) {
# height = unit(1, "npc")
# }
# }

# anno_size = list(width = width, height = height)

# value = x

# row_fun = function(index) {
# n = length(index)
# gb = value[index]
# gb = update_xy(gb, y = unit((n - seq_along(index) + 0.5)/n, "native"))
# grid.draw(gb)
# }
# column_fun = function(index, k = NULL, N = NULL, vp_name = NULL) {
# n = length(index)
# gb = value[index]
# gb = update_xy(gb, x = unit((seq_along(index) - 0.5)/n, "native"))
# grid.draw(gb)
# }

# if(which == "row") {
# fun = row_fun
# } else if(which == "column") {
# fun = column_fun
# }

# anno = AnnotationFunction(
# fun = fun,
# fun_name = "anno_richtext",
# which = which,
# width = width,
# height = height,
# n = n,
# var_import = list(value),
# show_name = FALSE
# )

# anno@subset_rule$value = subset_vector

# anno@subsetable = TRUE

# return(anno)
}

# == title
# Joyplot Annotation
#
Expand Down
258 changes: 258 additions & 0 deletions R/gridtext.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
# `[.grob` = function(x, i) {
# x2 = x
# for(nm in SUBSETABLE_FIELDS[[ intersect(names(SUBSETABLE_FIELDS), class(x)) ]]) {
# if(inherits(x2[[nm]], "gpar")) {
# # change to the class defined here
# class(x2[[nm]]) = "gpar"
# }

# if(length(x2[[nm]]) > 1) {
# x2[[nm]] = x2[[nm]][i]
# }
# }
# x2
# }

# `[.gpar` = function(x, i) {
# lapply(x, function(y) {
# if(length(y) > 1) {
# y[i]
# } else {
# y
# }
# })
# }

# SUBSETABLE_FIELDS = list(
# "text" = c("label", "x", "y", "gp"),
# "richtext_grob" = c("gp", "children", "childrenOrder")
# )

# length.text = function(x) {
# length(x$label)
# }

# length.richtext_grob = function(x) {
# length(x$children)
# }

# update_xy = function (gb, x, y, ...) {
# UseMethod("update_xy")
# }

# update_xy.text = function(gb, x, y, ...) {
# n = length(gb$label)
# if(!missing(x)) {
# if(n > 1 & length(x) > 1 && n != length(x)) {
# stop_wrap("Length of `x` should be the same as the length of labels.")
# }
# gb$x = x
# }
# if(!missing(y)) {
# if(n > 1 & length(y) > 1 && n != length(y)) {
# stop_wrap("Length of `y` should be the same as the length of labels.")
# }
# gb$y = y
# }
# gb
# }

# update_xy.richtext_grob = function(gb, x, y, ...) {
# n = length(gb$children)

# if(!missing(x)) {
# if(n > 1 & length(x) > 1 && n != length(x)) {
# stop_wrap("Length of `x` should be the same as the length of labels.")
# }
# for(i in 1:n) {
# if(length(x) == 1) {
# gb$children[[i]]$vp$x = x
# } else {
# gb$children[[i]]$vp$x = x[i]
# }
# }
# }
# if(!missing(y)) {
# if(n > 1 & length(y) > 1 && n != length(y)) {
# stop_wrap("Length of `y` should be the same as the length of labels.")
# }
# for(i in 1:n) {
# if(length(y) == 1) {
# gb$children[[i]]$vp$y = y
# } else {
# gb$children[[i]]$vp$y = y[i]
# }
# }
# }
# gb
# }

# textGrob = function(label, ...) {
# if(inherits(label, "grob")) {
# return(label)
# } else {
# grid::textGrob(label, ...)
# }
# }

# grid.text = function(label, x = unit(0.5, "npc"), y = unit(0.5, "npc"), ...) {
# if(inherits(label, "grob")) {
# gb = label
# gb = update_xy(gb, x, y)
# grid.draw(gb)
# } else {
# grid::grid.text(label, x, y, ...)
# }
# }

# == title
# Mark the text for the rendering by gridtext package
#
# == param
# -x Text labels. The value can be a vector.
# -... Other parameters passed to `gridtext::richtext_grob`.
#
# == details
# Text marked by `gt_render` will be rendered by `gridtext::richtext_grob` function.
#
# == example
# if(requireNamespace("gridtext")) {
# mat = matrix(rnorm(100), 10)
# rownames(mat) = letters[1:10]
# ht = Heatmap(mat,
# column_title = gt_render("Some <span style='color:blue'>blue text **in bold.**</span><br>And *italics text.*<br>And some <span style='font-size:18pt; color:black'>large</span> text.", r = unit(2, "pt"), padding = unit(c(2, 2, 2, 2), "pt")),
# column_title_gp = gpar(box_fill = "orange"),
# row_labels = gt_render(letters[1:10], padding = unit(c(2, 10, 2, 10), "pt")),
# row_names_gp = gpar(box_col = "red"),
# row_km = 2,
# row_title = gt_render(c("title1", "title2")),
# row_title_gp = gpar(box_fill = "yellow"),
# heatmap_legend_param = list(
# title = gt_render("<span style='color:orange'>**Legend title**</span>"),
# title_gp = gpar(box_fill = "grey"),
# at = c(-3, 0, 3),
# labels = gt_render(c("*negative* three", "zero", "*positive* three"))
# ))
# ht = rowAnnotation(
# foo = anno_text(gt_render(sapply(LETTERS[1:10], strrep, 10), align_widths = TRUE),
# gp = gpar(box_col = "blue", box_lwd = 2),
# just = "right",
# location = unit(1, "npc")
# )) + ht
# draw(ht)
#
# }
gt_render = function(x, ...) {
if(!requireNamespace("gridtext")) {
stop_wrap("gridtext package needs to be installed.")
}
param = list(...)
class(x) = "gridtext"
attr(x, "param") = param
return(x)
}

# == title
# Subset method of gridtext class
#
# == param
# -x A vector of labels generated by `gt_render`.
# -index Index
#
# == details
# Internally used.
"[.gridtext" = function(x, index) {
cl = class(x)
param = attr(x, "param")
class(x) = NULL
x = x[index]
class(x) = cl
attr(x, "param") = param
x
}

grid.text = function(label, x = unit(0.5, "npc"), y = unit(0.5, "npc"), ...) {
if(inherits(label, "gridtext")) {
# cat("draw text by gridtext:\n")
# print(label)
# cat("\n")
grid.draw(richtext_grob2(label, x, y, ...))
} else {
grid::grid.text(label, x, y, ...)
}
}

textGrob = function(label, ...) {
if(inherits(label, "gridtext")) {
richtext_grob2(label, ...)
} else {
grid::textGrob(label, ...)
}
}

normalize_just = function(x) {
if(is.character(x)) {
x[x == "centre"] = "center"
if(identical(x, "center")) {
return(c(0.5, 0.5))
} else if(identical(x, c("center", "center"))) {
return(c(0.5, 0.5))
} else if(identical(x, c("left", "center"))) {
return(c(0, 0.5))
} else if(identical(x, c("right", "center"))) {
return(c(1, 0.5))
} else if(identical(x, c("center", "top"))) {
return(c(0.5, 1))
} else if(identical(x, c("center", "bottom"))) {
return(c(0.5, 0))
} else if(identical(x, c("left", "bottom"))) {
return(c(0, 0))
} else if(identical(x, c("left", "top"))) {
return(c(0, 1))
} else if(identical(x, c("right", "bottom"))) {
return(c(1, 0))
} else if(identical(x, c("right", "top"))) {
return(c(1, 1))
} else if(identical(x, c("left"))) {
return(c(0, 0.5))
} else if(identical(x, c("right"))) {
return(c(1, 0.5))
} else if(identical(x, c("bottom"))) {
return(c(0.5, 0))
} else if(identical(x, c("top"))) {
return(c(0.5, 1))
}
}
if(length(x) == 1) x = c(x, x)
return(x)
}

# argument from grid.text directly pass to richtext_grob, so some argument need
# to be adjusted, e.g. those not supported in richtext_grob
richtext_grob2 = function(label, ...) {
param0 = attr(label, "param")
param = list(text = label, ...)
for(nm in names(param0)) {
param[[nm]] = param0[[nm]]
}
if("just" %in% names(param)) {
j = normalize_just(param$just)
param$just = NULL
param$hjust = j[1]
param$vjust = j[2]
}
if("gp" %in% names(param)) {
gp = param$gp
l_box = grepl("^box_", names(gp))
if(any(l_box)) {
box_gp = gp[l_box]
gp[l_box] = NULL
names(box_gp) = gsub("^box_", "", names(box_gp))
class(gp) = "gpar"
class(box_gp) = "gpar"
param$gp = gp
param$box_gp = box_gp
}
}
do.call(gridtext::richtext_grob, param)
}
Loading

0 comments on commit 784c44e

Please sign in to comment.