glin / reactable

Interactive data tables for R
https://glin.github.io/reactable
Other
627 stars 80 forks source link

Is there a way to change/update the data within a table using only the JavaScript API #278

Closed michaelpaulhirsch closed 1 year ago

michaelpaulhirsch commented 1 year ago

Firstly, thanks for a fantastic package! It is really excellent.

I would like for a table to change its content in a quarto document with ojs, depending on an input selection that chooses from different api endpoints (all datasets have the same structure, columns, etc.)

I have been trying to find a way of doing this without using crosstalk (the tables are very large, hence the api). Is it possible to accomplish this? - changing the table's state using JavaScript only?

Thanks

glin commented 1 year ago

It's not possible today, but I've been thinking about adding this for a long time. The only issue before was that it was very unlikely to ever be used, considering everyone would already be using Shiny for dynamic data fetching/updating anyway. But now that Quarto is here, I can see more use cases for updating data via JavaScript, or even rendering the table through JavaScript alone.

One question though - do you have your data in row or column format? By row format, I mean an array of objects like [{ i: 0, x: 'a' }, { i: 1, x: 'b' }]. By column format, I mean an object of arrays like { i: [0, 1], x: ['a', 'b'] }. Most JavaScript table APIs use row format, which is typically easier to work with, but reactable internally uses column format for efficiency. I'm wondering whether reactable should support both formats, but I guess there's also HTMLWidgets.dataframeToD3() to transform columns to rows.

michaelpaulhirsch commented 1 year ago

Thanks for the reply

Yeah, the application I want to use it in is in quarto. I would be happy with either format really

Thanks

michaelpaulhirsch commented 1 year ago

Happy to help with a PR on this, however I could only really help on the R side I'm afraid

glin commented 1 year ago

This is now done in https://github.com/glin/reactable/commit/858cc8b8dc18aa54755d8b81837636b82ed44d06:

I ended up adding support for either row or column formatted data, and it's autodetected by Reactable.setData(). Here's a short example of filtering a dataset using Observable inputs, based on Quarto's penguins example: https://github.com/glin/reactable/blob/main/vignettes/quarto-penguins/quarto-penguins.qmd. Or live at https://glin.quarto.pub/reactable-penguins/

You still need to create the table in R, but if you don't have the initial data, you can use an empty data frame and call Reactable.setData() on it afterwards, like:

data <- data.frame(species = character(0), island = character(0), bill_length = numeric(0))

reactable(data, elementId = "tbl")

If you have any fancier examples of Quarto/Observable, that would be useful too, as I've only spent a couple minutes reading about Observable and copying examples 🙂

michaelpaulhirsch commented 1 year ago

thank you!!

glin commented 1 year ago

Another small update: I moved the Quarto example to vignettes/quarto/observable-reactable.qmd and added a bit more content. There's now also an example of using reactable to filter Observable charts/outputs using the new Reactable.onStateChange() method in the JS API.

Demo: https://glin.quarto.pub/observable-reactable/ (this will eventually be added to the package docs)