Add spec_tooltip & spec_popover; Update documentation
diff --git a/NAMESPACE b/NAMESPACE
index db4b355..f800cc5 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -19,6 +19,8 @@
export(spec_angle)
export(spec_color)
export(spec_font_size)
+export(spec_popover)
+export(spec_tooltip)
export(text_spec)
export(usepackage_latex)
importFrom(knitr,include_graphics)
diff --git a/R/cell_spec.R b/R/cell_spec.R
index 4fa5895..8eb2c0f 100644
--- a/R/cell_spec.R
+++ b/R/cell_spec.R
@@ -18,10 +18,20 @@
#' values could be `l`, `c`, `r` plus `left`, `center`, `right`, `justify`,
#' `initial` and `inherit` while for LaTeX, you can only choose
#' from `l`, `c` & `r`.
-#' @param font_size j
+#' @param font_size A numeric input for font size. For HTML, you can also use
+#' options
#' @param angle 0-360, degree that the text will rotate. Can be a vector.
#' @param tooltip A vector of strings to be displayed as tooltip.
-#' Obviously, this feature is only available in HTML.
+#' Obviously, this feature is only available in HTML. Read the package
+#' vignette to see how to use bootstrap tooltip css to improve the loading
+#' speed and look.
+#' @param popover Similar with tooltip but can hold more contents. The best way
+#' to build a popover is through `spec_popover()`. If you only provide a text
+#' string, it will be used as content. Note that You have to enable this
+#' bootstrap module manually. Read the package vignette to see how.
+#' @param link A vector of strings for url links. Can be used together with
+#' tooltip and popover.
+#' @param escape T/F value showing whether special characters should be escaped.
#' @param background_as_tile T/F value indicating if you want to have round
#' cornered tile as background in HTML.
#' @param latex_background_in_cell T/F value. It only takes effect in LaTeX
@@ -31,10 +41,12 @@
#'
#' @export
cell_spec <- function(x, format,
- bold = F, italic = F, monospace = F,
+ bold = FALSE, italic = FALSE, monospace = FALSE,
color = NULL, background = NULL,
align = NULL, font_size = NULL, angle = NULL,
- tooltip = NULL, background_as_tile = TRUE,
+ tooltip = NULL, popover = NULL, link = NULL,
+ escape = TRUE,
+ background_as_tile = TRUE,
latex_background_in_cell = TRUE) {
if (missing(format) || is.null(format)) format = getOption('knitr.table.format')
@@ -46,18 +58,21 @@
if (tolower(format) == "html") {
return(cell_spec_html(x, bold, italic, monospace,
color, background, align, font_size, angle,
- tooltip, background_as_tile))
+ tooltip, popover, link,
+ escape, background_as_tile))
}
if (tolower(format) == "latex") {
return(cell_spec_latex(x, bold, italic, monospace,
- color, background, align, font_size, angle,
+ color, background, align, font_size, angle, escape,
latex_background_in_cell))
}
}
cell_spec_html <- function(x, bold, italic, monospace,
color, background, align, font_size, angle,
- tooltip, background_as_tile) {
+ tooltip, popover, link,
+ escape, background_as_tile) {
+ if (escape) x <- escape_html(x)
cell_style <- NULL
if (bold) cell_style <- paste(cell_style,"font-weight: bold;")
if (italic) cell_style <- paste(cell_style, "font-style: italic;")
@@ -77,16 +92,39 @@
cell_style <- paste0(cell_style, "text-align: ", align, ";")
}
if (!is.null(font_size)) {
- if (is.numeric) font_size <- paste0(font_size, "px")
+ if (is.numeric(font_size)) font_size <- paste0(font_size, "px")
cell_style <- paste0(cell_style, "font-size: ", font_size, ";")
}
- if (!is.null(tooltip)) {
- tooltip <- gsub("\n", "
", tooltip)
- tooltip <- paste0("data-toggle='tooltip' title='", tooltip, "'")
+
+ # favor popover over tooltip
+ if (!is.null(popover)) {
+ if (class(popover) != "ke_popover") popover <- spec_popover(popover)
+ tooltip_n_popover <- popover
+ } else if (!is.null(tooltip)) {
+ if (class(tooltip) != "ke_tooltip") tooltip <- spec_tooltip(tooltip)
+ tooltip_n_popover <- tooltip
+ } else {
+ tooltip_n_popover <- NULL
}
- out <- paste0(
- '<span style="', cell_style, '"', tooltip, '>', x, '</span>'
- )
+
+ if (!is.null(link)) {
+ x <- paste0('<a href="', link, '" style="', cell_style, '" ',
+ tooltip_n_popover, '>', x, '</a>')
+ } else {
+ x <- paste0('<span style="', cell_style, '" ',
+ tooltip_n_popover, '>', x, '</span>')
+ }
+
+ # if (!is.null(link)) {
+ # x <- paste0('<a href="', link, '" style="', cell_style, '" ',
+ # tooltip_n_popover, '>', x, '</a>')
+ # } else if (!is.null(tooltip_n_popover)) {
+ # x <- paste0('<span style="', cell_style, '" ',
+ # tooltip_n_popover, '>', x, '</span>')
+ # } else {
+ #
+ # }
+
if (!is.null(angle)) {
rotate_css <- paste0("-webkit-transform: rotate(", angle,
@@ -94,15 +132,17 @@
"deg); -ms-transform: rotate(", angle,
"deg); -o-transform: rotate(", angle,
"deg); transform: rotate(", angle,
- "deg);")
- out <- paste0('<div style="', rotate_css, '">', out, '</div>')
+ "deg); display: inline-block; ")
+ x <- paste0('<span style="', rotate_css, '">', x, '</span>')
}
- return(out)
+
+ return(x)
}
cell_spec_latex <- function(x, bold, italic, monospace,
- color, background, align, font_size, angle,
+ color, background, align, font_size, angle, escape,
latex_background_in_cell) {
+ if (escape) x <- escape_latex(x)
if (bold) x <- paste0("\\bfseries{", x, "}")
if (italic) x <- paste0("\\em{", x, "}")
if (monospace) x <- paste0("\\ttfamily{", x, "}")
@@ -116,8 +156,8 @@
x <- paste0("\\", background_env, background, "{", x, "}")
}
if (!is.null(font_size)) {
- x <- paste0("\\begingroup\\fontsize{", font_size, "}{", as.numeric(font_size) + 2,
- "}\\selectfont ", x, "\\endgroup")
+ x <- paste0("\\bgroup\\fontsize{", font_size, "}{", as.numeric(font_size) + 2,
+ "}\\selectfont ", x, "\\egroup{}")
}
if (!is.null(angle)) x <- paste0("\\rotatebox{", angle, "}{", x, "}")
if (!is.null(align)) x <- paste0("\\multicolumn{1}{", align, "}{", x, "}")
@@ -127,12 +167,13 @@
#' @rdname cell_spec
#' @export
text_spec <- function(x, format,
- bold = F, italic = F, monospace = F,
+ bold = FALSE, italic = FALSE, monospace = FALSE,
color = NULL, background = NULL,
align = NULL, font_size = NULL, angle = NULL,
- tooltip = NULL, background_as_tile = TRUE,
+ tooltip = NULL, popover = NULL, link = NULL,
+ escape = TRUE, background_as_tile = TRUE,
latex_background_in_cell = FALSE) {
cell_spec(x, format, bold, italic, monospace, color, background, align,
- font_size, angle, tooltip, background_as_tile,
+ font_size, angle, tooltip, popover, link, escape, background_as_tile,
latex_background_in_cell)
}
diff --git a/R/kable_styling.R b/R/kable_styling.R
index 9049ac2..04176c9 100644
--- a/R/kable_styling.R
+++ b/R/kable_styling.R
@@ -452,7 +452,7 @@
# fontsize is good enough
return(paste0(
"\\begingroup\\fontsize{", font_size, "}{", row_height, "}\\selectfont\n", x,
- "\\endgroup"
+ "\\endgroup{}"
))
}
diff --git a/R/spec_tools.R b/R/spec_tools.R
index f8545d4..bd27df4 100644
--- a/R/spec_tools.R
+++ b/R/spec_tools.R
@@ -21,6 +21,7 @@
}
html_color <- function(colors) {
+ colors <- as.character(colors)
sapply(colors, html_color_)
}
@@ -34,6 +35,7 @@
}
}
latex_color <- function(colors) {
+ colors <- as.character(colors)
sapply(colors, latex_color_)
}
@@ -61,3 +63,47 @@
x[is.na(x)] <- 0
return(x)
}
+
+#' Setup bootstrap tooltip
+#'
+#' @param title text for hovering message
+#' @param position How the tooltip should be positioned. Possible values are
+#' `right`(default), `top`, `bottom`, `left` & `auto`.
+#'
+#' @export
+spec_tooltip <- function(title, position = "right") {
+ position <- match.arg(position, c("right", "bottom", "top", "left", "auto"))
+ tooltip_options <- paste(
+ 'data-toggle="tooltip"',
+ paste0('data-placement="', position, '"'),
+ # ifelse(as_html, 'data-html="true"', NULL),
+ paste0('title="', title, '"'))
+ class(tooltip_options) <- "ke_tooltip"
+ return(tooltip_options)
+}
+
+#' Setup bootstrap popover
+#'
+#' @param content content for pop-over message
+#' @param title title for pop-over message.
+#' @param trigger Controls how the pop-over message should be triggered.
+#' Possible values include `hover` (default), `click`, `focus` and `manual`.
+#' @param position How the tooltip should be positioned. Possible values are
+#' `right`(default), `top`, `bottom`, `left` & `auto`.
+#'
+#' @export
+spec_popover <- function(content = NULL, title = NULL,
+ trigger = "hover", position = "right") {
+ trigger <- match.arg(trigger, c("hover", "click", "focus", "manual"),
+ several.ok = TRUE)
+ position <- match.arg(position, c("bottom", "top", "left", "right", "auto"),
+ several.ok = TRUE)
+ popover_options <- paste(
+ 'data-toggle="popover"',
+ paste0('data-trigger="', trigger, '"'),
+ paste0('data-placement="', position, '"'),
+ ifelse(!is.null(title), paste0('title="', title, '"'), ""),
+ paste0('data-content="', content, '"'))
+ class(popover_options) <- "ke_popover"
+ return(popover_options)
+}
diff --git a/docs/awesome_table_in_html.Rmd b/docs/awesome_table_in_html.Rmd
index fa6c222..66ad67e 100644
--- a/docs/awesome_table_in_html.Rmd
+++ b/docs/awesome_table_in_html.Rmd
@@ -143,34 +143,134 @@
row_spec(3:5, bold = T, color = "white", background = "#D7261E")
```
-# Cell Specification
-`cell_spec` is different from the rest. You should use it before you pipe the table into the `kable` function. It is designed in such a way that you can easily use it inside a `dplyr::mutate()` together with conditional logic like `ifelse`. Since everything happens before `kable`, you have to tell this function which format you want to go to, `html` or `latex`. To reduce unnecessary finger typing, I linked the `format` argument here with `knitr::kable`'s global format option `knitr.table.format`. If you have defined this option to be `html` at the beginning of your document (as suggested earlier), it is not necessary for you to define format again for every `cell_spec`.
-```{r, message=FALSE}
-library(dplyr)
-mtcars[1:5, 1:3] %>%
- mutate(
- car = row.names(.),
- mpg = ifelse(mpg > 20,
- cell_spec(mpg, "html", font_size = 18), mpg),
- cyl = cell_spec(cyl, "html", angle = (1:5)*60, hover_message = mpg,
- background = "red", color = "white", align = "center"),
- disp = ifelse(disp > 200,
- cell_spec(disp, "html", color = "red", bold = T),
- cell_spec(disp, "html", color = "green", italic = T)),
- fancy = c(12, 14, 16, 18, 20),
- fancy = cell_spec(fancy, "html", font_size = fancy,
- color = viridisLite::inferno(length(fancy), end = 0.8)),
- car = cell_spec(car, "html", bold = T,
- color = viridisLite::inferno(length(fancy), end = 0.8))
- ) %>%
- select(car, everything()) %>%
- kable("html", escape = F) %>%
- kable_styling("hover", full_width = F) %>%
- add_header_above(c(" ", "Hello" = 2, "World" = 2))
+
+## Header Rows
+One special case of `row_spec` is that you can specify the format of the header row via `row_spec(row = 0, ...)`.
+```{r}
+kable(dt, format = "html") %>%
+ kable_styling("striped", full_width = F) %>%
+ row_spec(0, angle = -45)
```
-##
+# Cell/Text Specification
+Function `cell_spec` is introduced in version 0.6.0 of `kableExtra`. Unlike `column_spec` and `row_spec`, **this function is designed to be used before the data.frame gets into the `kable` function**. Comparing with figuring out a list of 2 dimentional index for targeted cells, this design is way easier to learn and use and it fits perfectly well with `dplyr`'s `mutate` and `summarize` functions. With this design, there are two things to be noted:
+* Since `cell_spec` generates raw `HTML` or `LaTeX` code, make sure you remember to put `escape = FALSE` in `kable`. At the same time, you have to escape special symbols including `%` manually by yourself
+* `cell_spec` needs a way to know whether you want `html` or `latex`. You can specify it locally in function or globally via the `options(knitr.table.format = "latex")` method as suggested at the beginning. If you don't provide anything, this function will output as HTML by default.
+
+Currently, `cell_spec` supports features including bold, italic, monospace, text color, background color, align, font size & rotation angle. More features may be added in the future. Please see function documentations as reference.
+
+## Conditional logic
+It is very easy to use `cell_spec` with conditional logic. Here is an example.
+```{r, message=FALSE, warning=FALSE}
+library(dplyr)
+mtcars[1:10, 1:2] %>%
+ mutate(
+ car = row.names(.),
+ # You don't need format = "html" if you have ever defined options(knitr.table.format)
+ mpg = cell_spec(mpg, "html", color = ifelse(mpg > 20, "red", "blue")),
+ cyl = cell_spec(cyl, "html", color = "white", align = "c", angle = 45,
+ background = factor(cyl, c(4, 6, 8),
+ c("#666666", "#999999", "#BBBBBB")))
+ ) %>%
+ select(car, mpg, cyl) %>%
+ kable("html", escape = F) %>%
+ kable_styling("striped", full_width = F)
+```
+
+## Visualize data with Viridis Color
+This package also comes with a few helper functions, including `spec_color`, `spec_font_size` & `spec_angle`. These functions can rescale continuous variables to certain scales. For example, function `spec_color` would map a continuous variable to any [viridis color palettes](https://cran.r-project.org/web/packages/viridis/vignettes/intro-to-viridis.html). It offers a very visually impactful representation in a tabular format.
+
+```{r}
+iris[1:10, ] %>%
+ mutate_if(is.numeric, function(x) {
+ cell_spec(x, "html", bold = T, color = spec_color(x, end = 0.9),
+ font_size = spec_font_size(x))
+ }) %>%
+ mutate(Species = cell_spec(
+ Species, "html", color = "white", bold = T,
+ background = spec_color(1:10, end = 0.9, option = "A", direction = -1)
+ )) %>%
+ kable("html", escape = F, align = "c") %>%
+ kable_styling("striped", full_width = F)
+```
+
+In the example above, I'm using the `mutate` functions from `dplyr`. You don't have to use it. Base R solutions like `iris$Species <- cell_spec(iris$Species, color = "red")` also works.
+
+## Text Specification
+If you check the results of `cell_spec`, you will find that this function does nothing more than wrapping the text with appropriate HTML/LaTeX formatting syntax. The result of this function is just a vector of character strings. As a result, when you are writing a `rmarkdown` document or write some text in shiny apps, if you need extra markups other than **bold** or *italic*, you may use this function to `r text_spec("color", color = "red")`, `r text_spec("change font size ", font_size = 16)` or `r text_spec("rotate", angle = 30)` your text.
+
+An aliased function `text_spec` is also provided for a more literal writing experience. In HTML, there is no difference between these two functions.
+
+```{r}
+sometext <- strsplit(paste0(
+ "You can even try do do some crazy things like this paragraph. ",
+ "It seems to be a useless feature at this moment but who cares. ",
+ "It is so fun to play with color that I can't stop. ;)"
+), " ")[[1]]
+text_formatted <- paste(
+ text_spec(sometext, "html", color = spec_color(1:length(sometext), end = 0.9),
+ font_size = spec_font_size(1:length(sometext), begin = 5, end = 20)),
+ collapse = " ")
+
+# To display the text, type `r text_formatted` outside of the chunk
+```
+`r text_formatted`
+
+## Tooltip
+It's very easy to add a tooltip to text via `cell_spec`. For example, `text_spec("tooltip", color = "red", tooltip = "Hello World")` will give you something like `r text_spec("Hover over me", color = "red", tooltip = "Hello World")` (you need to wait for a few seconds before your browser renders it).
+
+Note that the original browser-based tooltip is slow. If you want to have a faster response, you may want to initialize bootstrap's tooltip by putting the following HTML code on the page.
+```
+<script>
+$(document).ready(function(){
+ $('[data-toggle="tooltip"]').tooltip();
+});
+</script>
+```
+
+In a rmarkdown document, you can just drop it outside of any R chunks. Unfortunately however, for rmarkdown pages with a **floating TOC** (like this page), you can't use bootstrap tooltips because there is a conflict in namespace between Bootstrap and JQueryUI (tocify.js). As a result, I can't provide a live demo here. If you want to have a tooltip together with a floating TOC, you should use `popover` which has a very similar effect.
+
+
+
+## Popover Message
+The popover message looks very similar with tooltip but it can hold more contents. Unlike tooltip which can minimally work without you manually enable that module, you **have to** enable the `popover` module to get it work. The upper side is that there is no conflict between Bootstrap & JQueryUI this time, you can use it without any concern.
+
+```
+<script>
+$(document).ready(function(){
+ $('[data-toggle="popover"]').popover();
+});
+</script>
+```
+
+<script>
+$(document).ready(function(){
+ $('[data-toggle="popover"]').popover();
+});
+</script>
+
+```{r}
+popover_dt <- data.frame(
+ position = c("top", "bottom", "right", "left"),
+ stringsAsFactors = FALSE
+)
+popover_dt$`Hover over these items` <- cell_spec(
+ paste("Message on", popover_dt$position), # Cell texts
+ popover = spec_popover(
+ content = popover_dt$position,
+ title = NULL, # title will add a Title Panel on top
+ position = popover_dt$position
+ ))
+kable(popover_dt, "html", escape = FALSE) %>%
+ kable_styling("striped", full_width = FALSE)
+```
+
+## Links
+You can add links to text via `text_spec("Google", link = "https://google.com")`: `r text_spec("Google", link = "https://google.com")`. If you want your hover message to be more obvious, it might be a good idea to put a `#` in the `link` option.
+`text_spec("Hover on me", link = "#", popover = "Hello")`:
+`r text_spec("Hover on me", link = "#", popover = "Hello")`
+
# Grouped Columns / Rows
## Add header rows to group columns
diff --git a/docs/awesome_table_in_html.html b/docs/awesome_table_in_html.html
index 98b43a6..34e2be4 100644
--- a/docs/awesome_table_in_html.html
+++ b/docs/awesome_table_in_html.html
@@ -11,7 +11,7 @@
<meta name="author" content="Hao Zhu" />
-<meta name="date" content="2017-10-12" />
+<meta name="date" content="2017-10-23" />
<title>Create Awesome HTML Table with knitr::kable and kableExtra</title>
@@ -217,16 +217,11 @@
<h1 class="title toc-ignore">Create Awesome HTML Table with knitr::kable and kableExtra</h1>
<h4 class="author"><em>Hao Zhu</em></h4>
-<h4 class="date"><em>2017-10-12</em></h4>
+<h4 class="date"><em>2017-10-23</em></h4>
</div>
-<script>
-$(document).ready(function(){
- $('[data-toggle="tooltip"]').tooltip();
-});
-</script>
<blockquote>
<p>Please see the package <a href="http://haozhu233.github.io/kableExtra/">documentation site</a> for how to use this package in LaTeX.</p>
</blockquote>
@@ -1801,48 +1796,179 @@
</tbody>
</table>
</div>
-</div>
-<div id="cell-specification" class="section level1">
-<h1>Cell Specification</h1>
-<p><code>cell_spec</code> is different from the rest. You should use it before you pipe the table into the <code>kable</code> function. It is designed in such a way that you can easily use it inside a <code>dplyr::mutate()</code> together with conditional logic like <code>ifelse</code>. Since everything happens before <code>kable</code>, you have to tell this function which format you want to go to, <code>html</code> or <code>latex</code>. To reduce unnecessary finger typing, I linked the <code>format</code> argument here with <code>knitr::kable</code>’s global format option <code>knitr.table.format</code>. If you have defined this option to be <code>html</code> at the beginning of your document (as suggested earlier), it is not necessary for you to define format again for every <code>cell_spec</code>.</p>
-<pre class="r"><code>library(dplyr)</code></pre>
-<pre><code>## Warning: package 'dplyr' was built under R version 3.4.2</code></pre>
-<pre class="r"><code>mtcars[1:5, 1:3] %>%
- mutate(
- car = row.names(.),
- mpg = ifelse(mpg > 20,
- cell_spec(mpg, "html", font_size = 18), mpg),
- cyl = cell_spec(cyl, "html", angle = (1:5)*60, hover_message = mpg,
- background = "red", color = "white", align = "center"),
- disp = ifelse(disp > 200,
- cell_spec(disp, "html", color = "red", bold = T),
- cell_spec(disp, "html", color = "green", italic = T)),
- fancy = c(12, 14, 16, 18, 20),
- fancy = cell_spec(fancy, "html", font_size = fancy,
- color = viridisLite::inferno(length(fancy), end = 0.8)),
- car = cell_spec(car, "html", bold = T,
- color = viridisLite::inferno(length(fancy), end = 0.8))
- ) %>%
- select(car, everything()) %>%
- kable("html", escape = F) %>%
- kable_styling("hover", full_width = F) %>%
- add_header_above(c(" ", "Hello" = 2, "World" = 2)) </code></pre>
-<table class="table table-hover" style="width: auto !important; margin-left: auto; margin-right: auto;">
+<div id="header-rows" class="section level2">
+<h2>Header Rows</h2>
+<p>One special case of <code>row_spec</code> is that you can specify the format of the header row via <code>row_spec(row = 0, ...)</code>.</p>
+<pre class="r"><code>kable(dt, format = "html") %>%
+ kable_styling("striped", full_width = F) %>%
+ row_spec(0, angle = -45)</code></pre>
+<table class="table table-striped" style="width: auto !important; margin-left: auto; margin-right: auto;">
<thead>
<tr>
-<th style="border-bottom:hidden">
+<th style="text-align:left;-webkit-transform: rotate(-45deg); -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg);">
</th>
-<th style="text-align:center; border-bottom:hidden; padding-bottom:0; padding-left:3px;padding-right:3px;" colspan="2">
-<div style="border-bottom: 1px solid #ddd; padding-bottom: 5px;">
-Hello
-</div>
+<th style="text-align:right;-webkit-transform: rotate(-45deg); -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg);">
+mpg
</th>
-<th style="text-align:center; border-bottom:hidden; padding-bottom:0; padding-left:3px;padding-right:3px;" colspan="2">
-<div style="border-bottom: 1px solid #ddd; padding-bottom: 5px;">
-World
-</div>
+<th style="text-align:right;-webkit-transform: rotate(-45deg); -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg);">
+cyl
+</th>
+<th style="text-align:right;-webkit-transform: rotate(-45deg); -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg);">
+disp
+</th>
+<th style="text-align:right;-webkit-transform: rotate(-45deg); -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg);">
+hp
+</th>
+<th style="text-align:right;-webkit-transform: rotate(-45deg); -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg);">
+drat
+</th>
+<th style="text-align:right;-webkit-transform: rotate(-45deg); -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg);">
+wt
</th>
</tr>
+</thead>
+<tbody>
+<tr>
+<td style="text-align:left;">
+Mazda RX4
+</td>
+<td style="text-align:right;">
+21.0
+</td>
+<td style="text-align:right;">
+6
+</td>
+<td style="text-align:right;">
+160
+</td>
+<td style="text-align:right;">
+110
+</td>
+<td style="text-align:right;">
+3.90
+</td>
+<td style="text-align:right;">
+2.620
+</td>
+</tr>
+<tr>
+<td style="text-align:left;">
+Mazda RX4 Wag
+</td>
+<td style="text-align:right;">
+21.0
+</td>
+<td style="text-align:right;">
+6
+</td>
+<td style="text-align:right;">
+160
+</td>
+<td style="text-align:right;">
+110
+</td>
+<td style="text-align:right;">
+3.90
+</td>
+<td style="text-align:right;">
+2.875
+</td>
+</tr>
+<tr>
+<td style="text-align:left;">
+Datsun 710
+</td>
+<td style="text-align:right;">
+22.8
+</td>
+<td style="text-align:right;">
+4
+</td>
+<td style="text-align:right;">
+108
+</td>
+<td style="text-align:right;">
+93
+</td>
+<td style="text-align:right;">
+3.85
+</td>
+<td style="text-align:right;">
+2.320
+</td>
+</tr>
+<tr>
+<td style="text-align:left;">
+Hornet 4 Drive
+</td>
+<td style="text-align:right;">
+21.4
+</td>
+<td style="text-align:right;">
+6
+</td>
+<td style="text-align:right;">
+258
+</td>
+<td style="text-align:right;">
+110
+</td>
+<td style="text-align:right;">
+3.08
+</td>
+<td style="text-align:right;">
+3.215
+</td>
+</tr>
+<tr>
+<td style="text-align:left;">
+Hornet Sportabout
+</td>
+<td style="text-align:right;">
+18.7
+</td>
+<td style="text-align:right;">
+8
+</td>
+<td style="text-align:right;">
+360
+</td>
+<td style="text-align:right;">
+175
+</td>
+<td style="text-align:right;">
+3.15
+</td>
+<td style="text-align:right;">
+3.440
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<div id="celltext-specification" class="section level1">
+<h1>Cell/Text Specification</h1>
+<p>Function <code>cell_spec</code> is introduced in version 0.6.0 of <code>kableExtra</code>. Unlike <code>column_spec</code> and <code>row_spec</code>, <strong>this function is designed to be used before the data.frame gets into the <code>kable</code> function</strong>. Comparing with figuring out a list of 2 dimentional index for targeted cells, this design is way easier to learn and use and it fits perfectly well with <code>dplyr</code>’s <code>mutate</code> and <code>summarize</code> functions. With this design, there are two things to be noted: * Since <code>cell_spec</code> generates raw <code>HTML</code> or <code>LaTeX</code> code, make sure you remember to put <code>escape = FALSE</code> in <code>kable</code>. At the same time, you have to escape special symbols including <code>%</code> manually by yourself * <code>cell_spec</code> needs a way to know whether you want <code>html</code> or <code>latex</code>. You can specify it locally in function or globally via the <code>options(knitr.table.format = "latex")</code> method as suggested at the beginning. If you don’t provide anything, this function will output as HTML by default.</p>
+<p>Currently, <code>cell_spec</code> supports features including bold, italic, monospace, text color, background color, align, font size & rotation angle. More features may be added in the future. Please see function documentations as reference.</p>
+<div id="conditional-logic" class="section level2">
+<h2>Conditional logic</h2>
+<p>It is very easy to use <code>cell_spec</code> with conditional logic. Here is an example.</p>
+<pre class="r"><code>library(dplyr)
+mtcars[1:10, 1:2] %>%
+ mutate(
+ car = row.names(.),
+ # You don't need format = "html" if you have ever defined options(knitr.table.format)
+ mpg = cell_spec(mpg, "html", color = ifelse(mpg > 20, "red", "blue")),
+ cyl = cell_spec(cyl, "html", color = "white", align = "c", angle = 45,
+ background = factor(cyl, c(4, 6, 8),
+ c("#666666", "#999999", "#BBBBBB")))
+ ) %>%
+ select(car, mpg, cyl) %>%
+ kable("html", escape = F) %>%
+ kable_styling("striped", full_width = F)</code></pre>
+<table class="table table-striped" style="width: auto !important; margin-left: auto; margin-right: auto;">
+<thead>
<tr>
<th style="text-align:left;">
car
@@ -1853,152 +1979,435 @@
<th style="text-align:left;">
cyl
</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td style="text-align:left;">
+Mazda RX4
+</td>
+<td style="text-align:left;">
+<span style="color: red;">21</span>
+</td>
+<td style="text-align:left;">
+<span style="-webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -ms-transform: rotate(45deg); -o-transform: rotate(45deg); transform: rotate(45deg); display: inline-block; "><span style="color: white;border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #999999;text-align: c;">6</span></span>
+</td>
+</tr>
+<tr>
+<td style="text-align:left;">
+Mazda RX4 Wag
+</td>
+<td style="text-align:left;">
+<span style="color: red;">21</span>
+</td>
+<td style="text-align:left;">
+<span style="-webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -ms-transform: rotate(45deg); -o-transform: rotate(45deg); transform: rotate(45deg); display: inline-block; "><span style="color: white;border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #999999;text-align: c;">6</span></span>
+</td>
+</tr>
+<tr>
+<td style="text-align:left;">
+Datsun 710
+</td>
+<td style="text-align:left;">
+<span style="color: red;">22.8</span>
+</td>
+<td style="text-align:left;">
+<span style="-webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -ms-transform: rotate(45deg); -o-transform: rotate(45deg); transform: rotate(45deg); display: inline-block; "><span style="color: white;border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #666666;text-align: c;">4</span></span>
+</td>
+</tr>
+<tr>
+<td style="text-align:left;">
+Hornet 4 Drive
+</td>
+<td style="text-align:left;">
+<span style="color: red;">21.4</span>
+</td>
+<td style="text-align:left;">
+<span style="-webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -ms-transform: rotate(45deg); -o-transform: rotate(45deg); transform: rotate(45deg); display: inline-block; "><span style="color: white;border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #999999;text-align: c;">6</span></span>
+</td>
+</tr>
+<tr>
+<td style="text-align:left;">
+Hornet Sportabout
+</td>
+<td style="text-align:left;">
+<span style="color: blue;">18.7</span>
+</td>
+<td style="text-align:left;">
+<span style="-webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -ms-transform: rotate(45deg); -o-transform: rotate(45deg); transform: rotate(45deg); display: inline-block; "><span style="color: white;border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #BBBBBB;text-align: c;">8</span></span>
+</td>
+</tr>
+<tr>
+<td style="text-align:left;">
+Valiant
+</td>
+<td style="text-align:left;">
+<span style="color: blue;">18.1</span>
+</td>
+<td style="text-align:left;">
+<span style="-webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -ms-transform: rotate(45deg); -o-transform: rotate(45deg); transform: rotate(45deg); display: inline-block; "><span style="color: white;border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #999999;text-align: c;">6</span></span>
+</td>
+</tr>
+<tr>
+<td style="text-align:left;">
+Duster 360
+</td>
+<td style="text-align:left;">
+<span style="color: blue;">14.3</span>
+</td>
+<td style="text-align:left;">
+<span style="-webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -ms-transform: rotate(45deg); -o-transform: rotate(45deg); transform: rotate(45deg); display: inline-block; "><span style="color: white;border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #BBBBBB;text-align: c;">8</span></span>
+</td>
+</tr>
+<tr>
+<td style="text-align:left;">
+Merc 240D
+</td>
+<td style="text-align:left;">
+<span style="color: red;">24.4</span>
+</td>
+<td style="text-align:left;">
+<span style="-webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -ms-transform: rotate(45deg); -o-transform: rotate(45deg); transform: rotate(45deg); display: inline-block; "><span style="color: white;border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #666666;text-align: c;">4</span></span>
+</td>
+</tr>
+<tr>
+<td style="text-align:left;">
+Merc 230
+</td>
+<td style="text-align:left;">
+<span style="color: red;">22.8</span>
+</td>
+<td style="text-align:left;">
+<span style="-webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -ms-transform: rotate(45deg); -o-transform: rotate(45deg); transform: rotate(45deg); display: inline-block; "><span style="color: white;border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #666666;text-align: c;">4</span></span>
+</td>
+</tr>
+<tr>
+<td style="text-align:left;">
+Merc 280
+</td>
+<td style="text-align:left;">
+<span style="color: blue;">19.2</span>
+</td>
+<td style="text-align:left;">
+<span style="-webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -ms-transform: rotate(45deg); -o-transform: rotate(45deg); transform: rotate(45deg); display: inline-block; "><span style="color: white;border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #999999;text-align: c;">6</span></span>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div id="visualize-data-with-viridis-color" class="section level2">
+<h2>Visualize data with Viridis Color</h2>
+<p>This package also comes with a few helper functions, including <code>spec_color</code>, <code>spec_font_size</code> & <code>spec_angle</code>. These functions can rescale continuous variables to certain scales. For example, function <code>spec_color</code> would map a continuous variable to any <a href="https://cran.r-project.org/web/packages/viridis/vignettes/intro-to-viridis.html">viridis color palettes</a>. It offers a very visually impactful representation in a tabular format.</p>
+<pre class="r"><code>iris[1:10, ] %>%
+ mutate_if(is.numeric, function(x) {
+ cell_spec(x, "html", bold = T, color = spec_color(x, end = 0.9),
+ font_size = spec_font_size(x))
+ }) %>%
+ mutate(Species = cell_spec(
+ Species, "html", color = "white", bold = T,
+ background = spec_color(1:10, end = 0.9, option = "A", direction = -1)
+ )) %>%
+ kable("html", escape = F, align = "c") %>%
+ kable_styling("striped", full_width = F)</code></pre>
+<table class="table table-striped" style="width: auto !important; margin-left: auto; margin-right: auto;">
+<thead>
+<tr>
+<th style="text-align:center;">
+Sepal.Length
+</th>
+<th style="text-align:center;">
+Sepal.Width
+</th>
+<th style="text-align:center;">
+Petal.Length
+</th>
+<th style="text-align:center;">
+Petal.Width
+</th>
+<th style="text-align:center;">
+Species
+</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(40, 174, 128, 1);font-size: 14px;">5.1</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(31, 154, 138, 1);font-size: 13px;">3.5</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(62, 75, 138, 1);font-size: 10px;">1.4</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(53, 96, 141, 1);font-size: 11px;">0.2</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: white;border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: rgba(254, 206, 145, 1);">setosa</span>
+</td>
+</tr>
+<tr>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(37, 131, 142, 1);font-size: 12px;">4.9</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(72, 34, 116, 1);font-size: 9px;">3</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(62, 75, 138, 1);font-size: 10px;">1.4</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(53, 96, 141, 1);font-size: 11px;">0.2</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: white;border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: rgba(254, 160, 109, 1);">setosa</span>
+</td>
+</tr>
+<tr>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(57, 87, 140, 1);font-size: 10px;">4.7</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(56, 88, 140, 1);font-size: 10px;">3.2</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(68, 1, 84, 1);font-size: 8px;">1.3</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(53, 96, 141, 1);font-size: 11px;">0.2</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: white;border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: rgba(246, 110, 92, 1);">setosa</span>
+</td>
+</tr>
+<tr>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(67, 62, 133, 1);font-size: 10px;">4.6</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(67, 62, 133, 1);font-size: 10px;">3.1</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(37, 131, 142, 1);font-size: 12px;">1.5</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(53, 96, 141, 1);font-size: 11px;">0.2</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: white;border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: rgba(222, 73, 104, 1);">setosa</span>
+</td>
+</tr>
+<tr>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(31, 154, 138, 1);font-size: 13px;">5</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(41, 175, 127, 1);font-size: 14px;">3.6</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(62, 75, 138, 1);font-size: 10px;">1.4</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(53, 96, 141, 1);font-size: 11px;">0.2</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: white;border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: rgba(183, 55, 121, 1);">setosa</span>
+</td>
+</tr>
+<tr>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(187, 223, 39, 1);font-size: 16px;">5.4</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(187, 223, 39, 1);font-size: 16px;">3.9</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(187, 223, 39, 1);font-size: 16px;">1.7</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(187, 223, 39, 1);font-size: 16px;">0.4</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: white;border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: rgba(140, 41, 129, 1);">setosa</span>
+</td>
+</tr>
+<tr>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(67, 62, 133, 1);font-size: 10px;">4.6</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(37, 131, 142, 1);font-size: 12px;">3.4</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(62, 75, 138, 1);font-size: 10px;">1.4</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(34, 168, 132, 1);font-size: 13px;">0.3</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: white;border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: rgba(100, 26, 128, 1);">setosa</span>
+</td>
+</tr>
+<tr>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(31, 154, 138, 1);font-size: 13px;">5</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(37, 131, 142, 1);font-size: 12px;">3.4</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(37, 131, 142, 1);font-size: 12px;">1.5</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(53, 96, 141, 1);font-size: 11px;">0.2</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: white;border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: rgba(60, 15, 112, 1);">setosa</span>
+</td>
+</tr>
+<tr>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(68, 1, 84, 1);font-size: 8px;">4.4</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(68, 1, 84, 1);font-size: 8px;">2.9</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(62, 75, 138, 1);font-size: 10px;">1.4</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(53, 96, 141, 1);font-size: 11px;">0.2</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: white;border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: rgba(20, 14, 54, 1);">setosa</span>
+</td>
+</tr>
+<tr>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(37, 131, 142, 1);font-size: 12px;">4.9</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(67, 62, 133, 1);font-size: 10px;">3.1</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(37, 131, 142, 1);font-size: 12px;">1.5</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: rgba(68, 1, 84, 1);font-size: 8px;">0.1</span>
+</td>
+<td style="text-align:center;">
+<span style=" font-weight: bold;color: white;border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: rgba(0, 0, 4, 1);">setosa</span>
+</td>
+</tr>
+</tbody>
+</table>
+<p>In the example above, I’m using the <code>mutate</code> functions from <code>dplyr</code>. You don’t have to use it. Base R solutions like <code>iris$Species <- cell_spec(iris$Species, color = "red")</code> also works.</p>
+</div>
+<div id="text-specification" class="section level2">
+<h2>Text Specification</h2>
+<p>If you check the results of <code>cell_spec</code>, you will find that this function does nothing more than wrapping the text with appropriate HTML/LaTeX formatting syntax. The result of this function is just a vector of character strings. As a result, when you are writing a <code>rmarkdown</code> document or write some text in shiny apps, if you need extra markups other than <strong>bold</strong> or <em>italic</em>, you may use this function to <span style="color: red;">color</span>, <span style="font-size: 16px;">change font size </span> or <span style="-webkit-transform: rotate(30deg); -moz-transform: rotate(30deg); -ms-transform: rotate(30deg); -o-transform: rotate(30deg); transform: rotate(30deg); display: inline-block; "><span style>rotate</span></span> your text.</p>
+<p>An aliased function <code>text_spec</code> is also provided for a more literal writing experience. In HTML, there is no difference between these two functions.</p>
+<pre class="r"><code>sometext <- strsplit(paste0(
+ "You can even try do do some crazy things like this paragraph. ",
+ "It seems to be a useless feature at this moment but who cares. ",
+ "It is so fun to play with color that I can't stop. ;)"
+), " ")[[1]]
+text_formatted <- paste(
+ text_spec(sometext, "html", color = spec_color(1:length(sometext), end = 0.9),
+ font_size = spec_font_size(1:length(sometext), begin = 5, end = 20)),
+ collapse = " ")
+
+# To display the text, type `r text_formatted` outside of the chunk</code></pre>
+<p><span style="color: rgba(68, 1, 84, 1);font-size: 5px;">You</span> <span style="color: rgba(70, 10, 93, 1);font-size: 5px;">can</span> <span style="color: rgba(72, 20, 102, 1);font-size: 6px;">even</span> <span style="color: rgba(72, 28, 110, 1);font-size: 6px;">try</span> <span style="color: rgba(72, 36, 117, 1);font-size: 7px;">do</span> <span style="color: rgba(71, 43, 122, 1);font-size: 7px;">do</span> <span style="color: rgba(70, 51, 127, 1);font-size: 7px;">some</span> <span style="color: rgba(68, 58, 131, 1);font-size: 8px;">crazy</span> <span style="color: rgba(65, 65, 134, 1);font-size: 8px;">things</span> <span style="color: rgba(62, 73, 137, 1);font-size: 9px;">like</span> <span style="color: rgba(60, 80, 139, 1);font-size: 9px;">this</span> <span style="color: rgba(57, 87, 140, 1);font-size: 9px;">paragraph.</span> <span style="color: rgba(53, 94, 141, 1);font-size: 10px;">It</span> <span style="color: rgba(50, 100, 142, 1);font-size: 10px;">seems</span> <span style="color: rgba(48, 105, 142, 1);font-size: 11px;">to</span> <span style="color: rgba(45, 112, 142, 1);font-size: 11px;">be</span> <span style="color: rgba(43, 117, 142, 1);font-size: 11px;">a</span> <span style="color: rgba(41, 123, 142, 1);font-size: 12px;">useless</span> <span style="color: rgba(38, 130, 142, 1);font-size: 12px;">feature</span> <span style="color: rgba(36, 135, 142, 1);font-size: 13px;">at</span> <span style="color: rgba(34, 141, 141, 1);font-size: 13px;">this</span> <span style="color: rgba(32, 146, 140, 1);font-size: 14px;">moment</span> <span style="color: rgba(31, 153, 138, 1);font-size: 14px;">but</span> <span style="color: rgba(31, 159, 136, 1);font-size: 14px;">who</span> <span style="color: rgba(32, 163, 134, 1);font-size: 15px;">cares.</span> <span style="color: rgba(36, 170, 131, 1);font-size: 15px;">It</span> <span style="color: rgba(41, 175, 127, 1);font-size: 16px;">is</span> <span style="color: rgba(49, 181, 123, 1);font-size: 16px;">so</span> <span style="color: rgba(59, 187, 117, 1);font-size: 16px;">fun</span> <span style="color: rgba(70, 192, 111, 1);font-size: 17px;">to</span> <span style="color: rgba(83, 197, 105, 1);font-size: 17px;">play</span> <span style="color: rgba(95, 202, 97, 1);font-size: 18px;">with</span> <span style="color: rgba(110, 206, 88, 1);font-size: 18px;">color</span> <span style="color: rgba(123, 209, 81, 1);font-size: 18px;">that</span> <span style="color: rgba(138, 214, 71, 1);font-size: 19px;">I</span> <span style="color: rgba(155, 217, 60, 1);font-size: 19px;">can’t</span> <span style="color: rgba(171, 220, 50, 1);font-size: 20px;">stop.</span> <span style="color: rgba(187, 223, 39, 1);font-size: 20px;">;)</span></p>
+</div>
+<div id="tooltip" class="section level2">
+<h2>Tooltip</h2>
+<p>It’s very easy to add a tooltip to text via <code>cell_spec</code>. For example, <code>text_spec("tooltip", color = "red", tooltip = "Hello World")</code> will give you something like <span style="color: red;" data-toggle="tooltip" data-placement="right" title="Hello World">Hover over me</span> (you need to wait for a few seconds before your browser renders it).</p>
+<p>Note that the original browser-based tooltip is slow. If you want to have a faster response, you may want to initialize bootstrap’s tooltip by putting the following HTML code on the page.</p>
+<pre><code><script>
+$(document).ready(function(){
+ $('[data-toggle="tooltip"]').tooltip();
+});
+</script></code></pre>
+<p>In a rmarkdown document, you can just drop it outside of any R chunks. Unfortunately however, for rmarkdown pages with a <strong>floating TOC</strong> (like this page), you can’t use bootstrap tooltips because there is a conflict in namespace between Bootstrap and JQueryUI (tocify.js). As a result, I can’t provide a live demo here. If you want to have a tooltip together with a floating TOC, you should use <code>popover</code> which has a very similar effect.</p>
+</div>
+<div id="popover-message" class="section level2">
+<h2>Popover Message</h2>
+<p>The popover message looks very similar with tooltip but it can hold more contents. Unlike tooltip which can minimally work without you manually enable that module, you <strong>have to</strong> enable the <code>popover</code> module to get it work. The upper side is that there is no conflict between Bootstrap & JQueryUI this time, you can use it without any concern.</p>
+<pre><code><script>
+$(document).ready(function(){
+ $('[data-toggle="popover"]').popover();
+});
+</script></code></pre>
+<script>
+$(document).ready(function(){
+ $('[data-toggle="popover"]').popover();
+});
+</script>
+<pre class="r"><code>popover_dt <- data.frame(
+ position = c("top", "bottom", "right", "left"),
+ stringsAsFactors = FALSE
+)
+popover_dt$`Hover over these items` <- cell_spec(
+ paste("Message on", popover_dt$position), # Cell texts
+ popover = spec_popover(
+ content = popover_dt$position,
+ title = NULL, # title will add a Title Panel on top
+ position = popover_dt$position
+ ))
+kable(popover_dt, "html", escape = FALSE) %>%
+ kable_styling("striped", full_width = FALSE)</code></pre>
+<table class="table table-striped" style="width: auto !important; margin-left: auto; margin-right: auto;">
+<thead>
+<tr>
<th style="text-align:left;">
-disp
+position
</th>
<th style="text-align:left;">
-fancy
+Hover over these items
</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left;">
-<div style=" font-weight: bold;color: #000004FF;">
-Mazda RX4
-</div>
+top
</td>
<td style="text-align:left;">
-<div style="font-size: 18px;">
-21
-</div>
-</td>
-<td style="text-align:left;">
-<div style="color: white;border-radius: 4px; padding-right: 2px; background-color: red;text-align: center;-webkit-transform: rotate(60deg); -moz-transform: rotate(60deg); -ms-transform: rotate(60deg); -o-transform: rotate(60deg);" data-toggle="tooltip" title="<div style="font-size: 18px;">21</div>">
-6
-</div>
-</td>
-<td style="text-align:left;">
-<div style=" font-style: italic;color: green;">
-160
-</div>
-</td>
-<td style="text-align:left;">
-<div style="color: #000004FF;font-size: 12px;">
-12
-</div>
+<span style data-toggle="popover" data-trigger="hover" data-placement="top" data-content="top">Message on top</span>
</td>
</tr>
<tr>
<td style="text-align:left;">
-<div style=" font-weight: bold;color: #420A68FF;">
-Mazda RX4 Wag
-</div>
+bottom
</td>
<td style="text-align:left;">
-<div style="font-size: 18px;">
-21
-</div>
-</td>
-<td style="text-align:left;">
-<div style="color: white;border-radius: 4px; padding-right: 2px; background-color: red;text-align: center;-webkit-transform: rotate(120deg); -moz-transform: rotate(120deg); -ms-transform: rotate(120deg); -o-transform: rotate(120deg);" data-toggle="tooltip" title="<div style="font-size: 18px;">21</div>">
-6
-</div>
-</td>
-<td style="text-align:left;">
-<div style=" font-style: italic;color: green;">
-160
-</div>
-</td>
-<td style="text-align:left;">
-<div style="color: #420A68FF;font-size: 14px;">
-14
-</div>
+<span style data-toggle="popover" data-trigger="hover" data-placement="bottom" data-content="bottom">Message on bottom</span>
</td>
</tr>
<tr>
<td style="text-align:left;">
-<div style=" font-weight: bold;color: #932667FF;">
-Datsun 710
-</div>
+right
</td>
<td style="text-align:left;">
-<div style="font-size: 18px;">
-22.8
-</div>
-</td>
-<td style="text-align:left;">
-<div style="color: white;border-radius: 4px; padding-right: 2px; background-color: red;text-align: center;-webkit-transform: rotate(180deg); -moz-transform: rotate(180deg); -ms-transform: rotate(180deg); -o-transform: rotate(180deg);" data-toggle="tooltip" title="<div style="font-size: 18px;">22.8</div>">
-4
-</div>
-</td>
-<td style="text-align:left;">
-<div style=" font-style: italic;color: green;">
-108
-</div>
-</td>
-<td style="text-align:left;">
-<div style="color: #932667FF;font-size: 16px;">
-16
-</div>
+<span style data-toggle="popover" data-trigger="hover" data-placement="right" data-content="right">Message on right</span>
</td>
</tr>
<tr>
<td style="text-align:left;">
-<div style=" font-weight: bold;color: #DD513AFF;">
-Hornet 4 Drive
-</div>
+left
</td>
<td style="text-align:left;">
-<div style="font-size: 18px;">
-21.4
-</div>
-</td>
-<td style="text-align:left;">
-<div style="color: white;border-radius: 4px; padding-right: 2px; background-color: red;text-align: center;-webkit-transform: rotate(240deg); -moz-transform: rotate(240deg); -ms-transform: rotate(240deg); -o-transform: rotate(240deg);" data-toggle="tooltip" title="<div style="font-size: 18px;">21.4</div>">
-6
-</div>
-</td>
-<td style="text-align:left;">
-<div style=" font-weight: bold;color: red;">
-258
-</div>
-</td>
-<td style="text-align:left;">
-<div style="color: #DD513AFF;font-size: 18px;">
-18
-</div>
-</td>
-</tr>
-<tr>
-<td style="text-align:left;">
-<div style=" font-weight: bold;color: #FCA50AFF;">
-Hornet Sportabout
-</div>
-</td>
-<td style="text-align:left;">
-18.7
-</td>
-<td style="text-align:left;">
-<div style="color: white;border-radius: 4px; padding-right: 2px; background-color: red;text-align: center;-webkit-transform: rotate(300deg); -moz-transform: rotate(300deg); -ms-transform: rotate(300deg); -o-transform: rotate(300deg);" data-toggle="tooltip" title="18.7">
-8
-</div>
-</td>
-<td style="text-align:left;">
-<div style=" font-weight: bold;color: red;">
-360
-</div>
-</td>
-<td style="text-align:left;">
-<div style="color: #FCA50AFF;font-size: 20px;">
-20
-</div>
+<span style data-toggle="popover" data-trigger="hover" data-placement="left" data-content="left">Message on left</span>
</td>
</tr>
</tbody>
</table>
-<div id="section" class="section level2">
-<h2></h2>
+</div>
+<div id="links" class="section level2">
+<h2>Links</h2>
+<p>You can add links to text via <code>text_spec("Google", link = "https://google.com")</code>: <a href="https://google.com" style>Google</a>. If you want your hover message to be more obvious, it might be a good idea to put a <code>#</code> in the <code>link</code> option. <code>text_spec("Hover on me", link = "#", popover = "Hello")</code>: <a href="#" style data-toggle="popover" data-trigger="hover" data-placement="right" data-content="Hello">Hover on me</a></p>
</div>
</div>
<div id="grouped-columns-rows" class="section level1">
@@ -3005,7 +3414,7 @@
3
</td>
<td style="text-align:center;">
-1
+0
</td>
</tr>
<tr>
@@ -3021,7 +3430,7 @@
5
</td>
<td style="text-align:center;">
-0
+1
</td>
</tr>
<tr>
@@ -3029,7 +3438,7 @@
6
</td>
<td style="text-align:center;">
-1
+0
</td>
</tr>
<tr>
@@ -3086,7 +3495,7 @@
12
</td>
<td style="text-align:center;">
-0
+1
</td>
</tr>
<tr>
@@ -3105,7 +3514,7 @@
14
</td>
<td style="text-align:center;">
-0
+1
</td>
</tr>
<tr>
diff --git a/docs/awesome_table_in_pdf.Rmd b/docs/awesome_table_in_pdf.Rmd
index aa7888c..53fa39a 100644
--- a/docs/awesome_table_in_pdf.Rmd
+++ b/docs/awesome_table_in_pdf.Rmd
@@ -198,6 +198,16 @@
row_spec(3:5, bold = T, color = "white", background = "black")
```
+## Header Rows
+One special case of `row_spec` is that you can specify the format of the header row via `row_spec(row = 0, ...)`.
+```{r}
+kable(dt, format = "latex", booktabs = T, align = "c") %>%
+ kable_styling(latex_options = "striped", full_width = F) %>%
+ row_spec(0, angle = 45)
+```
+
+
+
# Cell/Text Specification
Function `cell_spec` is introduced in version 0.6.0 of `kableExtra`. Unlike `column_spec` and `row_spec`, **this function is designed to be used before the data.frame gets into the `kable` function**. Comparing with figuring out a list of 2 dimentional index for targeted cells, this design is way easier to learn and use and it fits perfectly well with `dplyr`'s `mutate` and `summarize` functions. With this design, there are two things to be noted:
* Since `cell_spec` generates raw `HTML` or `LaTeX` code, make sure you remember to put `escape = FALSE` in `kable`. At the same time, you have to escape special symbols including `%` manually by yourself
@@ -207,15 +217,14 @@
## Conditional logic
It is very easy to use `cell_spec` with conditional logic. Here is an example.
-```{r}
-suppressMessages(library(dplyr))
+```{r, message=FALSE, warning=FALSE}
+library(dplyr)
mtcars[1:10, 1:2] %>%
mutate(
- # Since we are using tibble, we need to get the rownames
car = row.names(.),
- # You don't need "latex" if you have ever defined options(knitr.table.format)
- mpg = cell_spec(mpg, "latex", color = ifelse(mpg > 20, "green", "red")),
- cyl = cell_spec(cyl, "latex", color = "white", align = "c", angle = 90,
+ # You don't need format = "latex" if you have ever defined options(knitr.table.format)
+ mpg = cell_spec(mpg, "latex", color = ifelse(mpg > 20, "red", "blue")),
+ cyl = cell_spec(cyl, "latex", color = "white", align = "c", angle = 45,
background = factor(cyl, c(4, 6, 8),
c("#666666", "#999999", "#BBBBBB")))
) %>%
@@ -229,11 +238,11 @@
```{r}
iris[1:10, ] %>%
mutate_if(is.numeric, function(x) {
- cell_spec(x, bold = T, color = spec_color(x, end = 0.9),
+ cell_spec(x, "latex", bold = T, color = spec_color(x, end = 0.9),
font_size = spec_font_size(x))
}) %>%
mutate(Species = cell_spec(
- Species, color = "white", bold = T,
+ Species, "latex", color = "white", bold = T,
background = spec_color(1:10, end = 0.9, option = "A", direction = -1)
)) %>%
kable("latex", escape = F, booktabs = T, linesep = "", align = "c")
@@ -244,15 +253,17 @@
## Text Specification
If you check the results of `cell_spec`, you will find that this function does nothing more than wrapping the text with appropriate HTML/LaTeX formatting syntax. The result of this function is just a vector of character strings. As a result, when you are writing a `rmarkdown` document or write some text in shiny apps, if you need extra markups other than **bold** or *italic*, you may use this function to `r text_spec("color", color = "red")`, `r text_spec("change font size ", font_size = 16)` or `r text_spec("rotate", angle = 30)` your text.
-An alias function `text_spec` is also provided for a more literal writing experience. The only difference is that in LaTeX, unless you specify `latex_background_in_cell = FALSE` (default is `TRUE`) in `cell_spec`, it will define cell background color as `\cellcolor{}`, which doesn't work outside of a table, while for `text_spec`, the default value for `latex_background_in_cell` is `FALSE`.
+An aliased function `text_spec` is also provided for a more literal writing experience. The only difference is that in LaTeX, unless you specify `latex_background_in_cell = FALSE` (default is `TRUE`) in `cell_spec`, it will define cell background color as `\cellcolor{}`, which doesn't work outside of a table, while for `text_spec`, the default value for `latex_background_in_cell` is `FALSE`.
```{r}
sometext <- strsplit(paste0(
"You can even try do do some crazy things like this paragraph. Although ",
- "it's probably a useless feature but you may find it's fun to play with. :)"
+ "it seems to be a useless feature at this moment, it is so fun to play ",
+ "with that I can't stop. :P"
), " ")[[1]]
text_formatted <- paste(
- text_spec(sometext, color = spec_color(1:length(sometext), end = 0.8, option = "A")),
+ text_spec(sometext, "latex", color = spec_color(1:length(sometext), end = 0.9),
+ font_size = spec_font_size(1:length(sometext), begin = 5, end = 20)),
collapse = " ")
# To display the text, type `r text_formatted` outside of the chunk
diff --git a/docs/awesome_table_in_pdf.pdf b/docs/awesome_table_in_pdf.pdf
index d84b4bc..3987820 100644
--- a/docs/awesome_table_in_pdf.pdf
+++ b/docs/awesome_table_in_pdf.pdf
Binary files differ
diff --git a/inst/.DS_Store b/inst/.DS_Store
index 5219a51..a0b4f9a 100644
--- a/inst/.DS_Store
+++ b/inst/.DS_Store
Binary files differ
diff --git a/man/cell_spec.Rd b/man/cell_spec.Rd
index 9d5e050..2e758b0 100644
--- a/man/cell_spec.Rd
+++ b/man/cell_spec.Rd
@@ -5,14 +5,16 @@
\alias{text_spec}
\title{Specify Cell/Text format}
\usage{
-cell_spec(x, format, bold = F, italic = F, monospace = F, color = NULL,
- background = NULL, align = NULL, font_size = NULL, angle = NULL,
- tooltip = NULL, background_as_tile = TRUE,
+cell_spec(x, format, bold = FALSE, italic = FALSE, monospace = FALSE,
+ color = NULL, background = NULL, align = NULL, font_size = NULL,
+ angle = NULL, tooltip = NULL, popover = NULL, link = NULL,
+ escape = TRUE, background_as_tile = TRUE,
latex_background_in_cell = TRUE)
-text_spec(x, format, bold = F, italic = F, monospace = F, color = NULL,
- background = NULL, align = NULL, font_size = NULL, angle = NULL,
- tooltip = NULL, background_as_tile = TRUE,
+text_spec(x, format, bold = FALSE, italic = FALSE, monospace = FALSE,
+ color = NULL, background = NULL, align = NULL, font_size = NULL,
+ angle = NULL, tooltip = NULL, popover = NULL, link = NULL,
+ escape = TRUE, background_as_tile = TRUE,
latex_background_in_cell = FALSE)
}
\arguments{
@@ -40,12 +42,25 @@
\code{initial} and \code{inherit} while for LaTeX, you can only choose
from \code{l}, \code{c} & \code{r}.}
-\item{font_size}{j}
+\item{font_size}{A numeric input for font size. For HTML, you can also use
+options}
\item{angle}{0-360, degree that the text will rotate. Can be a vector.}
\item{tooltip}{A vector of strings to be displayed as tooltip.
-Obviously, this feature is only available in HTML.}
+Obviously, this feature is only available in HTML. Read the package
+vignette to see how to use bootstrap tooltip css to improve the loading
+speed and look.}
+
+\item{popover}{Similar with tooltip but can hold more contents. The best way
+to build a popover is through \code{spec_popover()}. If you only provide a text
+string, it will be used as content. Note that You have to enable this
+bootstrap module manually. Read the package vignette to see how.}
+
+\item{link}{A vector of strings for url links. Can be used together with
+tooltip and popover.}
+
+\item{escape}{T/F value showing whether special characters should be escaped.}
\item{background_as_tile}{T/F value indicating if you want to have round
cornered tile as background in HTML.}
diff --git a/man/spec_popover.Rd b/man/spec_popover.Rd
new file mode 100644
index 0000000..c9565d7
--- /dev/null
+++ b/man/spec_popover.Rd
@@ -0,0 +1,23 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/spec_tools.R
+\name{spec_popover}
+\alias{spec_popover}
+\title{Setup bootstrap popover}
+\usage{
+spec_popover(content = NULL, title = NULL, trigger = "hover",
+ position = "right")
+}
+\arguments{
+\item{content}{content for pop-over message}
+
+\item{title}{title for pop-over message.}
+
+\item{trigger}{Controls how the pop-over message should be triggered.
+Possible values include \code{hover} (default), \code{click}, \code{focus} and \code{manual}.}
+
+\item{position}{How the tooltip should be positioned. Possible values are
+\code{right}(default), \code{top}, \code{bottom}, \code{left} & \code{auto}.}
+}
+\description{
+Setup bootstrap popover
+}
diff --git a/man/spec_tooltip.Rd b/man/spec_tooltip.Rd
new file mode 100644
index 0000000..8f2543a
--- /dev/null
+++ b/man/spec_tooltip.Rd
@@ -0,0 +1,17 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/spec_tools.R
+\name{spec_tooltip}
+\alias{spec_tooltip}
+\title{Setup bootstrap tooltip}
+\usage{
+spec_tooltip(title, position = "right")
+}
+\arguments{
+\item{title}{text for hovering message}
+
+\item{position}{How the tooltip should be positioned. Possible values are
+\code{right}(default), \code{top}, \code{bottom}, \code{left} & \code{auto}.}
+}
+\description{
+Setup bootstrap tooltip
+}
diff --git a/tests/visual_tests/tooltip.Rmd b/tests/visual_tests/tooltip.Rmd
index 55f81b3..e54e095 100644
--- a/tests/visual_tests/tooltip.Rmd
+++ b/tests/visual_tests/tooltip.Rmd
@@ -2,34 +2,23 @@
title: "Untitled"
author: "Hao"
date: "10/15/2017"
-output: html_document
+output:
+ html_document:
+ theme: simplex
---
-```{r, include=FALSE}
-library(knitr)
+<script>
+$(document).ready(function(){
+ $('[tooltip-toggle="tooltip"]').tooltip();
+});
+</script>
+
+
+
+
+
+```{r}
library(kableExtra)
-library(tidyverse)
```
-```{r}
-htmlFun = function(content) {
- x = htmltools::tags$div(content, class = 'error')
- # you could also do this if you don't care about escaping HTML entities in 'content':
- # x = htmltools::HTML(paste('<div class="error">', content, '</div>'))
- d = htmltools::htmlDependency(
- 'knitr-css', '1.2.3', src = system.file('misc', package = 'knitr'),
- stylesheet = 'knitr.css'
- )
- x = htmltools::attachDependencies(x, d)
- x
-}
-
-htmlFun('Hello World!')
-```
-
-```{r}
-mtcars[1:5, 1:2] %>%
- mutate(mpg = cell_spec(mpg, tooltip = cyl)) %>%
- kable("html", escape = F) %>%
- htmltools::HTML()
-```
+`r cell_spec("hover over me", tooltip = spec_tooltip("Hello world", position = "right"))`