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.