inst/shiny/demo/app.R

library(shiny)
library(ggplot2)
library(ggrepel)
library(showtext)
font_add_google("Oswald", "Oswald")
showtext_auto()
load("demoApp.RData")

bc1 <- inputColumn(
  lcarsButton("btn_totals", "Total words"),
  lcarsButton("btn_best", "Top episodes"),
  lcarsToggle("bars", "Bar values", FALSE, pill = FALSE, inverse = FALSE, "Yes", "No",
              label_color = "atomic-tangerine", label_right = TRUE, width = "150px"),
  lcarsToggle("uniforms", "Uniforms", FALSE, pill = FALSE, inverse = FALSE, "Yes", "No",
              false_color = "lilac", label_color = "lilac", label_right = TRUE, width = "150px"),
  lcarsToggle("dark", "Dark theme", FALSE, pill = FALSE, inverse = FALSE, "Yes", "No",
              false_color = "tamarillo", outer_border = TRUE, outer_color = "tamarillo", label_color = "tamarillo")
)

bc2 <- inputColumn(
  lcarsButton("btn_picard", "PICARD"),
  lcarsButton("btn_data", "DATA"),
  lcarsButton("btn_riker", "RIKER"),
  lcarsButton("btn_laforge", "LA FORGE"),
  lcarsButton("btn_crusher", "CRUSHER"),
  lcarsButton("btn_troi", "TROI"),
  lcarsButton("btn_worf", "WORF"),
  lcarsButton("btn_wesley", "WESLEY")
)

ui <- lcarsPage(
  lcarsHeader("Enterprise NCC-1701-D"),
  lcarsBox(uiOutput("topPanel"),
    title = "Crew summary", left_inputs = bc1, color = "tanoi", title_color = "atomic-tangerine"
  ),
  lcarsBox(uiOutput("bottomPanel"),
    title = "Crew members", left_inputs = bc2, color = "tanoi", title_color = "atomic-tangerine"
  ),
  lcarsHeader()
)

server <- function(input, output) {
  rv <- reactiveValues(cur1 = "totals", cur2 = "PICARD")

  observeEvent(input$btn_totals, { rv$cur1 <- "totals" })
  observeEvent(input$btn_best, { rv$cur1 <- "best" })

  observeEvent(input$btn_picard, { rv$cur2 <- "PICARD" })
  observeEvent(input$btn_data, { rv$cur2 <- "DATA" })
  observeEvent(input$btn_riker, { rv$cur2 <- "RIKER" })
  observeEvent(input$btn_laforge, { rv$cur2 <- "LA FORGE" })
  observeEvent(input$btn_crusher, { rv$cur2 <- "CRUSHER" })
  observeEvent(input$btn_troi, { rv$cur2 <- "TROI" })
  observeEvent(input$btn_worf, { rv$cur2 <- "WORF" })
  observeEvent(input$btn_wesley, { rv$cur2 <- "WESLEY" })

  ptheme <- reactive({
    if(input$dark) theme_lcars_dark(20, "Oswald", 0.1) else theme_lcars_light(20, "Oswald", 0.1)
  })
  clr <- reactive(if(input$dark) "#FFFFCC" else "#000000")
  clr2 <- reactive(if(input$dark) "#99ccff" else "#664466")

  p_totals <- reactive({
    g <- ggplot(totals, aes(character, words, fill = if(input$uniforms) uniform else NULL))
    g <- g + if(input$uniforms)
      geom_col(color = NA, show.legend = FALSE) else
        geom_col(color = NA, fill = clr2(), show.legend = FALSE)
    g <- g + scale_fill_manual(values = uniform_colors) +
      scale_x_discrete(expand = c(0, 0)) +
      scale_y_continuous(expand = c(0, 0)) +
      ptheme() + theme(text = element_text(size = 30)) +
      labs(x = NULL, y = "TOTAL WORDS")
    if(input$bars){
      g <- g + geom_text(aes(label = paste0(round(words / 1000), "K")),
        size = 12, color = "white", vjust = 1.3, family = "Oswald")
    }
    g
  })

  p_biggest <- reactive({
    g <- ggplot(biggest, aes(season, words)) +
      geom_linerange(aes(ymin = ymn, ymax = ymx), color = clr(), size = 0.25)
    g <- g + if(input$uniforms)
      geom_point(aes(color = uniform), size = 1, show.legend = FALSE) else
        geom_point(size = 1, color = clr(), show.legend = FALSE)
    g + scale_color_manual(values = uniform_colors) +
      geom_text_repel(aes(label = paste0(title, " (", character, ")")), color = clr(),
                      size = 3, hjust = -0.1, direction = "y", segment.size = 0.15, min.segment.length = 0.65) +
      scale_x_continuous(breaks = 1:7, labels = 1:7, expand = expansion(0, c(0.1, 0.8))) +
      ptheme() + theme(panel.grid.minor = element_blank(), text = element_text(size = 30)) +
      labs(x = "SEASON", y = "TOTAL WORDS")
  })

  topPanelPlot <- reactive({
    switch(rv$cur1, totals = p_totals(), best = p_biggest())
  })

  output$topPanel <- renderUI({
    totals <- rv$cur1 == "totals"
    fluidRow(
      column(3,
        if(totals) h3("Total spoken words") else h3("Prominent roles"),
        if(totals) p("Estimated spoken word count for each member of the main bridge crew.") else
            p("A summary of each character's biggest episode per season in terms of estimated spoken words"),
        br(), br(),
        HTML("<p>Side note: Notice the customization of the toggle buttons in the side panel. See <code>lcarsApp(\"toggle\")</code> for many more examples.</p>")
      ),
      column(9,
        renderPlot(topPanelPlot(), res = 200, height = 600)
      )
    )
  })

  bottomPanelPlot <- reactive({
    d <- biggest[biggest$character == rv$cur2, ]
    clrs <- ifelse(rv$cur2 %in% c("CRUSHER", "TROI", "WESLEY"), uniform_colors[3],
                   ifelse(rv$cur2 %in% c("DATA", "LA FORGE", "WORF"), uniform_colors[2], uniform_colors[1]))
    g <- ggplot(d, aes(season, words)) +
      geom_linerange(aes(ymin = ymn, ymax = ymx), color = clr(), size = 0.25)
    g <- g + if(input$uniforms)
      geom_point(aes(color = uniform), size = 1, show.legend = FALSE) else
        geom_point(size = 1, color = clr(), show.legend = FALSE)
    g + scale_color_manual(values = clrs) +
      geom_text_repel(aes(label = paste0(title, " (", character, ")")), color = clr(),
                      size = 6, hjust = -0.1, direction = "y", segment.size = 0.15, min.segment.length = 0.65) +
      scale_x_continuous(breaks = 1:7, labels = 1:7, expand = expansion(0, c(0.1, 0.8))) +
      ptheme() + theme(panel.grid.minor = element_blank(), text = element_text(size = 30)) +
      labs(x = "SEASON", y = "TOTAL WORDS")
  })

  output$bottomPanel <- renderUI({
      fluidRow(column(12, renderPlot(bottomPanelPlot(), res = 200, height = 600)))
  })

}

shinyApp(ui = ui, server = server)

Try the lcars package in your browser

Any scripts or data that you put into this service are public.

lcars documentation built on Sept. 10, 2023, 9:07 a.m.