I'm trying to use a bar chart inside a reactable
, but I'm having a hard time getting the chart into the totalizers. Here's an example:
library(reactable)
library(htmltools)
bar_chart <- function(label, width = "100%", height = "16px", fill = "#00bfc4", background = NULL) {
# https://glin.github.io/reactable/articles/cookbook/cookbook.html
bar <- div(style = list(background = fill, width = width, height = height))
chart <- div(style = list(flexGrow = 1, marginLeft = "8px", background = background), bar)
div(style = list(display = "flex", alignItems = "center"), label, chart)
}
formata_coluna <- colDef(aggregate = "sum",
footer = function(values) format(sum(values), big.mark = '.', decimal.mark = ','),
format = colFormat(separators = TRUE, digits = 0, locales = 'pt-BR'))
totais_perc <- JS("function(column, state) {
let total_total = 0
let total_ocupadas = 0
state.data.forEach(function(row) {
total_total += row[\'Total\']
total_ocupadas += row[\'Sold\']
})
return (total_ocupadas / total_total * 100).toFixed(2)
}")
grupos_perc <- JS("function(values, rows) {
let total_total = 0
let total_ocupadas = 0
rows.forEach(function(row) {
total_total += row[\'Total\']
total_ocupadas += row[\'Sold\']
})
return (total_ocupadas / total_total * 100).toFixed(2)
}")
expand.grid(Seller = LETTERS[1:3], Product = letters[1:3]) %>%
mutate(Sold = rpois(9, 50),
Total = Sold + rpois(9, 10),
Perc = Sold/Total) %>%
bind_rows(data.frame(Seller = 'D',
Product = 'd',
Sold = 0,
Total = 10,
Perc = 0)) %>%
reactable(groupBy = "Seller",
columns = list(
Seller = colDef(footer = "Total"),
Sold = formata_coluna,
Total = formata_coluna,
Perc = colDef(cell = function(value) {
width <- paste0(value * 100, "%")
bar_chart(sprintf('%.0f%%', round(value * 100, 0)), width = width, fill = "#fc5185", background = "#e1e1e1")
},footer = totais_perc,
aggregate = grupos_perc,
html = TRUE)),
pagination = F)
The code above correctly adds the chart to the original table rows, and the correct percentages in the subtotals and total. I tried to change the totais_totals
and grupos_perc
functions to return something similar to the bar_chart function (<div>
tags with the same parameters), but it doesn't render anything inside the cells. I believe the error is here, but as I don't understand much about HTML, I couldn't identify where:
<div style="display:flex alignItems:center">90%<div style="flexGrow:1 marginLeft:8px background:#e1e1e1"> <div style="background:#fc5185 width:90% height:16px"></div></div></div>
On this site I found another example of a graph using <div>
and adapted the grupos_perc
function, but it's giving a problem when the value is 0 (it's showing a partially filled bar).
grupos_perc <- JS('function(values, rows) {
let total_total = 0
let total_ocupadas = 0
rows.forEach(function(row) {
total_total += row[\'Total\']
total_ocupadas += row[\'Sold\']
})
return \'<div style="font: 16px sans-serif; text-align: right; color: white;"><div style="background: steelblue; padding: 16px; margin: 0px; width: \' + total_ocupadas / total_total * 100 + \'%;"></div></div>\'
}')