Skip to contents

data_bars() customization options

Parameter Description Default Value
data name of data set NULL
text_position position of the values relative to bars ‘inside-end’
number_fmt the format of the values NULL
fill_color color of the filled portion of the bars ‘#15607A’
fill_color_ref column containing color assignments NULL
fill_by column containing value assignments NULL
fill_opacity opaqueness of the fill color 1
bias the spacing between colors 1
min_value the minimum value for the width of the bars NULL (0)
max_value the maximum value for the width of the bars NULL (max value of the column)
align_bars the alignment of the bars within the column ‘left’
bar_height the height of the bars NULL
force_outside convert a range of values to ‘outside-end’ NULL
text_size the size of the text NULL
text_color the color of the text ‘black’
text_color_ref column containing text color assignments NULL
brighten_text auto-adjust text color based on fill color TRUE
brighten_text_color color of the auto-adjusted text color ‘white’
bold_text bold format text FALSE
border_style the style of the border around the bars NULL
border_width the width of the border around the bars NULL
border_color the color of the border around the bars NULL
icon add an icon to the bars NULL
icon_ref column containing icon assignments NULL
icon_size the size of the icons NULL
icon_color the color of the icons NULL
icon_color_ref column containing icon color assignments NULL
img add an image to the bars NULL
img_ref column containing image assignments NULL
img_height the height of the images NULL
img_width the width of the images NULL
box_shadow add a box shadow around the bars NULL
round_edges round the edges around the bars FALSE
tooltip enable hover tooltip FALSE
animation animation of color transitions on sort ‘width 1s ease’

Position text

By default, the values are positioned on the “inside-end” of the filled bars:

data <- data.frame(
  Group = c("Red Group 1","Red Group 2","Red Group 3","Red Group 4","Red Group 5",
            "Blue Group 1","Blue Group 2","Blue Group 3","Blue Group 4","Blue Group 5",
            "Green Group 1","Green Group 2","Green Group 3","Green Group 4","Green Group 5"),
  Pct1 = c(.27, .82, .44, .68, .78, 
           .74, .66, .33, .23, .20, 
           .50, .55, .40, .70, .60),
  Pct2 = c(.33, .17, .87, .54, .37,
           .84, .72, .61, .48, .77,
           .21, .39, .60, .55, .81)
)
reactable(
  data,
  pagination = FALSE,
  defaultColDef = colDef(
    cell = data_bars(data, 
                     number_fmt = scales::percent)
  )
)

However, you can change the location of the values with text_position. The available options are “inside-end” (default), “outside-base”, “outside-end”, “inside-base”, “center”, “above”, or “none”. Below is an example of “outside-base” which is the way the old version of data_bars() displayed the values.

reactable(
  data,
  pagination = FALSE,
  defaultColDef = colDef(
    cell = data_bars(data, 
                     text_position = "outside-base", 
                     number_fmt = scales::percent)
  )
)

Values positioned inside the base of the filled bars with “inside-base”:

reactable(
  data,
  pagination = FALSE,
  defaultColDef = colDef(
    cell = data_bars(data, 
                     text_position = "inside-base", 
                     number_fmt = scales::percent)
  )
)

Values positioned inside the end of the filled bars with “outside-end”:

reactable(
  data,
  pagination = FALSE,
  defaultColDef = colDef(
    cell = data_bars(data,
                     text_position = "inside-end",
                     number_fmt = scales::percent)
  )
)

Values positioned inside the center of the filled bars with “center”:

reactable(
  data,
  pagination = FALSE,
  defaultColDef = colDef(
    cell = data_bars(data,
                     text_position = "center", 
                     number_fmt = scales::percent)
  )
)

Values positioned above the filled bars with “above”:

reactable(
  data,
  pagination = FALSE,
  defaultColDef = colDef(
    cell = data_bars(data,
                     text_position = "above", 
                     number_fmt = scales::percent)
  )
)

Lastly, values can be hidden with “none”:

reactable(
  data,
  pagination = FALSE,
  defaultColDef = colDef(
    cell = data_bars(data, 
                     text_position = "none")
  )
)

Force text outside

If the values are difficult to see inside the bars since they are small relative to other values in the column, you can “force” them to show outside of the data bars by providing a range of values within force_outside:

reactable(
  data,
  pagination = FALSE,
  defaultSortOrder = "desc",
  defaultSorted = "Pct2",
  defaultColDef = colDef(
    cell = data_bars(data, 
                     number_fmt = scales::percent,
                     force_outside = c(0,0.4))
  )
)

Aligning data bars

By default, the filled bars are aligned from left-to-right, but can be aligned from right-to-left by setting align_bars = "right":

