jthomasmock / gtExtras

A Collection of Helper Functions for the gt Package.
https://jthomasmock.github.io/gtExtras/
Other
193 stars 26 forks source link

Can `gt_merge_stack()` use `gt::cols_merge()` internally to support auto font coloring? #71

Closed mrcaseb closed 1 year ago

mrcaseb commented 1 year ago

The current implementation of gt_merge_stack() fixes font colors which can be hard to read if color scales are used in cells. gt::cols_merge() with an appropriate merge pattern can solve this. Maybe gt_merge_stack() can use it with a clever merge pattern?

No auto font colors in gt_merge_stack()

library(gt)

tbl_data <- tibble::tibble(
  value = 1:5,
  color_by = seq.int(10, 98, length.out = 5)
)

pal <- c(
  ggsci::rgb_material("deep-purple", reverse = TRUE),
  "white",
  ggsci::rgb_material("green", reverse = FALSE)
)

gt::gt(tbl_data) |> 
  gt::data_color(
    value, function(x){
      scales::col_numeric(
        palette = pal,
        domain = 0:100, 
        na.color = "white"
      )(tbl_data$color_by)
    }
  ) |> 
  gtExtras::gt_merge_stack(value, color_by)

grafik

Automatic color adjustments in gt::cols_merge()

library(gt)

tbl_data <- tibble::tibble(
  value = 1:5,
  color_by = seq.int(10, 98, length.out = 5)
)

pal <- c(
  ggsci::rgb_material("deep-purple", reverse = TRUE),
  "white",
  ggsci::rgb_material("green", reverse = FALSE)
)

merge_pattern <- "{1}<br>{2}"

gt::gt(tbl_data) |> 
  gt::data_color(
    value, function(x){
      scales::col_numeric(
        palette = pal,
        domain = 0:100, 
        na.color = "white"
      )(tbl_data$color_by)
    }
  ) |> 
  gt::cols_merge(
    columns = c(value, color_by),
    pattern = merge_pattern
  )

grafik

Merge Pattern

I think the merge pattern could be more sophisticated and use html elements which would allow for more options to adjust the merge behavior. We could for example change line height for a line break, apply bold font to first column and reduce font size in second column with the following code

library(gt)

tbl_data <- tibble::tibble(
  value = 1:5,
  color_by = seq.int(10, 98, length.out = 5)
)

pal <- c(
  ggsci::rgb_material("deep-purple", reverse = TRUE),
  "white",
  ggsci::rgb_material("green", reverse = FALSE)
)

merge_pattern <- '<div style="line-height:1.5em; font-weight:bold">{1}<br></div><div style="font-size:0.5em">{2}</div>'

gt::gt(tbl_data) |> 
  gt::data_color(
    value, function(x){
      scales::col_numeric(
        palette = pal,
        domain = 0:100, 
        na.color = "white"
      )(tbl_data$color_by)
    }
  ) |> 
  gt::cols_merge(
    columns = c(value, color_by),
    pattern = merge_pattern
  )

grafik

jthomasmock commented 1 year ago

@mrcaseb I've added a gt_merge_stack_color() function - the goal here is to avoid people trying to mix merge and stack with coloring rows - they're incompatible right now, as opposed to the dedicated function based off your suggestion.

set.seed(12345)
 dplyr::tibble(
   value = sample(state.name, 5),
   color_by = seq.int(10, 98, length.out = 5)
 ) %>%
   gt::gt() %>%
   gt_merge_stack_color(value, color_by)

image

mrcaseb commented 1 year ago

Sounds good to me, thank you for implementing!

jthomasmock commented 1 year ago

Thanks for suggestion and some reprex code!