Jeopardy!
Overview
This is my entry into the ⚡R Studio 2022 Table Contest. It uses reactable and scss in Quarto to style a Jeopardy! game board.
My aims for this project were three-fold:
-
To think about creative uses of tables! ✅
-
Learn how to use some of
reactable
’s custom rendering capabilities ✅ -
Continue to investigate and experiment (s)css and Quarto. ✅
Approach
I start by pulling archived Jeopardy! game data using the whatr
📦. What’s nice is that each row of data is indexed by the row and column it appears on in the actual board 😝. This makes it simple to ensure the right content is in the right place. ✅
In the next step, I borrow some preexisting css for creating flip cards 🔍. I ♻️, 🔨 and 🗑 elements in order to match the aesthetic of Jeopardy! This was relatively straightforward, though researching colors and fonts took a bit of time.
The last step is to arrange the data once it’s been read into R into a format serviceable for display. I knew I planned to use reactable
as the display table package and leverage escaping html.
Method 1
My first approach was to bake the html/css stuff directly into each cell, before passing it to reactable for escaping. It looked something like this:
👉️ See Code
raw_data %>%
.... %>%
mutate(content = if_else(row == 1,
# html for header
glue::glue('<div class="flip-card">
<div class="flip-card-inner">
<div class="flip-card-head">
<p>{category}</p>
</div>
<div class="flip-card-head">
{category}
</div>
</div>
</div>'),
# html for clues
glue::glue('<div class="flip-card">
<div class="flip-card-inner">
<div class="flip-card-front">
{value}
</div>
<div class="flip-card-back">
<p>{clue}</p>
<details>
<summary>Answer</summary>
<p>{answer}</p>
</details>
</div>
</div>
</div>'))) %>%
.... %>%
reactable(.,
defaultColDef = colDef(html = TRUE))
While this certainly worked (it has in the past for me), I knew reactable had more to offer in terms of custom rendering. It was time to have a closer look at specifics. 😨
Method 2
It turns reactables defaultColDef
argument works great for custom rendering in this case since every cell in my Jeopardy! board needs the same html/css treatment. It looks something like this:
👉️ See Code
reactable(table_data,
sortable = FALSE,
defaultColDef = colDef(
html = TRUE,
align = "center",
# Header Rendering
header = function(value) {
tags$div(
class = "flip-card flip-card-head",
value
)
},
# Cell Rendering
cell = function(value, index) {
# parse clue, answer from table cell
content <- str_split(value, ";", simplify = TRUE)
clue <- content[1]
answer <- content[2]
# cell content
tags$div(
class = "flip-card",
tags$div(
class = "flip-card-inner",
tags$div(
class = "flip-card-front",
# multiply row index by 200 for tile value
paste("$", index * 200)
),
tags$div(
class = "flip-card-back",
clue,
tags$details(
tags$summary("Answer"),
answer
)
)
)
)
}
)
)
I like this approach much better than the first because I’m keeping table and data wrangling parts of my workflow separate and hopefully more clear for readers. 🤓
Forward
It’s been an awesome ride so far experimenting with Quarto and continuing to learn how to create and modify existing CSS. I’m happy that the R Studio 2022 Table Contest is currently taking place because it was a constructive outlet to build something that uses things I’ve recently learned.
🍻✌ Enjoy!