reactable(
  data,
  pagination = FALSE,
  defaultColDef = colDef(
    cell = data_bars(data, 
                     align_bars = "right", 
                     number_fmt = scales::percent)
  )
)

The same text positions outlined in the section above can be applied to right-aligned data bars. You can also mix and match alignments.

reactable(
  data,
  pagination = FALSE,
  columns = list(
    Pct1 = colDef(
      cell = data_bars(data, 
                       align_bars = "right", 
                       text_position = "inside-end", 
                       number_fmt = scales::percent)
      ),
    Pct2 = colDef(
      cell = data_bars(data, 
                       align_bars = "left",
                       text_position = "inside-end",
                       number_fmt = scales::percent)
      )
  )
)

Add a box shadow

Box shadows can be added to the bars to create a “3-D” effect via box_shadow.

reactable(
  data,
  pagination = FALSE,
  defaultColDef = colDef(
    cell = data_bars(data, 
                     box_shadow = TRUE, 
                     number_fmt = scales::percent)
  )
)

Round edges

The edges of the bars can be rounded by setting round_edges to TRUE.

reactable(
  data,
  pagination = FALSE,
  defaultColDef = colDef(
    cell = data_bars(data, 
                     round_edges = TRUE, 
                     number_fmt = scales::percent)
  )
)

Add borders

Borders can be placed around the bars by setting the border properties within border_style, border_color, and border_width:

reactable(
  data,
  pagination = FALSE,
  defaultColDef = colDef(
    cell = data_bars(data, 
                     border_style = "solid",
                     border_color = "gold", 
                     border_width = "2px",
                     number_fmt = scales::percent)
  )
)

Set a maximum width

By default, the width of the filled data bars is equal to the maximum value within that particular column. In most cases, this is what we want to display, but sometimes it’s better to extend the range. For example, in the percentages below, if we want to extend the width to show the values out of 100%, we could do so by setting the max_value to 1:

reactable(
  data,
  pagination = FALSE,
  defaultColDef = colDef(
    cell = data_bars(data, 
                     fill_color = viridis(5), 
                     background = "lightgrey",
                     text_position = "inside-end", 
                     max_value = 1, 
                     number_fmt = scales::percent)
  )
)

Now when you look at the 82% value above, there is 18% empty space filled by the background showing that the value is out of 100% and not 82%.

Adjust the height of the bars

The default height of the data bars is set to 19px but can be adjusted within bar_height.

To increase the height of the bars, provide a numeric value greater than 19:

reactable(
  data,
  pagination = FALSE,
  defaultColDef = colDef(
    cell = data_bars(data, 
                     bar_height = 35, 
                     number_fmt = scales::percent)
  )
)

To decrease the height of the bars, provide a numeric value less than 19:

reactable(
  data,
  pagination = FALSE,
  defaultColDef = colDef(
    cell = data_bars(data,
                     bar_height = 3, 
                     text_position = "outside-end", 
                     background = "transparent", 
                     number_fmt = scales::percent)
  )
)

Reference colors from another column

You can now conditionally assign colors to rows based on values within another column with the fill_color_ref argument. This allows you to assign colors to groups such as shown below:

data %>%
  mutate(color_pal = case_when(
    str_detect(Group, "Red") ~ "#FF3B28",
    str_detect(Group, "Blue") ~ "#006FEF",
    str_detect(Group, "Green") ~ "#3ABC0E",
    TRUE ~ "darkgrey"
  )) %>%
reactable(.,
  pagination = FALSE,
  defaultColDef = colDef(
    cell = data_bars(.,
                     fill_color_ref = "color_pal", 
                     text_position = "inside-end",
                     background = "lightgrey", 
                     max_value = 1, 
                     number_fmt = scales::percent)
  ),
  columns = list(color_pal = colDef(show = FALSE) ## hide the color_pal column
  )
) 

Or you can conditionally assign colors based on values:

data %>%
  mutate(color_pal = case_when(
    Pct1 >= .7 ~ "#FF3B28",
    TRUE ~ "darkgrey"
  )) %>%
  select(-Pct2) %>% 
reactable(.,
  pagination = FALSE,
  defaultSorted = "Pct1",
  defaultSortOrder = "desc",
  defaultColDef = colDef(
    cell = data_bars(., 
                     fill_color_ref = "color_pal", 
                     text_position = "inside-end", 
                     background = "lightgrey", 
                     max_value = 1, 
                     number_fmt = scales::percent)
  ),
  columns = list(color_pal = colDef(show = FALSE)
  )
) 

Gradient colors

data_bars_gradient() is now depreciated and has been replaced with the gradient argument within data_bars(). Set fill_gradient = TRUE to change any multi-color palette to a left-to-right gradient to be used as the fill for the bars:

