MyNixOS website logo
Description

Link Interactive Plots and Tables in 'shiny' Applications.

Build powerful, linked-view dashboards in 'shiny' applications. With a declarative, one-line setup, you can create bidirectional links between interactive components. When a user interacts with one element (e.g., clicking a map marker), all linked components (such as 'DT' tables or other charts) instantly update. Supports 'leaflet' maps, 'DT' tables, 'plotly' charts, and spatial data via 'sf' objects out-of-the-box, with an extensible API for custom components.

linkeR: Effortless Linked Views for 'shiny' Applications

R-CMD-check Codecov testcoverage CRANstatus Lifecycle:experimental EpiForeSITE ForeSITEGroup

Create synchronized, interactive dashboards where one click updates multiple components

linkeR makes it effortless to create linked views in 'shiny' applications. When users interact with one component (like clicking a map marker), all related components (tables, charts, other maps) automatically update to show corresponding information.

What linkeR Does

  • Bidirectional Linking: Click a map marker → table row highlights. Click table row → map zooms and shows popup.
  • One-Line Setup: Link multiple components with a single function call
  • Custom Behaviors: Define exactly what happens when users click different components
  • Multi-Component Support: Link maps, tables, charts, and more in complex dashboards
  • Zero Boilerplate: No manual observer setup or event handling required

Why Use linkeR?

Before linkeR (Manual Approach)

# Complex manual setup for each component pair
observeEvent(input$map_marker_click, {
  clicked_id <- input$map_marker_click$id
  # Find corresponding table row
  row_idx <- which(my_data()$id == clicked_id)
  # Update table selection
  dataTableProxy("my_table") %>% selectRows(row_idx)
  # Update map view
  leafletProxy("my_map") %>% setView(...)
  # Update any other components...
  # Repeat this for every component combination!
})

observeEvent(input$my_table_rows_selected, {
  # More boilerplate code...
  # Handle edge cases...
  # Ensure consistency...
})

With linkeR (Simple Approach)

# One line links everything!
link_plots(
  session,
  my_map = my_data,
  my_table = my_data,
  shared_id_column = "id"
)

Key Benefits

Manual ApproachlinkeR Approach
50+ lines of observer code1 function call
Easy to introduce bugsTested and reliable
Hard to maintainDeclarative and clear
Limited to 2 componentsUnlimited components
No built-in customizationRich customization options

Installation

# Install from CRAN (when available)
install.packages("linkeR")

# Or install development version from GitHub
# install.packages("devtools")
devtools::install_github("EpiForeSITE/linkeR")

Requirements

For linking to work, your setup needs:

  1. Shared ID Column: All datasets must have a common identifier column
  2. Matching Component IDs:
    • Leaflet: Use layerId = ~your_id_column
    • DT: Row numbers automatically map to data rows
  3. Reactive Data: Wrap your data in reactive()
# Good: Proper setup
my_data <- reactive({
  data.frame(
    id = 1:10,           # ← Shared ID column
    name = paste("Item", 1:10),
    lat = runif(10), lng = runif(10)
  )
})

output$my_map <- renderLeaflet({
  leaflet(my_data()) %>%
    addMarkers(layerId = ~id)  # ← layerId matches shared_id_column
})

link_plots(session, my_map = my_data, shared_id_column = "id")

# Bad: Missing layerId
output$my_map <- renderLeaflet({
  leaflet(my_data()) %>%
    addMarkers()  # ← No layerId = no linking!
})

Supported Components

ComponentStatusNotes
Leaflet Maps✅ Full SupportInteractive maps with markers, circles, polygons
DT DataTables✅ Full SupportSortable, filterable tables
Plotly Charts🔄 PartialSingle selection supported
Custom Components🔄 PartialAny 'shiny' component with click events, Requires manual event handling
Base R Plots📋 PlannedStatic plots with click detection
Mapbox📋 PlannedAlternative mapping solution

Plotly visual feedback

For native plotly selection highlighting to work, your Shiny UI must include a custom JavaScript message handler:

tags$script(HTML("
  Shiny.addCustomMessageHandler('eval', function(code) {
    try {
      eval(code);
    } catch(e) {
      console.error('JavaScript execution error:', e);
    }
  });
"))

This enables linkeR to send selection updates to plotly charts for visual feedback.

Contributing

Contributions are welcome and encouraged! Follow best practice for github contributions.

Development Setup

# Clone and setup
git clone https://github.com/EpiForeSITE/linkeR.git
cd linkeR

# Install dependencies
devtools::install_deps()

# Run tests
devtools::test()

# Check package
devtools::check()

License

This project is licensed under the MIT License - see the LICENSE file for details.


Metadata

Version

0.1.3

License

Unknown

Platforms (76)

    Darwin
    FreeBSD
    Genode
    GHCJS
    Linux
    MMIXware
    NetBSD
    none
    OpenBSD
    Redox
    Solaris
    WASI
    Windows
Show all
  • aarch64-darwin
  • aarch64-freebsd
  • aarch64-genode
  • aarch64-linux
  • aarch64-netbsd
  • aarch64-none
  • aarch64-windows
  • aarch64_be-none
  • arm-none
  • armv5tel-linux
  • armv6l-linux
  • armv6l-netbsd
  • armv6l-none
  • armv7a-linux
  • armv7a-netbsd
  • armv7l-linux
  • armv7l-netbsd
  • avr-none
  • i686-cygwin
  • i686-freebsd
  • i686-genode
  • i686-linux
  • i686-netbsd
  • i686-none
  • i686-openbsd
  • i686-windows
  • javascript-ghcjs
  • loongarch64-linux
  • m68k-linux
  • m68k-netbsd
  • m68k-none
  • microblaze-linux
  • microblaze-none
  • microblazeel-linux
  • microblazeel-none
  • mips-linux
  • mips-none
  • mips64-linux
  • mips64-none
  • mips64el-linux
  • mipsel-linux
  • mipsel-netbsd
  • mmix-mmixware
  • msp430-none
  • or1k-none
  • powerpc-linux
  • powerpc-netbsd
  • powerpc-none
  • powerpc64-linux
  • powerpc64le-linux
  • powerpcle-none
  • riscv32-linux
  • riscv32-netbsd
  • riscv32-none
  • riscv64-linux
  • riscv64-netbsd
  • riscv64-none
  • rx-none
  • s390-linux
  • s390-none
  • s390x-linux
  • s390x-none
  • vc4-none
  • wasm32-wasi
  • wasm64-wasi
  • x86_64-cygwin
  • x86_64-darwin
  • x86_64-freebsd
  • x86_64-genode
  • x86_64-linux
  • x86_64-netbsd
  • x86_64-none
  • x86_64-openbsd
  • x86_64-redox
  • x86_64-solaris
  • x86_64-windows