16.3 Adding Interactivity
The dashboard built in the previous section is already interactive at the chart level — hover any bar or point and a tooltip appears. Two further levels of interactivity are available, and choosing between them is one of the central design decisions for a dashboard project.
16.3.1 Client-side filters with crosstalk
The crosstalk package adds linked filters that work in plain HTML, with no server. A SharedData object connects a filter widget (a dropdown, a slider) to one or more charts; when the user moves the filter, the linked charts update instantly in the browser.
library(crosstalk)
library(DT)
shared_data <- SharedData$new(absenteeism)
filter_select(
id = "education",
label = "Education",
sharedData = shared_data,
group = ~Education
)
datatable(shared_data, options = list(pageLength = 10))A dashboard with crosstalk is a single self-contained HTML file. It can be emailed, dropped on a static web host, or attached to a learning-management module. There is no server to maintain, no reactive runtime, no scaling concerns. The tradeoff: any computation crosstalk performs runs in the user’s browser, so very large datasets may feel sluggish.
16.3.2 Server-side reactivity with Shiny
Shiny is the alternative when the dashboard needs more than linked filters — when, for example, the user should be able to change a model parameter and have a chart re-fit on the fly. Adding runtime: shiny to the YAML header converts the document into a live Shiny app, with reactive expressions that re-execute whenever a user input changes.
# In the YAML header, add: runtime: shiny
selectInput(
inputId = "education",
label = "Education",
choices = unique(absenteeism$Education)
)
renderPlotly({
filtered <- absenteeism |>
filter(Education == input$education)
p <- ggplot(filtered,
aes(x = Age, y = `Absenteeism time in hours`)) +
geom_point(color = "steelblue") +
theme_minimal()
ggplotly(p)
})Shiny dashboards are powerful but require a Shiny server to host — shinyapps.io, Posit Connect, or self-hosted Shiny Server. For most internal HR reporting, crosstalk is sufficient and dramatically simpler to deploy.
Multiple ways: choosing client-side versus server-side
| Need | Use |
|---|---|
| Hover tooltips, no filters | plotly alone |
| Dropdown / slider filters | crosstalk (client-side) |
| Reactive recomputation on input | Shiny (server-side) |
| Distribute as an emailable file | crosstalk |
| Personalized views per user | Shiny |
Start client-side. Move to Shiny only when the requirements genuinely demand it.