Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate R-interface for custom cell-rendering #990

Open
3 tasks done
markschat opened this issue Apr 7, 2022 · 3 comments
Open
3 tasks done

Integrate R-interface for custom cell-rendering #990

markschat opened this issue Apr 7, 2022 · 3 comments

Comments

@markschat
Copy link

markschat commented Apr 7, 2022

First: DT is a great and mature package I love and use lot - thank´s for that 🎉

One major drawback I´ve noticed when applying custom renderings on cell content. DT has some predefined format*() functions which are useful for specific cases. If I want a different cell output (icons, badges, tooltips, ...) things get quiet uncomfortable.

Either I can use R and format the input data upfront using all the great tools like htmltools, fontawesome, ... (This feels unclean to me, as DT should be responsible for the cell formatting/ styling and not the "raw input data") or I have to go to the JavaScript side of things, which is ok but takes me outside of R.

Recently I took a look at reactable and fell in love with their concept of custom cell rendering. Here´s a short example:

library(reactable)

data <- MASS::Cars93[1:5, c("Manufacturer", "Model", "AirBags")]

reactable(
  data, 
  columns = list(
    Model = colDef(cell = function(value, index) {
      url <- sprintf("https://wikipedia.org/wiki/%s_%s", data[index, "Manufacturer"], value)
      htmltools::tags$a(href = url, target = "_blank", as.character(value))
    }),
    AirBags = colDef(cell = function(value) {
      if (value == "None") "\u274c No" else "\u2714\ufe0f Yes"
    })
  )
)
  • Input data and cell rendering/ content-styling are cleanly separated
  • An R-Function can be used for rendering/ styling (taking cell value, row index, and column name as arguments)

At the moment DT has a very similar feature options$columnDefs$render that only supports JS-Functions. I think it would be great to expand this to regular R-Functions. It would add endless flexibility to custom cell-rendering with an clean and easy to use interface.


By filing an issue to this repo, I promise that

  • I have fully read the issue guide at https://yihui.name/issue/.
  • I have provided the necessary information about my issue.
    • If I'm asking a question, I have already asked it on Stack Overflow or RStudio Community, waited for at least 24 hours, and included a link to my question there.
    • If I'm filing a bug report, I have included a minimal, self-contained, and reproducible example, and have also included xfun::session_info('DT'). I have upgraded all my packages to their latest versions (e.g., R, RStudio, and R packages), and also tried the development version: remotes::install_github('rstudio/DT').
    • If I have posted the same issue elsewhere, I have also mentioned it in this issue.
  • I have learned the Github Markdown syntax, and formatted my issue correctly.

I understand that my issue may be closed if I don't fulfill my promises.

@markschat markschat changed the title Integrate R-Interface for custom cell-rendering Integrate R-interface for custom cell-rendering Apr 7, 2022
@shrektan
Copy link
Collaborator

shrektan commented Apr 7, 2022

Is PR #949 what you want?

@markschat
Copy link
Author

Is PR #949 what you want?

@shrektan Your PR nails it! It´s nearly identical 😀 Thank´s for providing some workable code 👏. I just went through all issues to see if there is a similar request, didn´t check the PR´s.

I will give it a try later eventually and some feedback if possible. Should this issue be closed/ referenced in your PR?

@mikmart
Copy link
Contributor

mikmart commented Jan 25, 2024

I played around with the idea of using DataTables' orthogonal data for implementing a formatCustom() in this style. A crude POC, but could possibly go somewhere.

formatCustom = function(table, columns, formatter) {
  if (attr(table$x, 'rownames')) columns = columns + 1
  table$x$data[columns] = lapply(table$x$data[columns], applyCustom, formatter)
  table$x$options$columnDefs = append(
    table$x$options$columnDefs, list(customDef(columns - 1))
  )
  table
}

applyCustom = function(x, formatter) {
  transpose(list(`_disp` = format(formatter(x)), `_orig` = x))
}

transpose = function(x) {
  purrr::list_transpose(x, simplify = FALSE)
}

customDef = function(targets) {
  list(targets = targets, render = list(display = '_disp', `_` = '_orig'))
}

DT::datatable(data.frame(foo = rnorm(10))) |>
  formatCustom(1, formattable::color_tile('yellow', 'red'))

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants