Shiny Dashboards

Carlos A. Ar.

Última edición 06 de septiembre del 2021

#Paquetes a usar
library(shinydashboard)
library(shinydashboardPlus)
library("leaflet")

#Condiciones generales del Rmd
knitr::opts_chunk$set(eval = FALSE)

1. Estructura de ShinyDashboard

Es una página un poco más elaborada que shiny porque te permite tener múltiples accesos dado el panel de menú que se inserta del lado izquierdo.

Las partes que componen al Dashboard son dos: la interfás de usuario (ui) y el servidor (server).

La interfás de usuario (lo que el usuarioo puede ver y “tocar”) se compone de tres cosas principalmente:

Cada una de las cuales se estudiarán en este documento.

Primero veamos en forma general cómo se compone un dashboard de Shiny:

# El ui necesita ahora tres elementos principales
 header <- shinydashboard::dashboardHeader()
 sidebar <- shinydashboard::dashboardSidebar()
 body <- shinydashboard::dashboardBody()

#Generamos la interfás de usuario con esos elementos
ui <- shinydashboard::dashboardPage(skin = "green", header, sidebar, body)

#Creamos el servidor como siempre
server <- function(input, output){}

#Creamos la aplicación de shiny
shiny::shinyApp(ui, server)

2. Conexiones entre ui and server.

Recordemos que dentro de una shiny app, necesitamos la interfás de usuario y el servidor que se conectan mediante los inputs, outputs y render functions.

Cada función de ___Input o ___Output va dentro del ui mientras que cada función de render___ va dentro del server y sirve para definir (renderizadamente) los objetos creados que aparecerán en la ui. Es por ello que para cada render, le corresponde un tipo de Output.

Se puede leer información (pero no entendí eso qué o qué)

Para poder hacer botones renderizados que les des click y se aumente la cuenta.

# En la barra de menú ponemos un botón para tocar.
sidebar <- dashboardSidebar(
              actionButton("click", "Update click box") # <- es una entrada
           ) 

# El servidor resibirá el valor del click y generaremos 
# la salida "Click Box"
server <-
  function(input, output) {
    output$click_box <-
      renderValueBox({
        valueBox(value = input$click, 
                 subtitle = "Click Box")
      })
  }

# La salida se mostrará en el cuerpo de nuestro dashboard
body <- dashboardBody(valueBoxOutput("click_box"))

3. Personalización del dashboard

Acomodo del body por Bootstrap

Para los shiny dashboord se usa un tipo de “programación” bootstrap que consiste en ordenar la información por columnas o renglones. El número de columas permitido (dentro del body) es 12 así mismo para el número de renglones. En ese sentido, es importante saber cómo se puede hacer una sintáxis de código para acomodarlo en nuestro dashboard.

Por renglones

Podemos hacer que en el body del dashboard, existan diversas filas que contengas información.

#Dentro del body de la shiny dashboard
body <- dashboardBody(

#Creamos un renglón
  fluidRow(
  # Qué contenga una "caja"
    box(
      # que abarque las 12 columans posibles
      width = 12,
      #Y que lleve un cierto título
      title = "Regular Box, Row 1",
      "Star Wars"
      )
  ),
  
  #Adempas creamos otro renglón
  fluidRow(
    #Con otra caja
    box(
      #que igual ocupe las 12 columnas 
      width = 12,
      title = "Regular Box, Row 2",
      "Nothing but Star Wars"
      )
  )
)

Por columnas

body <- dashboardBody(
  fluidRow(
#Aquí no es necesario poner dos "fluidRow" dado que ya sabemos que existe
#una sola columna para todas las filas
      #Especificamos el ancho de la columna (que consta de 6 columanas)
      column(width = 6,
      infoBox(
        #La caja del contenido no tiene un ancho especídico porque ese ya 
        #se había especificado anteirormente. 
        width = NULL,
        title = "Regular Box, Column 1",
        subtitle = "Gimme those Star Wars"
      )
    ),
# Esta es la otra columna
    column(width = 6,
      infoBox(
      width = NULL,
      title = "Regular Box, Column 2",
      subtitle = "Don't let them end"
      )
    )
  )
)

Por renglones y columnas

body <- dashboardBody(
  fluidRow(
# Un relón "entero"
  box(
    width = 12,
    title = "Regular Box, Row 1",
    "Star Wars, nothing but Star Wars"
    )
  ),

#Otro renglón que se divide
  fluidRow(
  #Esta es la primera columna de ese rebglón
  column(width = 6,
    infoBox(
      width = NULL,
      title = "Regular Box, Row 2, Column 1",
      subtitle = "Gimme those Star Wars"
      )
    ),
  #Esta es la segunda columna de ese rebglón
  column(width = 6,
    infoBox(
      width = NULL,
      title = "Regular Box, Row 2, Column 2",
      subtitle = "Don't let them end"
      )
    )
  )
)

Cambiar colores, fondo, estilos de letra

Colores