reactable(
  data,
  pagination = FALSE,
  defaultColDef = colDef(
    cell = data_bars(data, 
                     fill_color = c("#1efffd", "#1e20ff"), 
                     fill_gradient = TRUE, 
                     background = "lightgrey", 
                     max_value = 1, 
                     brighten_text = FALSE,
                     text_color = "white",
                     number_fmt = scales::percent)
  )
)

Fill assignments by another column

With fill_by, you can apply data bars to a non-numeric column by referencing values contained within another column.

Note: this only works with columns of character-type, not for factors.

car_data <- MASS::Cars93 %>% 
  filter(Type %in% c('Compact', 'Sporty', 'Van')) %>% 
  select(c('Make', 'Type', 'MPG.city')) %>% 
  mutate(Make = as.character(Make)) %>% 
  tail(10)

reactable(
  car_data,
  columns = list(
    Make = colDef(
      cell = data_bars(car_data, fill_by = "MPG.city")
    )
  )
)

You are still able to control the position of the text relative to the bars with text_position:

car_data <- MASS::Cars93 %>% 
  filter(Type %in% c('Compact', 'Sporty', 'Van')) %>% 
  select(c('Make', 'Type', 'MPG.city')) %>% 
  mutate(Make = as.character(Make)) %>% 
  tail(10)

reactable(
  car_data,
  defaultSorted = "MPG.city",
  defaultSortOrder = "desc",
  columns = list(
    Make = colDef(
      cell = data_bars(car_data, fill_by = "MPG.city", text_position = "above")
    )
  )
)

Add a legend

add_legend() customization options

