How to create a color gradient for html tags in R? - html

enter image description hereThe below code is meant to create 2 gradients for each column of my data. One from red to white for 100.8 to 0 and another from green to white for -100.8 to 0. The attached picture is what is generated. Much thanks!
structure(list(RFD.Diff = c(8.4, 56.6, -36.3, 26, -15.9, -8.1,
35.3, 66.8, 100.8, -20.2, 63.6, -9.7, -24.8, -4.6, 11.6, 21.3,
9.1, -0.9)), class = "data.frame", row.names = c(NA, -18L))
#Create tags and specify color gradient parameters
`add_cyl_color2 <- function(RFD.Diff){
# Define color values
red_val <- "#FF0000"
white_val <- "#FFFFFF"
green_val <- "#00FF00"
# Calculate color gradient based on RFD.Diff value
if (RFD.Diff >= 0) {
color_val <- paste0(
"background: linear-gradient(to right, ",
red_val, " ", round((100.8 - RFD.Diff) / 100.8 * 100), "%, ",
white_val, " ", round(RFD.Diff / 100.8 * 100), "%); color: #000000;"
)
} else {
color_val <- paste0(
"background: linear-gradient(to right, ",
white_val, " ", round((100.8 + RFD.Diff) / 100.8 * 100), "%, ",
green_val, " ", round(-RFD.Diff / 100.8 * 100), "%); color: #000000;"
)
}
# Create HTML div element with color-coded RFD.Diff value
div_out <- htmltools::div(
style = paste(
"display: inline-block; padding: 10px 30px; border-radius: 8px; font-weight: 1000; font- size: 15px;",
color_val
),
paste(RFD.Diff)
)
as.character(div_out) %>% gt::html()
}
, `
# {gt} table
data %>%
mutate(RFD.Diff = purrr::map(RFD.Diff, add_cyl_color2)) %>%
gt() %>%
cols_label(
RFD.Diff = md("Braking RFD"),
) %>%
tab_style(
cell_text(align = "center"),
locations = cells_body(
columns = everything(),
rows = everything()
)
)%>%
tab_style(
cell_borders(
sides = c("all"),
style = "hidden"
),
locations = cells_body(
columns = everything(),
rows = everything()
)
)%>%
opt_align_table_header(align = "left")%>%
cols_width(
RFD.Diff ~ px(100))

Related

How to use INLINE HTML to make text white on dark background automatically after setting background from palette

This question is somehow related but not depending to this Can you color an adjacent cell in gt table in r?:
I am explicitly looking for the modification of the <span style=\...</span> part of my code!
I have this example dataset with colors of the background of mpg column depending on the values applied with html.
library(dplyr)
library(purrr)
library(gt)
library(viridis)
head(mtcars[,1:2]) %>%
mutate(
color = scales::col_numeric(
palette = viridis(20, direction = 1, option ="D"), #color from viridis package
domain = NULL)(mpg),
mpg = glue::glue('<span style=\"display: inline-block; direction: ltr; border-radius: 5px; padding-right: 2px; background-color: {color}; width: 100%\"> {mpg} </span>'),
mpg = map(mpg, ~gt::html(as.character(.x)))
) %>%
select(-color) %>%
gt()
which gives:
I would like to have the text in mpg column in white color conditional to dark background coded in the inline html part of my code e.g. before transforming to an gt object.
While this works: This is not what I am looking for!
library(dplyr)
library(gt)
library(viridis)
head(mtcars[,1:2]) %>%
gt() %>%
data_color(
columns = c(mpg),
colors = scales::col_numeric(
palette = viridis(20, direction = 1, option ="D"), #color from viridis package
domain = NULL)
)
gives:
I have tried so far: adding color:white to inline html
head(mtcars[,1:2]) %>%
mutate(
color = scales::col_numeric(
palette = viridis(20, direction = 1, option ="D"), #color from viridis package
domain = NULL)(mpg),
mpg = glue::glue('<span style=\"display: inline-block; direction: ltr; color:white; border-radius: 5px; padding-right: 2px; background-color: {color}; width: 100%\"> {mpg} </span>'),
mpg = map(mpg, ~gt::html(as.character(.x)))
) %>%
select(-color) %>%
gt()
which gives:
One option would be prismatic::best_contrast. By default it will not use pure white so we have to set the colors:
prismatic::best_contrast("red", c("white", "black"))
#> [1] "black"
prismatic::best_contrast("purple", c("white", "black"))
#> [1] "white"
This could be added easily to your glue string to set font color based on the background color:
head(mtcars[, 1:2]) %>%
mutate(
color = scales::col_numeric(
palette = viridis(20, direction = 1, option = "D"), # color from viridis package
domain = NULL
)(mpg),
mpg = glue::glue(
'<span style=\"display: inline-block; direction: ltr; border-radius: 5px; padding-right: 2px;',
'color: {prismatic::best_contrast(color, c("white", "black"))}; background-color: {color}; width: 100%\"> {mpg} </span>'
),
mpg = map(mpg, ~ gt::html(as.character(.x)))
) %>%
select(-color) %>%
gt()