Para cabiar colores solo es necesario usar la función skin dentro de la función dashboardPage() donde se ponen el header, sidebar y output.

Los colores disponibles son:

  • blue (por defecto)

  • black

  • purple

  • green

  • red

  • yellow

ui <- dashboardPage(
#Este es el parámetro que cambia el color
  skin = "purple",
  header = dashboardHeader(),
  sidebar = dashboardSidebar(),
  body = body)

CSS. Íconos.

Podemos además de cambiar el color, la letra, el fodo, añadir muchas cosas que harán ver nuestra imagen increible.

La manera formal es sabiendo un poco sobre esta sintáxis que es “todo un mundo”. Sin embargo, aquí veremos cómo podemos hacer ciertas cosas con este estilo de formato añadido a la shiny dashboard.

body <- dashboardBody(
#Iniciamos la escritura en CSS
      tags$head( # <- cambiamos el título
        tags$style( # <- con un estilo de HTML 
            HTML('  
           h3 {
                font-weight: bold;
              }
            ') #Para que la letra (en el título) sea "negrita"
        )
    ),
  fluidRow(
    box(
      width = 12,
      title = "Regular Box, Row 1",
      "Star Wars, nothing but Star Wars"
    )
  ),
  fluidRow(
    column(width = 6,
      infoBox(
        width = NULL,
        title = "Regular Box, Row 2, Column 1",
        subtitle = "Gimme those Star Wars"
    )
   ),
    column(width = 6,
      infoBox(
        width = NULL,
        title = "Regular Box, Row 2, Column 2",
        subtitle = "Don't let them end"
    )
  )
 )
)

Para poner íconos primero puedes conocer los que hay para posteriormente utilizarlos donde creas conveniente, por ejemplo en el header o algún otro lugar.

header <- dashboardHeader(
  dropdownMenu(
    type = "notifications",
    notificationItem(
      text = "The International Space Station is overhead!",
#Aquí simplemente añadimos el ícono de "nave espacial" en la notificación
      icon = icon("rocket")
    )
  )
)

Podemos también cambiar el color de las cajas que creamos dentro de nuestro dashboard. Esto se hace a través de los destintos estados status que corresponden a lo siguiente:

Veamos el ejemplo siguiente:

body <- dashboardBody(
  tags$head(
    tags$style(
      HTML('
      h3 {
        font-weight: bold;
      }
      ')
    )
  ),
  fluidRow(
    box(
      width = 12,
      title = "Regular Box, Row 1",
      "Star Wars, nothing but Star Wars",
#Aquí hacemos que la primer caja sea roja.
      status = "danger"
    )
  ),
  fluidRow(
    column(width = 6,
      infoBox(
        width = NULL,
        title = "Regular Box, Row 2, Column 1",
        subtitle = "Gimme those Star Wars",
#Podemos añadir al título una estrella
        icon = icon("star")
    )
   ),
    column(width = 6,
      infoBox(
        width = NULL,
        title = "Regular Box, Row 2, Column 2",
        subtitle = "Don't let them end",
#O incluso puedes pintar el fondo de la caja.
        color = "yellow"
    )
  )
 )
)

4. Ejemplo

max_vel <- sort(nasa_fireball$vel)[159]
max_impact_e <- sort(nasa_fireball$impact_e)[500]
max_energy <- sort(nasa_fireball$energy)[500]

n_us <- sum(
  ifelse(
    nasa_fireball$lat < 64.9 & nasa_fireball$lat > 19.5
      & nasa_fireball$lon < -68.0 & nasa_fireball$lon > -161.8,
        1, 0),
  na.rm = TRUE)


server <- function(input, output) {
  output$plot <- renderLeaflet({
    leaflet() %>%
      addTiles() %>%  
      addCircleMarkers(
        lng = nasa_fireball$lon,
        lat = nasa_fireball$lat, 
        radius = log(nasa_fireball$impact_e), 
        label = nasa_fireball$date, 
        weight = 2)
    })
}

body <- dashboardBody(
 fluidRow(
    valueBox(
      value = max_energy, 
      subtitle = "Maximum total radiated energy (Joules)", 
      icon = icon("lightbulb-o")
    ),
    valueBox(
      value = max_impact_e, 
      subtitle = "Maximum impact energy (kilotons of TNT)",
      icon = icon("star")
    ),
    valueBox(
      value = max_vel,
      subtitle = "Maximum pre-impact velocity", 
      icon = icon("fire")
    )
  ),
  fluidRow(
    leafletOutput("plot")
  )
)


ui <- dashboardPage(
  skin = "red",
  header = dashboardHeader(),
  sidebar = dashboardSidebar(),
  body = body
)

shinyApp(ui, server)

Aquí hay más ejemplos

Uno Hecho por mí…

header <- shinydashboard::dashboardHeader(
  dropdownMenu(
    type = "messages",
    messageItem(
        from = "Carliux",
        message = "Este dashboard fue creado para ti, disfrútalo",
        icon = icon("accusoft")
        ),
    messageItem(
        from = "Yane",
        message = "Podrías conocer más acerca de nuestro trabajo en nuestra página", 
        href = "https://tutorialesmg.netlify.app/",
        icon = icon("award")
        ),
    messageItem(
        from = "Lalo",
        message = "Colabora con nosotros para hacer más material", 
        href = "https://github.com/yanelyluna/Sitios-en-R-sobre-Git",
        icon = icon("github")
        )
  ),
dropdownMenu(
       type = "notifications",
       notificationItem(
       text = "El dashboard aún está en desarrollo",
       icon = icon("car-battery")
       ),
       notificationItem(
       text = "Ten gusto por usar estas aplicaciones de R",
       icon = icon("cookie-bite")
       )
  ),


  dropdownMenu(
      type = "tasks",
      taskItem(
      text = "Elegir un tema para hacer un dashboar en shiny",
      value = 50
      ),
      taskItem(
      text = "Ver videos sobre esta herramienta",
      value = 78
      ),
      taskItem(
      text = "Dar click para explorar este dashboard",
      value = 100,
      href = "https://rstudio.github.io/shinydashboard/examples.html"
      )
  )
)


sidebar <- shinydashboard::dashboardSidebar(
  sidebarMenu(
    menuItem(
      text = "Acercamiento de listas",
      tabName = "a_listas"
    ),
    menuItem(
      text = "Dos cuadritos",
      tabName = "d_cuadritos"
    ),
    menuItem(
      text = "Mejor haz una mezcla",
      tabName = "mezcla"
    )
  )
)


body <- shinydashboard::dashboardBody(
    tabItems(
    tabItem(
      
      tabName = "a_listas",
      tabBox(
        title = "Este ejemplo contiene listas.",
        tabPanel("Añade las que quieras",
                 fluidRow(
                    box(
                      width = 12,
                      title = "Una caja larga",
                      "Todo lo que puedes hacer en Shiny Dashboards"
                      )
                  ),
                 
                  fluidRow(
                    box(
                      width = 12,
                      title = "Otra caja larga",
                      "Te sirve para entender el funcionamiento"
                    )
                  )
                ),
        tabPanel("Si quieres pon varios colores",
                fluidRow(
                    box(
                      width = 12,
                      title = "Esta otra caja...",
                      "Está más padre porque tiene colorcitos y además íconos",
                      status = "danger",
                      icon = icon("charging-station")
                      )
                  ),
                 
                  fluidRow(
                    box(
                      width = 12,
                      title = "Igual esta está padre",
                      "Se ve el diseño, todo muy interesante",
                      icon = icon("copy"),
                      color = "orange",
                      status = "danger"
                    )
                  ) 
                )
      )
    ),

    tabItem(
      tabName = "d_cuadritos",
      tabBox(
        title = "Cuadros aquí hay ejemplos",
        
        tabPanel("Cuadritos básicos",
          fluidRow(
            column(width = 6,
                    infoBox(
                      width = NULL,
                      title = "Esta es un bello cuadrito",
                      subtitle = "La verdad creo que esto no es muy útil",
                      color = "orange",
                      icon = icon("cut")
                    )
                  ),
            column(width = 6,
                    infoBox(
                      width = NULL,
                      title = "Segundo cuadrito",
                      subtitle = "Ya me cansé de tratar de usar todos los clicks",
                      color = "green",
                      icon = icon("edit")
                    )
                  )
            ) 
          ),
        tabPanel("Bellos cuadros",
                 fluidRow(
            column(width = 6,
                    infoBox(
                      width = NULL,
                      title = "Mi trecer cuadrito en el Dashboard",
                      subtitle = "Se me acaban las ideas",
                      color = "yellow",
                      icon = icon("fire")
                    )
                  ),
            column(width = 6,
                    infoBox(
                      width = NULL,
                      title = "Último cuadrito de verdad",
                      subtitle = "Esto sí que está muy talachudo, si vieras el código...",
                      ,
                      color = "purple",
                      icon = icon("frog")
                    )
                  )
            ) 
          )
      )
    ),
    tabItem(
      tabName = "mezcla",
        fluidRow(
            box(
              width = 12,
              title = "Este renglonazo",
              "Te quedaste con el ojo triangular, ¿no?",
              status = "danger"
              )
            ),
          
            fluidRow(
            column(width = 6,
              infoBox(
                width = NULL,
                title = "Chance y...",
                subtitle = "No te gustan tan largos",
                color = "olive",
                icon = icon("hiking")
                )
              ),
            column(width = 6,
              infoBox(
                width = NULL,
                title = "Me prefieres a mí",
                subtitle = "Un poco más compacto",
                color = "black",
                icon = icon("file-alt")
                )
              )
            )

      )
    )
  )





server <- function(input, output){
    
}



ui <- shinydashboard::dashboardPage(
                skin = "red", 
                header, 
                sidebar, 
                body
)


shiny::shinyApp(ui, server)