3

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>\'
                  
      }')
Rcoster
  • 3,170
  • 2
  • 16
  • 35

0 Answers0