Stripe effect in formattable(), shadow in light gray every other row. R

I was wondering, does anyone know how to achieve the "stripe" style seen in kableExtra? That is to shadow in light gray odd rows but not even rows? Something like the following picture:
Given my code using formattable, I am going to export the table to a pdf document, so I would like to know If I can achieve that effect? is it possible? I tried modifying td's, tr's but the actual cells were very strangely shaded creating an undesired effect. This is the current code I got and its output:
library("htmltools")
library("webshot")
library(formattable)
DF <- data.frame(Ticker=c("", "", "", "IBM", "AAPL", "MSFT"),
Name=c("Dow Jones", "S&P 500", "Technology",
"IBM", "Apple", "Microsoft"),
Value=accounting(c(15988.08, 1880.33, 50,
130.00, 97.05, 50.99)),
Change=percent(c(-0.0239, -0.0216, 0.021,
-0.0219, -0.0248, -0.0399)))
################################## FUNCTIONS ##################################
unit.scale = function(x) (x - min(x)) / (max(x) - min(x))
export_formattable <- function(f, file, width = "100%", height = NULL,
background = "white", delay = 0.2)
{
w <- as.htmlwidget(f, width = width, height = height)
#Remove row height!
w <- htmlwidgets::prependContent(w, tags$style("td { padding: 0px !Important;}"))
path <- html_print(w, background = background, viewer = NULL)
url <- paste0("file:///", gsub("\\\\", "/", normalizePath(path)))
webshot(url,
file = file,
selector = ".formattable_widget",
delay = delay)
}
###############################################################################
FT <- formattable(DF, align =c("l","c","r","c"), list(
Name=formatter("span",
style = x ~ ifelse(x == "Technology", style(font.weight = "bold"), NA)), #NOT APPLIED when we output to PNG with the function!
#Value = color_tile("white", "orange"),
Value = color_bar("orange" , fun = unit.scale
),
Change = formatter("span",
style = x ~ style(color = ifelse(x < 0 , "red", "green"), "font.size" = "18px"),
x ~ icontext(ifelse(x < 0, "arrow-down", "arrow-up"), x)
)),
table.attr = 'style="font-size: 18px; font-family: Calibri";\"')
FT
#OUTPUT the table in the document as an image!
export_formattable(FT,"/outputpath/FT.png")
Thanks in advance!
You can use .table-striped inside the table.attr argument to add zebra-striping to any table row.
Code
FT <- formattable(DF, align =c("l","c","r","c"), list(
Name=formatter("span",
style = x ~ ifelse(x == "Technology", style(font.weight = "bold"), NA)), #NOT APPLIED when we output to PNG with the function!
#Value = color_tile("white", "orange"),
Value = color_bar("orange" , fun = unit.scale
),
Change = formatter("span",
style = x ~ style(color = ifelse(x < 0 , "red", "green"), "font.size" = "18px"),
x ~ icontext(ifelse(x < 0, "arrow-down", "arrow-up"), x)
)),
table.attr = 'class=\"table table-striped\" style="font-size: 18px; font-family: Calibri"')
Table

how to get background color in html variable for a shiny app in r?