Parameter Description Default Value
data name of dataset NULL
col_name name of column containing numeric values NULL
bins number of bins to be displayed 5
colors color palette c(‘#15607A’,‘#FFFFFF’,‘#FA8C00’)
bias opaqueness of color palette 1
labels show or hide value labels TRUE
number_fmt the format of the values NULL
title the title above the legend NULL
footer the footer below the legend NULL
align align to the left or right of the table ‘right’

If you would like to add a legend below the table, you can do so by including add_legend(). The two things you will need within add_legend(), are the name of the column from which the legend is to be displayed for, and the color palette used within the table.

Since we used a custom color palette for the fill_color of data_bars in the example below, we will need to match that color palette within colors of the legend.

Adding a legend is useful when using the fill_by option in data_bars since the values aren’t directly displayed on the bars as they would be if they were used in a numeric column.

reactable(
  car_data,
  defaultSorted = "MPG.city",
  defaultSortOrder = "desc",
  columns = list(
    Make = colDef(
      cell = data_bars(car_data, fill_by = "MPG.city", text_position = "above", fill_color = c("#22577A","#38A3A5","#57CC99","#80ED99","#C7F9CC"))
    )
  )
) %>% 
add_legend(car_data, col_name = 'MPG.city', title = 'MPG City', align = 'left', colors = c("#22577A","#38A3A5","#57CC99","#80ED99","#C7F9CC"))
MPG City
  • 17
  • 18
  • 20
  • 22
  • 25


Positive and negative values

data_bars_pos_neg() is also now depreciated and has been replaced with the default setting of data_bars() which automatically detects if there are negative values within a column and adjusts the bars to go in opposite directions rather than one.

If two colors are provided, the first color will be applied to the negative-filled bars and the second color will be applied to the positive-filled bars

data %>% 
  mutate(Change = Pct1 - Pct2) %>% 
  select(Group, Change) %>% 
reactable(.,
  pagination = FALSE,
  columns = list(
    Change = colDef(
      cell = data_bars(., 
                       fill_color = c("lightblue","orange"),
                       number_fmt = scales::percent))
  )
)

The labels can be positioned in the same fashion that is used for the positive-valued data bars in the examples above:

data %>% 
  mutate(Change = Pct1 - Pct2) %>% 
  select(Group, Change) %>% 
reactable(.,
  pagination = FALSE,
  defaultSorted = "Change",
  defaultSortOrder = "asc",
  columns = list(
    Change = colDef(
      cell = data_bars(., 
                       fill_color = c("lightblue","orange"),
                       text_position = "inside-end", 
                       number_fmt = scales::percent))
  )
)

Add icons

Now within the data_bars() formatter, you can directly add icons to your tables!

First let’s start with a dataset that shows fake data from some of the leading social media websites. We will later use the names of the sites within the Logo column to apply the icons from the Font Awesome icon library. Please note that the names of the sites are all lower-case to match the icon names within Font Awesome.

data <- data.frame(
  Company = c("facebook", "twitter", "linkedin", "reddit", "youtube", "instagram", "pinterest", "snapchat"),
  Primary = c("#4267B2", "#1DA1F2", "#0E76A8", "#FF4500", "#FF0000", "#833AB4", "#E60023", "#FFFC00"),
  Values = c(75, 120, 90, 100, 80, 70, 60, 40)
)
reactable(
  data,
  defaultSorted = "Values",
  defaultSortOrder = "desc",
  columns = list(
    Values = colDef(
      cell = data_bars(data, 
                       fill_color = "black",
                       fill_opacity = 0.8, 
                       text_position = "inside-end"))
  )
)

To add the logos of each company to the end of the data bars, use icon_ref to reference the column (Company) containing the names of the companies:

reactable(
  data,
  defaultSorted = "Values",
  defaultSortOrder = "desc",
  columns = list(
    Values = colDef(
      cell = data_bars(data, 
                       icon_ref = "Company", 
                       fill_color = "black", 
                       fill_opacity = 0.8, 
                       text_position = "inside-end"))
  )
)

By default, the color of the icon is inherited from the color of the filled data bar, but they can be changed either through icon_color or with icon_color_ref which we will be using below in order to apply each company’s primary color to icons:

reactable(
  data,
  defaultSorted = "Values",
  defaultSortOrder = "desc",
  columns = list(
    Values = colDef(
      cell = data_bars(data,
                       icon_ref = "Company", 
                       icon_color_ref = "Primary",
                       fill_color = "black", 
                       fill_opacity = 0.8, 
                       text_position = "inside-end"))
  )
)

An alternative would be to use fill_color_ref instead, which applies each company’s primary color to the fill of the data bars and then the icons inherit that color as well:

reactable(
  data,
  defaultSorted = "Values",
  defaultSortOrder = "desc",
  columns = list(
    Values = colDef(
      cell = data_bars(data, 
                       icon_ref = "Company",
                       fill_color_ref = "Primary",
                       text_position = "inside-end"))
  )
)

The size of the icons can also be adjusted with icon_size:

reactable(
  data,
  defaultSorted = "Values",
  defaultSortOrder = "desc",
  columns = list(
    Values = colDef(
      cell = data_bars(data, 
                       icon_ref = "Company", 
                       icon_size = 35, 
                       fill_color_ref = "Primary",
                       text_position = "inside-end", 
                       background = "transparent")
    ),
    Company = colDef(show = FALSE), 
    Primary = colDef(show = FALSE)
  )
) 

Add images

Similarly, you can now assign images to your data bars!

First let’s load the dataset from nflfastR that was used in the Embed Images example (this dataset is limited to just the 2018-2019 seasons):

## load multiple seasons
seasons <- 2018:2019
pbp <- map_df(seasons, function(x) {
  readRDS(url(
    paste0(
      "https://raw.githubusercontent.com/guga31bb/nflfastR-data/master/data/play_by_play_",
      x,
      ".rds"
    )
  ))
})
## figures with QB stats
qbs <- pbp %>%
  filter(week <= 17,!is.na(epa)) %>%
  group_by(id, name) %>%
  summarize(
    epa = mean(qb_epa),
    cpoe = mean(cpoe, na.rm = T),
    n_dropbacks = sum(pass),
    n_plays = n(),
    team = last(posteam)
  ) %>%
  ungroup() %>%
  filter(n_dropbacks > 100 & n_plays > 1000)
## `summarise()` has grouped output by 'id'. You can override using the `.groups` argument.
## join team logos to dataset
qbs <- qbs %>%
  left_join(teams_colors_logos, by = c('team' = 'team_abbr')) %>% 
  select(name, team_logo_espn, team_color, cpoe, epa)

The URL’s for the team logos contained within the team_logo_espn column can be referenced using img_ref to overlay on top of the data bars. The images can also be re-sized using img_height and img_width. The default image size is 20px by 20px.

reactable(
  qbs,
  defaultPageSize = 20,
  columns = list(
    team_logo_espn = colDef(show = FALSE), ## hide column containing team logos
    team_color = colDef(show = FALSE), ## hide column containing team colors
    name = colDef(maxWidth = 120),
    cpoe = colDef(
      cell = data_bars(qbs, 
                       fill_color_ref = "team_color",
                       fill_opacity = 0.3,
                       brighten_text = FALSE, 
                       text_position = "inside-end",
                       number_fmt = scales::percent, 
                       img_ref = "team_logo_espn", 
                       img_height = 30, 
                       img_width = 30)
    ),
    epa = colDef(
      cell = data_bars(qbs, 
                       fill_color_ref = "team_color",
                       fill_opacity = 0.3, 
                       brighten_text = FALSE,
                       text_position = "inside-end",
                       number_fmt = scales::number_format(accuracy = 0.01),
                       img_ref = "team_logo_espn",
                       img_height = 30, 
                       img_width = 30)
    )
  )
)