kcuilla / reactablefmtr

Streamlined Table Styling and Formatting for Reactable
https://kcuilla.github.io/reactablefmtr/
Other
208 stars 27 forks source link

color_scales / color_tiles assign colors based on another column #22

Open shannonpileggi opened 2 years ago

shannonpileggi commented 2 years ago

Hi Kyle! 👋 Thank you for this awesome package, I'm having so much making tables with the incredible {reactable} + {reactablefmtr} combo!

I am interested in assigning colors to a column by the value of another column. It looks like the color_ref option has the colors hard coded, but I am interested in a sort of color_by argument that allows for color_scales to work its magic✨ without hard coding.

Here is an example:

library(reactable)
library(reactablefmtr)
library(tidyverse)
#> Warning: package 'tibble' was built under R version 4.1.2
#> Warning: package 'tidyr' was built under R version 4.1.2
library(glue)
#> 
#> Attaching package: 'glue'
#> The following object is masked from 'package:dplyr':
#> 
#>     collapse

iris_mod <- iris %>% 
  group_by(Species) %>% 
  summarize(
    n_total = n(),
    n_length_gt_5 = sum(Sepal.Length > 5),
    pct_length_gt_5 = n_length_gt_5 / n_total,
    length_label = glue("{n_length_gt_5} ({scales::percent(pct_length_gt_5, 0.1)})")
  ) %>% 
  ungroup() 

reactable(
  iris_mod,
  columns = list(
    pct_length_gt_5 = colDef(style = color_scales(iris_mod))
  )
)

Created on 2022-01-28 by the reprex package (v2.0.1)

My goal would be to have length_label colored by the value of pct_length_gt_5, and then to hide n_length_gt_5 and pct_length_gt_5.

Please let me know if this is already a possibility and I missed it! Or otherwise, what you think about this feature.

Many thanks!

kcuilla commented 2 years ago

Hi Shannon! Thank you for the suggestion, I think this is a great idea!

I just added the color_by parameter to both color_scales and color_tiles. You'll just need to call the name of the column you want to assign the colors from in quotes as shown below:

library(reactable)
library(reactablefmtr)
library(tidyverse)
#> Warning: package 'tibble' was built under R version 4.1.2
#> Warning: package 'tidyr' was built under R version 4.1.2
library(glue)
#> 
#> Attaching package: 'glue'
#> The following object is masked from 'package:dplyr':
#> 
#>     collapse

iris_mod <- iris %>% 
  group_by(Species) %>% 
  summarize(
    n_total = n(),
    n_length_gt_5 = sum(Sepal.Length > 5),
    pct_length_gt_5 = n_length_gt_5 / n_total,
    length_label = glue("{n_length_gt_5} ({scales::percent(pct_length_gt_5, 0.1)})")
  ) %>% 
  ungroup() 

reactable(
  iris_mod,
  columns = list(
    length_label = colDef(style = color_scales(iris_mod, color_by = "pct_length_gt_5"))
  )
)

reactable(
  iris_mod,
  columns = list(
    length_label = colDef(cell = color_tiles(iris_mod, color_by = "pct_length_gt_5"))
  )
)

image image

kcuilla commented 2 years ago

Forgot to mention that this will still work with the referenced column hidden which you can do with pct_length_gt_5 = colDef(show = FALSE)

shannonpileggi commented 2 years ago

Wow, you are fast! I installed the dev version and works like a charm. Thank you for the addition of this wonderful feature!

shannonpileggi commented 2 years ago

I actually had another thought about this feature that I hadn't considered initially - what would you expect the sorting behavior to be for these columns now? Would it be based on the values shown or based on the values of the color_by column?

kcuilla commented 2 years ago

That's a good question. I think I would like it to be sorted by the column referenced in color_by, or at least have the option to sort it by that column. However, I don't believe there's a way to do custom sorting like that in {reactable} at the moment unfortunately.

shannonpileggi commented 2 years ago

I agree. But understood regarding current limitations!