I am creating a shiny app and trying to get top two fields (Name & location) of the html popup to have a orange background color.
library(shiny)
library(shinydashboard)
library(tidyverse)
library(leaflet)
# library(htmlwidgets)
# library(htmltools)
library(readxl)
library(RCurl)
URL <- "https://www.mohfw.gov.in/pdf/PMJAYPRIVATEHOSPITALSCONSOLIDATED.xlsx"
download.file(URL, destfile = "../../timesnow_PMJAYPRIVATEHOSPITALSCONSOLIDATED.xlsx",method = "curl")
# Data
ind_vaccination_leaflet <- readxl::read_xlsx(path = "../../timesnow_PMJAYPRIVATEHOSPITALSCONSOLIDATED.xlsx",
sheet = 1)
# Creating variable with html tags & background doesn't work
ind_vaccination_leaflet <- ind_vaccination_leaflet %>%
mutate(label_display = paste(
"<body style='background-color:orange;'>",
"<h2>", "Center: ", ind_vaccination_leaflet$`Name of the Vaccination Site*`, "</h2>",
"<h3>",ind_vaccination_leaflet$`District*`, ", ", ind_vaccination_leaflet$`State*`, "</h3>",
"</body>",
"<p>", "Address: ", ind_vaccination_leaflet$Address, ", ", ind_vaccination_leaflet$`PinCode*`, "</p>",
"<p>", "Mobile: ", ind_vaccination_leaflet$`Mobile Number`, "</p>",
"<p>", "Contact Person: ", ind_vaccination_leaflet$`Contact Person`, "</p>"
)
)
Issue: When I plot it using below code then I don't get the orange background in the first two rows of the popup:
m <- leaflet() %>%
setView(lat = 26.64510, lng = 80.17012, zoom = 5) %>%
addTiles(group = "OSM") %>%
addProviderTiles(providers$CartoDB.DarkMatter, group = "Dark") %>%
addProviderTiles(providers$CartoDB.Positron, group = "Light") %>%
addProviderTiles("Stamen.Terrain", group = "Terrain") %>%
addProviderTiles("Esri.WorldImagery", group = "WorldImagery") %>%
addLayersControl(baseGroups = c("OSM","WorldImagery","Dark","Light","Terrain"))
m %>%
addCircleMarkers(
lng = ind_vaccination_leaflet$lon,
lat = ind_vaccination_leaflet$lat,
label = lapply(ind_vaccination_leaflet$label_display, htmltools::HTML),
color = "midnightblue",
weight = 1,
radius = 8
)%>%
addMiniMap(tiles = providers$OpenStreetMap, width = 120, height=80)
I am not really a coder nor ui/html person so not sure where is it going wrong.
Try switching body to div.
You can experiment with HTML code much easier in an online editor, e.g. this one

Customize pagination box size and font

