-
Notifications
You must be signed in to change notification settings - Fork 79
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
Calculate width of barchart with JS custom rendering function #88
Comments
Hi, it's not currently possible to get the rest of the values in a column from a JS cell renderer. However, it will likely be possible in the next release, similar to how header and footer render functions get the table data: https://glin.github.io/reactable/articles/custom-rendering.html#javascript-render-function-1 For now, calculations that depend on the entire column can be precalculated in R, and passed to the JS render function. For example:
data <- MASS::Cars93[40:44, c("Make", "Length", "Luggage.room")]
# Put the bar chart width in a "Luggage.room_width" column
data$Luggage.room_width <- paste0(data$Luggage.room / max(data$Luggage.room) * 100, "%")
reactable(data, columns = list(
# Align values using a fixed-width container for units
Luggage.room = colDef(
name = "Luggage Room",
cell = JS("function(cellInfo) {
// Get the precalculated bar chart width
var width = cellInfo.row['Luggage.room_width']
return cellInfo.value + '<div class=\"units\">' +
// Changing units for barchart
'<div style=\"display: flex; align-items: center;\">' +
'<div style=\"flex-grow: 1; margin-left: 6px; height: 14px; background-color: #e1e1e1\">' +
'<div style=\"height: 100%; width: ' + width + '; background-color: #fc5185\"></div>' +
'</div>' +
'</div>' +
'</div>'
}"),
html = TRUE
),
Luggage.room_width = colDef(show = FALSE)
))
data <- MASS::Cars93[40:44, c("Make", "Length", "Luggage.room")]
reactable(data, columns = list(
# Align values using a fixed-width container for units
Luggage.room = colDef(
name = "Luggage Room",
# When using sprintf, make sure to escape percent characters like "%%"
cell = JS(sprintf("function(cellInfo) {
var width = cellInfo.value / %s * 100 + '%%'
return cellInfo.value + '<div class=\"units\">' +
// Changing units for barchart
'<div style=\"display: flex; align-items: center;\">' +
'<div style=\"flex-grow: 1; margin-left: 6px; height: 14px; background-color: #e1e1e1\">' +
'<div style=\"height: 100%%; width: ' + width + '; background-color: #fc5185\"></div>' +
'</div>' +
'</div>' +
'</div>'
}", max(data$Luggage.room))),
html = TRUE
)
)) Neither of these workarounds are great, and I've intentionally avoided creating any examples that do this. To align labels with bar charts, the Twitter Followers tutorial should be more helpful: https://glin.github.io/reactable/articles/building-twitter-followers.html#add-bar-charts. There's also an example further down that renders a bar chart with aligned labels in a JS function: https://glin.github.io/reactable/articles/building-twitter-followers.html#dynamic-formatting. This is probably the closest example to what you'd like to do. Adapting those examples for this table, the code might look like this: data <- MASS::Cars93[40:44, c("Make", "Length", "Luggage.room")]
data$Luggage.room_width <- paste0(data$Luggage.room / max(data$Luggage.room) * 100, "%")
reactable(data, columns = list(
Luggage.room = colDef(
name = "Luggage Room",
cell = JS("function(cellInfo) {
var width = cellInfo.row['Luggage.room_width']
// Create a fixed-width label of 2 characters
var label = '<div>' + cellInfo.value.toString().padStart(2) + '</div>'
return (
'<div style=\"display: flex; align-items: center;\">' +
label +
'<div style=\"flex-grow: 1; margin-left: 6px; height: 14px; background-color: #e1e1e1\">' +
'<div style=\"height: 100%; width: ' + width + '; background-color: #fc5185\"></div>' +
'</div>' +
'</div>'
)
}"),
# Styles for label alignment
style = list(fontFamily = "monospace", whiteSpace = "pre"),
html = TRUE
),
Luggage.room_width = colDef(show = FALSE)
)) |
Thank you a lot for the detailed answer Greg. It´s been very enlightening. Reading documentation I came across the highlighting sorted columns example where there are several arguments passed to
Also, in case it is useful for someone, for me using monospaced fonts caused the table to be vertically misaligned. I used the style below to correct this:
|
Is it possible to calculate the width of a barchart inside a JavaScript function taking into account the rest of the values in that column?
For example, in the Twitter followers example, the width of the column is already defined by
cellInfo.value
. However, what if we want to calculate the width as (I´m just going to invent the code)cellInfo.value / max(colInfo.rows) * 100
, like in the cookbook barchart example?I´ve been playing with the example where a JavaScript render function is used to put a unit in a fixed-width container, preceded by the cell value. I tried to render a barchart inside that container, with not much success.
Changing "units" for a barchart:
So, is it possible to access the rest of the values in the column to calculate the width of the barchart?
Also, how would be the correct way of replacing "units" with a barchart in this example so the charts are aligned?
Best regards,
Alejandro.
The text was updated successfully, but these errors were encountered: