lvalnegri

Building Dashboards with shinydashboard.md

Mar 21st, 2018
206
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!

All commands in the shinydashboard package, in the same way as the shiny commands, follow the camelCase style.

Any shiny dashboard is made up of three main parts:

  • header, with the title, and possibly a navbar tabbed menu, and dropdown menus for messages, notifications, and tasks
  • sidebar, space normally used for input controls
  • body, where the outputs live

To launch an empty functional dashboard just run the following template code:

library(shinydashboard)
header <- dashboardHeader()
sidebar <- dashboardSidebar()
body <- dashboardBody()
ui <- dashboardPage(header, sidebar, body, skin = 'colour_name')
server <- function(input, output){}
shiny::shinyApp(ui, server)

Each part can include any typical shiny object, but also some specific shinydashboard object, as explained below.

In the Header it's possible to include drop down menus:

header <- dashboardHeader(
    dropdownMenu(
        type = 'messages',
        messageItem(
            from = 'author',
            message = 'message text,
            href = 'url',
            icon = icon('icon_name'),  # see http://glyphicons.com/ or https://fontawesome.com/
            time = 'yyyy-mm-dd'
        ),
        messageItem(
            ...
        ),
        ...
    ),
    dropdownMenu(
        type = 'notifications',
        notificationItem(
            from = 'author',
            message = 'notification text',
            href = 'url'
        ),
        notificationItem(
            ...
        ),
        ...
    ),
    dropdownMenu(
        type = 'tasks',
        taskItem(
            text = 'task text',
            value = n     # this is the percentage 0-100 of completeness/progress of the task shown as a barchart to the user
        ),
        taskItem(
            ...
        ),
        ...
    )
)

The above menus have been filled manually, which doesn't look ideal. It's obviously possible to add items automatically and dynamically, iterating over a preloaded or timely polled dataframe or list. As always in Shiny, there needs to be a placeholder for the output in the ui part of the app, called dropdownMenuOutput, and a correspondent render function in the server part, called renderMenu, that generates the actual output. There are many ways to generate the list of items to feed the dropdownMenu function. The following, regarding messages, is only an example that assumes that the content for the messages come from a dataframe called msg_df which has at least three columns: from, message, time.

# UI
  dashboardHeader( dropdownMenuOutput('msg_menu') )
# SERVER
  output$msg_menu <- renderMenu({
    msg_lst <- apply(msg_df, 1, function(x) messageItem(from = x[['from']], message = x[['message']], time = x[['time']]) )
    dropdownMenu(type = "messages", .list = msg_lst)
  })

In the sidebar it's possible to include row tabs that are connected to tabbed page(s) in the body:

sidebar <- dashboardSidebar(
    sidebarMenu(
        menuItem('first_title',
            tabName = 'first_tab_id'  # this is the lookup item for the tab in the body
        ),
        menuItem('second_name',
            tabName = 'second_tab_id'
        ),
        ...
    )
)

In the body it's possible to include many sorts of objects, like tabs (that can be connected with the sidebar by the tabName)

dashboardBody(
    tabBox(
        title = "first level box title text",
        tabPanel("first_level_first_tab_id", "Content for the first tab"),
        tabPanel("first_level_second_tab_id", "Content for the second tab")
    ),
    tabItems(
        tabItem(
            tabName = 'first_tab_id',
            tabBox(
                title = "second level box title text",
                tabPanel("second_level_first_tab_id", "Content for the first tab"),
                tabPanel("second_level_second_tab_id", "Content for the second tab")
            ),
        ),
        tabItem(
            tabName = 'second_tab_id',
            ...
        ),
        ...
    )
)

A box is a peculiar object of a shinydashboard, and represent a rectangular portion of the body of possibly fixed width and height, using the width argument. It can assume one of the four following forms:

  • box
  • infoBox
    infoBox(
        width = n,
        title = "title text",
        subtitle = "subtitle text",
        icon = icon('icon_name'),
        status = 'colour_name',
        colour = 'colour_name'
     )
  • valueBox
  • tabBox

It might be useful to know that some valid statuses and their corresponding colors for the boxes are:

  • primary Blue
  • success Green
  • info Blue
  • warning Orange
  • danger Red

It is possible to create reactive boxes in the usual Shiny way:

  • the reactive functions renderValueBox in the server to generate the object,
  • the corresponding ui functions valueBoxOutput that create the placeholder.
    # UI
    dashboardBody( valueBoxOutput('box_id') )
    # SERVER
    output$box_id <- renderValueBox({
    valueBox(
      value = input$click,
      subtitle = 'Click Box',
    )   
    })

One characteristic of a dashboard is the ability to examine and present real-time data. In shiny, this can be done using one of the following functions, depending on the input:

reactiveFileReader(
    intervalMillis = n,
    session = session, 
    filePath = path,
    readFunc = fun           # the function used to read the data, it can also be user defined
) 
reactivePoll(
)

Shiny is built over the Bootstrap framework, that follows a strict grid layout that spread along 12 columns width. There are only two possible ways of distributing content:

  • column-based
    fluidRow(
        column(width = 6,
            box(
                width = NULL,   # with column layouts, this is mandatory
                title = 'box on the left',
                subtitle = '?'
            ),
            box(
                width = NULL,
                title = 'box on the right',
                subtitle = '?'
            )
        )
    )
  • row-based:
    fluidRow(
        box(
            width = 6,
            title = 'upper box',
            subtitle = '?'
        ),
        box(
            width = 6,
            title = 'lower box',
            subtitle = '?'
        )
    )

    In addition to the above layouts, it's also possible to have a mixed layouts that combine the two.


To enhancing the style of the dashboard it's possible to change any attribute of the page using a file with css commands, and then importing the file when calling the dashboardPage function:

dashboardPage(
    header, sidebar, body, skin = 'colour_name',
    tags$head( tags$link( rel = 'stylesheet', type = 'text/css', href = '/path/to/filename.css' ) )
)

Icons are a great way to make a dashboard look more polished! icons can be rendered in shiny using the icon() function that require at least the name of the icon, as it's listed at font-awesome or glyphicons, and the name of library, if different from font awesome. It's also possible to add a value to the class argument to get a different sub-style:

icon('', class = '')
icon('', , class = '')
Add Comment
Please, Sign In to add comment