I'm trying to achieve the following goal. I have this code to display a dataTableOutput:
fluidRow(column(4,
dataTableOutput(outputId="table01", width = '80px')))
and this is the code that defines the visual settings:
output$table01 <- DT::renderDataTable({
list_var <- get_mp_data()
df <- list_var[[3]]
if(is.null(df)){
df <- data.frame()
}else{
upcolor = "lightblue"
downcolor = "lightblue"
col_name = "CHG"
df <- datatable(df
, rownames = FALSE
, caption = paste0("Pre/Post Duration")
, filter = 'none'
, options = list(scrollX = F,
autoWidth = T
,pageLength = 10 # this determines how many rows we want to see per page
, info = FALSE # this will hide the "Showing 1 of 2..." at the bottom of the table --> https://stackoverflow.com/questions/51730816/remove-showing-1-to-n-of-n-entries-shiny-dt
,searching = FALSE # this removes the search box -> https://stackoverflow.com/questions/35624413/remove-search-option-but-leave-search-columns-option
,columnDefs = list(list(width = '4', targets = c(3) )
,list(width = '4', targets = c(2) )
) # careful, column counting STARTS FROM 0 !!!!
)) %>%
formatStyle(col_name,
#background = styleColorBar(range(df[, c(col_name)]), 'lightblue'),
background = color_from_middle(df[, c(col_name)] , downcolor, upcolor),
backgroundSize = '98% 88%',
backgroundRepeat = 'no-repeat',
backgroundPosition = 'center')
}
return(df)
})
This table is almost perfect, but as you can see from my screenshot, the pagination box(es) on the lower hand side of the table are taking a ton of space for no reason.
Is there a way to have the "1" box much smaller? and is there a way to hide the "Previous" "Next" words?
Many thanks
You can use this CSS to reduce the size of the buttons:
CSS <- "
.dataTables_wrapper .dataTables_paginate .paginate_button {
min-width: 0.5em !important;
padding: 0.1em .5em !important;
}
"
ui <- fluidPage(
tags$head(tags$style(HTML(CSS))),
...
To remove the words "previous", "next", "first", "last", you can do:
datatable(mydataframe, options =
list(
language = list(
paginate = list(first="", last="", previous="", `next`="")
)
)
)

Formatting Html Tables in R - Using Css

I am using the package "htmlTable" in R and trying to format a table. Specifically, I want to delete the uppermost border and change the remaining borders to black. Please run the code below to get the table that I am looking at.
Any help would be appreciated!
devtools::install_github('SwedishPensionsAgency/format.tables')
library(htmlTable)
Code <- ("AB", "BC", "MB", "NB")
Numbers <- c(148137, 186955, 37755, 17376)
DataFrame <- data.frame(Code, Numbers, stringsAsFactors = FALSE)
htmlTable(DataFrame, align = "c",
rnames = FALSE,
caption = "<b> <center> <font face = Times New Roman> Table 1. Test <br> <br>",
tfoot = "<b> Source </b> <br> [1] Test Source",
header = paste(c(" Territory", "Number of People")),
css.caption = "color:red;",
col.rgroup = c("none", "#ADADAD"),
padding.tspanner = "", ctable = TRUE,
css.table = "width:150%;border: none")
If you know basic CSS, you can easily format any element in the table quite easily:
x <- htmlTable(DataFrame, align = "c",
rnames = FALSE,
caption = "<b> <center> <font face = Times New Roman> Table 1. Test <br> <br>",
tfoot = "<b> Source </b> <br> [1] Test Source",
header = paste(c(" Territory", "Number of People")),
css.caption = "color:red;",
col.rgroup = c("none", "#ADADAD"),
padding.tspanner = "", ctable = TRUE)
## add id to gmisc_table
x <- gsub('(?<=.gmisc_table.)', ' id = \'gmisc_table\'', x, perl = TRUE)
formats <- paste(x)
attributes(formats) <- attributes(x)
## Edit css
css <- '
<style>
/* Remove the top border */
#gmisc_table > thead > tr > th {
border-top: none !important;
}
/* Add boarder to the table body */
#gmisc_table > tbody > tr > td {
border: 2px solid black;
}
</style>'
gsub('^', css, formats)
In my opinion, the methods you are using to generate the <html> is limiting your options for formatting. Below is my suggestion to how you should do this if you want absolute control of the styling. It also allows you to use resources like w3schools to fix perfect formatting:
Your data:
Code <- c("AB", "BC", "MB", "NB")
Numbers <- c(148137, 186955, 37755, 17376)
DataFrame <- data.frame(Code, Numbers, stringsAsFactors = FALSE)
names(DataFrame) <- c("Territory", "Number of People")
I use this library to produce <html> tables. Not as few lines of code
as yours but no lack of flexibility. Here I install using the
remotes package:
remotes::install_github('trosendal/hlt')
library(hlt)
Basic table structure and add style:
my_table <- hlt::html_table(DataFrame)
hlt::tag_attr(my_table) <- list(id = "table1", class = "gmisc_table")
A blurb before and after your table:
a <- html_p("Table 1. Test")
b <- html_p("<b>Source</b><br>[1] Test Source")
Put the table in a <div> as you had:
my_table <- hlt::html_div(a +
my_table +
b)
hlt::tag_attr(my_table) <- list(style = "margin: 0 auto; display: table; margin-top: 1em;")
Add the style (same as yours, plus your suggested changes)
head <- hlt::html_head(hlt::html_meta(charset="utf-8") +
hlt::html_meta("http-equiv" = "Content-type") +
hlt::html_meta("content" = "text/html") +
hlt::html_style(c(".gmisc_table {",
" width:150%;",
" border:1px solid black;",
" border-collapse:collapse",
"}",
".gmisc_table th {",
" border-bottom: 2px solid grey;",
" border-left: 1px solid black;",
" text-align: center;",
"}",
".gmisc_table tr:nth-child(even) {",
" background-color: #adadad;",
"}",
".gmisc_table tr:nth-child(odd) {",
" background-color: transparent;",
"}",
".gmisc_table td {",
" background-color: transparent;",
" text-align: center;",
" border-left: 1px solid black",
"}")))
Stitch the pieces together into a page:
page <- hlt::html_html(head +
hlt::html_body(my_table))
tab <- tempfile()
capture.output(file = tab, print(page))
browseURL(tab)
It's not clear exactly how you wanted the final formatting of
the table to be; I removed the top line and added all black solid
borders otherwise. But from this, I hope it illustrates how this
method provides all the flexibility you could ever need. I started
with the htmlTable package too for making tables on sva.se
and quickly found that the needs are always more complex than the
features in R packages that write html.