Enabling R styling via a new param `formatter`
Closes #938 #652 #990
DT implements many nice JS wrappers on styling the columns. However, R users may still find they want to implement their own style, as the love for beautiful table never ends. They can do it in two ways:
- On JS side: Write a JS function and set it in
renderoptions, i.e.,datatable(..., options = list( columnDefs = list( list(targets = 1, render = JS(...))))) - On R side: Transform the R data.frame object's relevent column into characters, then pass it to DT, probably need to set the
escapeargument toFALSE.
Unfortunately, those two methods are either difficult to implement or contain side-effects:
- JS method:
- Many R users are not aware of the existence of the
columnDefs.renderoption - Write the JS function correctly is not easy, especially when the "style" is complicated
- You can't leverage the existing R packages like
formattable
- R method:
- Probably lose the ability to sort, filter or search correctly as the raw "data" is tranformed into formatted "data"
- Probably need additional efforts to "unescape" data, align text, etc.
The new param formatter allows users to write formatting functions in R without losing the ability to sort, filter or search by retaining the raw data "untouched" as it creates invisible helper columns.
TODO
- [ ] support formatter type like
list(function() ... , targets = ...) - [ ] figure out a way when the formatter need other info from the data, like other column
- [ ] try out all the possible corner cases in case of unexpected happening
- [ ] state clear the limitations in doc (probably cause issues when editing data
- [ ] need to triger updating the hidden formatted columns when source is updated, e.g, via proxy, or editing
- [ ] NEWS
- [ ] Add an example into inst/example
- [ ] Add an example into site
- [ ] add tests
Example
set.seed(100)
x <- rnorm(10)
rk <- rank(x)
prefix <- sample(LETTERS[1:3], replace = TRUE, 10)
tbl <- data.frame(V1 = x, V2 = x, V3 = x, V4 = x, RK = rk)
DT::datatable(tbl, rownames = FALSE, filter = "top", formatter = list(
V2 = function(x) paste0(prefix, round(x * 100, 2), "%"),
V3 = formattable::percent,
V4 = function(x) round(x * 100, 2),
V4 = formattable::color_tile(min.color = "yellow", max.color = "red")
))
Now I think this feature is not suitable for DT as it becomes more complicated than I thought. I don't wanna introduce any complexity into DT as it's already a big project.
Close it for now.
It's was a very good try. Thanks. (Sob). Perhaps later ? :)
@yihui , @shrektan
This reopened issue gives me the opportunity to thank you for your work on DT.
When I first installed DT in early 2018, for me it was a simple adaptation of datatable.net, but now that I'm trying to use datatable.net with Flask Rest and VueJs 3 I see that I have to rewrite a lot of things which I thought was in datatable.net but actually written in the server side of DT, and I understand how your API wrapping initial datatable.net ones in the front side.
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.