Skip to content

Commit e7f0b82

Browse files
authored
Merge pull request #1930 from xx02al/autocoloroptions
Autocoloroptions
2 parents 4c8debc + c574241 commit e7f0b82

File tree

6 files changed

+220
-16
lines changed

6 files changed

+220
-16
lines changed

DESCRIPTION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ Imports:
5353
vctrs,
5454
xml2 (>= 1.3.6)
5555
Suggests:
56+
farver,
5657
fontawesome (>= 0.5.2),
5758
ggplot2,
5859
grid,

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## Minor improvements and bug fixes
44

5+
* `data_color()` now allows to specify which light/dark color to use when `autocolor_text = TRUE` (@xx02al, #1930).
6+
57
* Fixed an issue with a warning in Quarto (@olivroy, #1985)
68

79
* `as_word()` now handles "<br>" line breaks for `md()` and `html()`, and no longer automatically adds "Table N" ahead of the caption.

R/data_color.R

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@
5757
#' text
5858
#' - text autocoloring: if colorizing the cell background, `data_color()` will
5959
#' automatically recolor the foreground text to provide the best contrast (can
60-
#' be deactivated with `autocolor_text = FALSE`)
60+
#' be deactivated with `autocolor_text = FALSE`; a light and dark color to be
61+
#' used can be specified with `autocolor_light` and `autocolor_dark`)
6162
#'
6263
#' `data_color()` won't fail with the default options used, but
6364
#' that won't typically provide you the type of colorization you really need.
@@ -233,6 +234,22 @@
233234
#' default this is `"apca"` (Accessible Perceptual Contrast Algorithm) and the
234235
#' alternative to this is `"wcag"` (Web Content Accessibility Guidelines).
235236
#'
237+
#' @param autocolor_light *Automatically recolor text, light color*
238+
#'
239+
#' `scalar<character>` // *default:* `"white"`
240+
#'
241+
#' The light color to use when `autocolor_text = TRUE`. By default the color
242+
#' `"white"` will be used (`#FFFFFF"`). Alpha channel values will be set to
243+
#' 1.0 (fully opaque).
244+
#'
245+
#' @param autocolor_dark *Automatically recolor text, dark color*
246+
#'
247+
#' `scalar<character>` // *default:* `"black"`
248+
#'
249+
#' The dark color to use when `autocolor_text = TRUE`. By default the color
250+
#' `"black"` will be used (`#000000"`). Alpha channel values will be set to
251+
#' 1.0 (fully opaque).
252+
#'
236253
#' @param colors *[Deprecated] Color mapping function*
237254
#'
238255
#' `function` // *default:* `NULL` (`optional`)
@@ -363,7 +380,9 @@
363380
#' setting `autocolor_text` to `FALSE`. The `contrast_algo` argument lets us
364381
#' choose between two color contrast algorithms: `"apca"` (*Accessible
365382
#' Perceptual Contrast Algorithm*, the default algo) and `"wcag"` (*Web Content
366-
#' Accessibility Guidelines*).
383+
#' Accessibility Guidelines*). `autocolor_light` and `autocolor_dark` allow for
384+
#' further customization, however, should only be used if you are sure that
385+
#' accessibility criteria are guaranteed.
367386
#'
368387
#' @section Examples:
369388
#'
@@ -673,6 +692,8 @@ data_color <- function(
673692
apply_to = c("fill", "text"),
674693
autocolor_text = TRUE,
675694
contrast_algo = c("apca", "wcag"),
695+
autocolor_light = "#FFFFFF",
696+
autocolor_dark = "#000000",
676697
colors = NULL
677698
) {
678699

@@ -695,6 +716,21 @@ data_color <- function(
695716
# Get the correct `contrast_algo` value
696717
contrast_algo <- rlang::arg_match0(contrast_algo, values = c("apca", "wcag"))
697718

719+
# When using non-default `autocolor_light` or `autocolor_dark`, check if
720+
# {farver} is installed and stop if not (we would error in `ideal_fgnd_color()`,
721+
# check here to get out early)
722+
if (rlang::is_true(autocolor_text) && !autocolor_light %in% c("white", "#FFFFFF", "#FFF")) {
723+
rlang::check_installed(
724+
"farver", reason = "to use non-default `autocolor_light`."
725+
)
726+
}
727+
728+
if (rlang::is_true(autocolor_text) && !autocolor_dark %in% c("black", "#000000", "#000")) {
729+
rlang::check_installed(
730+
"farver", reason = "to use non-default `autocolor_dark`."
731+
)
732+
}
733+
698734
# If no color is provided to `na_color`, use gray as a default
699735
na_color <- na_color %||% "#808080"
700736

@@ -1126,6 +1162,8 @@ data_color <- function(
11261162
color_vals <-
11271163
ideal_fgnd_color(
11281164
bgnd_color = color_vals,
1165+
light = autocolor_light,
1166+
dark = autocolor_dark,
11291167
algo = contrast_algo
11301168
)
11311169

@@ -1272,8 +1310,10 @@ expand_short_hex <- function(colors) {
12721310

12731311
#' For a background color, which foreground color provides better contrast?
12741312
#'
1275-
#' The input for this function is a single color value in 'rgba()' format. The
1276-
#' output is a single color value in #RRGGBB hexadecimal format
1313+
#' The `bgnd_color` input for this function is a single color value in 'rgba()'
1314+
#' format. The output is a single color value in #RRGGBB hexadecimal format.
1315+
#' `light` and `dark` accepts every color(specification) that can be handled by
1316+
#' {farver}.
12771317
#'
12781318
#' @noRd
12791319
ideal_fgnd_color <- function(
@@ -1286,6 +1326,9 @@ ideal_fgnd_color <- function(
12861326
# Get the correct `algo` value
12871327
algo <- rlang::arg_match0(algo, values = c("apca", "wcag"))
12881328

1329+
light_color <- farver::encode_colour(farver::decode_colour(light))
1330+
dark_color <- farver::encode_colour(farver::decode_colour(dark))
1331+
12891332
# Normalize color to hexadecimal color if it is in the 'rgba()' string format
12901333
bgnd_color <- rgba_to_hex(colors = bgnd_color)
12911334

@@ -1295,17 +1338,17 @@ ideal_fgnd_color <- function(
12951338
if (algo == "apca") {
12961339

12971340
# Determine the ideal color for the chosen background color with APCA
1298-
contrast_dark <- get_contrast_ratio(color_1 = dark, color_2 = bgnd_color, algo = "apca")[, 1]
1299-
contrast_light <- get_contrast_ratio(color_1 = light, color_2 = bgnd_color, algo = "apca")[, 1]
1341+
contrast_dark <- get_contrast_ratio(color_1 = dark_color, color_2 = bgnd_color, algo = "apca")[, 1]
1342+
contrast_light <- get_contrast_ratio(color_1 = light_color, color_2 = bgnd_color, algo = "apca")[, 1]
13001343

13011344
} else {
13021345

13031346
# Determine the ideal color for the chosen background color with WCAG
1304-
contrast_dark <- get_contrast_ratio(color_1 = dark, color_2 = bgnd_color, algo = "wcag")
1305-
contrast_light <- get_contrast_ratio(color_1 = light, color_2 = bgnd_color, algo = "wcag")
1347+
contrast_dark <- get_contrast_ratio(color_1 = dark_color, color_2 = bgnd_color, algo = "wcag")
1348+
contrast_light <- get_contrast_ratio(color_1 = light_color, color_2 = bgnd_color, algo = "wcag")
13061349
}
13071350

1308-
ifelse(abs(contrast_dark) >= abs(contrast_light), dark, light)
1351+
ifelse(abs(contrast_dark) >= abs(contrast_light), dark_color, light_color)
13091352
}
13101353

13111354
#' Convert colors in mixed formats (incl. rgba() strings) format to hexadecimal

R/utils_color_contrast.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ get_relative_luminance_wcag <- function(col) {
135135

136136
coef <- round(c(apca_coeffs$sRco, apca_coeffs$sGco, apca_coeffs$sBco), 4)
137137

138-
rgb[] <- ifelse(rgb <= 0.03928, rgb / 12.92, ((rgb + 0.055) / 1.055)^2.4)
138+
rgb[] <- ifelse(rgb <= 0.04045, rgb / 12.92, ((rgb + 0.055) / 1.055)^2.4)
139139

140140
as.numeric(rgb %*% coef)
141141
}

man/data_color.Rd

Lines changed: 23 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)