Chapter section list

R Code 12.1 : Show line charts in new navigational structure

#| '!! shinylive warning !!': |
#|   shinylive does not work in self-contained HTML documents.
#|   Please set `embed-resources: false` in your metadata.
#| standalone: true
#| viewerHeight: 800
#| components: [editor, viewer]
#| layout: vertical

## file: app.R
## path: app-071-page-navbar-line-chart/app.R
## my book: @sec-071-page-navbar-line-chart

library(shiny)
library(shinythemes)
library(bslib)
library(dplyr)
library(plotly)
library(ggplot2)
library(ggbump)


rwb <- readRDS(gzcon(url("https://raw.githubusercontent.com/petzi53/rwb-book/master/data/chap011/rwb/rwb.rds")))


sidebar_map <- page_sidebar(
    sidebar = "Controls for map"
)

sidebar_chart <- list(
        selectInput(
            inputId = "var",
            label = "Score or Rank Type",
            choices = c(
                "Global score" = "score",
                "Global Rank" = "rank"
            )
        ),
        selectInput(
            inputId = "country",
            label = "Countries",
            choices = unique(rwb$country_en),
            multiple = TRUE
            )
)


sidebar_country <- page_sidebar(
    sidebar = "Control for country"
)

cards <- list(
    card(
        full_screen = TRUE,
        card_header("This is a map"),
    ),
    card(
        full_screen = TRUE,
        card_header((textOutput("card_title"))),
        plotlyOutput("p")
    ),
    card(
        full_screen = TRUE,
        card_header("This is country information")
    )
)

ui <- page_navbar(
    theme = bs_theme(5, bootswatch = "cosmo"),
    title = "Reporters Without Borders",
    id = "nav",
    sidebar = sidebar(
        conditionalPanel(
            "input.nav === 'Map'",
            "Map controls"
        ),
        conditionalPanel(
            "input.nav === 'Chart'",
            sidebar_chart
        ),
        conditionalPanel(
            "input.nav === 'Country'",
            "Country controls"
        )
    ),
    nav_spacer(),
    nav_panel("Map", cards[[1]]),
    nav_panel("Chart", cards[[2]]),
    nav_panel("Country", cards[[3]]),
    nav_item(tags$a("About",
                    href = "https://rsf.org/en/index",
                    target = "_blank"))
)

server <-  function(input, output) {
    pal = RColorBrewer::brewer.pal(12, "Paired")

    countries <- reactive({
        req(input$country)

        output$card_title <-  renderText({
            if (input$var == "score") {
                s = "Global Score for"
            }
            if (input$var == "rank") {
                s = "Global Rank for"
            }
            s = paste(s, input$country[1])
            if (length(input$country)  > 1) {
                for (i in 2:length(input$country)) {
                    s <- paste(s, input$country[i], sep = ", ")
                }
            }
            s
        })

        rwb |>
            select(year_n, input$var, country_en, iso) |>
            filter(country_en %in% input$country) |>
            arrange(year_n) |>
            na.omit() |>
            droplevels()
    })

    output$p <- renderPlotly({
        req(countries())
        length(pal) <- length(input$country)
        pal <- setNames(pal, input$country)
        if (input$var == "score") {
            plot <- plotly::plot_ly(
                data = countries(),
                x = ~year_n,
                y = ~score,
                color = ~country_en,
                colors = pal,
                type = 'scatter',
                mode = 'lines+markers',
                line = list(width = 4),
                marker = list(size = 20)
            )
        }
        if (input$var == "rank") {
            plot <- ggplot(countries(),
                           aes(x = year_n,
                               y = rank,
                               color = country_en)
            ) +
                geom_bump(linewidth = 1.0) +
                geom_point(size = 5) +
                geom_text(data = countries() |>  filter(year_n == min(year_n)),
                          aes(label = iso), nudge_x = -1,
                          size = 5, color = "black",
                          hjust = 1) +
                geom_text(data = countries() |> filter(year_n == max(year_n)),
                          aes(label = iso), nudge_x = 1,
                          size = 5, color = "black",
                          hjust = 0) +
                theme_bw() +
                theme(legend.position = "none") +
                scale_y_reverse(
                    breaks = waiver(),
                    n.breaks = 25) +
                scale_colour_manual(values = pal)
            plot <- ggplotly(plot)
        }
        plot
    })
}

shinyApp(ui, server)

12.1 Glossary Entries

#> data frame with 0 columns and 0 rows

Session Info

Session Info

Code
sessioninfo::session_info()
#> ─ Session info ───────────────────────────────────────────────────────────────
#>  setting  value
#>  version  R version 4.5.1 (2025-06-13)
#>  os       macOS Sequoia 15.6.1
#>  system   aarch64, darwin20
#>  ui       X11
#>  language (EN)
#>  collate  en_US.UTF-8
#>  ctype    en_US.UTF-8
#>  tz       Europe/Zagreb
#>  date     2025-09-26
#>  pandoc   3.7.0.2 @ /opt/homebrew/bin/ (via rmarkdown)
#>  quarto   1.8.4 @ /usr/local/bin/quarto
#> 
#> ─ Packages ───────────────────────────────────────────────────────────────────
#>  package     * version    date (UTC) lib source
#>  cli           3.6.5      2025-04-23 [1] CRAN (R 4.5.0)
#>  curl          7.0.0      2025-08-19 [1] CRAN (R 4.5.0)
#>  digest        0.6.37     2024-08-19 [1] CRAN (R 4.5.0)
#>  evaluate      1.0.5      2025-08-27 [1] CRAN (R 4.5.1)
#>  fastmap       1.2.0      2024-05-15 [1] CRAN (R 4.5.0)
#>  glossary    * 1.0.0.9003 2025-06-08 [1] local
#>  htmltools     0.5.8.1    2024-04-04 [1] CRAN (R 4.5.0)
#>  htmlwidgets   1.6.4      2023-12-06 [1] CRAN (R 4.5.0)
#>  jsonlite      2.0.0      2025-03-27 [1] CRAN (R 4.5.0)
#>  knitr         1.50       2025-03-16 [1] CRAN (R 4.5.0)
#>  rlang         1.1.6      2025-04-11 [1] CRAN (R 4.5.0)
#>  rmarkdown     2.29       2024-11-04 [1] CRAN (R 4.5.0)
#>  rstudioapi    0.17.1     2024-10-22 [1] CRAN (R 4.5.0)
#>  rversions     2.1.2      2022-08-31 [1] CRAN (R 4.5.0)
#>  sessioninfo   1.2.3      2025-02-05 [1] CRAN (R 4.5.0)
#>  xfun          0.53       2025-08-19 [1] CRAN (R 4.5.0)
#>  xml2          1.4.0      2025-08-20 [1] CRAN (R 4.5.0)
#>  yaml          2.3.10     2024-07-26 [1] CRAN (R 4.5.0)
#> 
#>  [1] /Library/Frameworks/R.framework/Versions/4.5-arm64/library
#>  [2] /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/library
#>  * ── Packages attached to the search path.
#> 
#> ──────────────────────────────────────────────────────────────────────────────