Background: Shiny and HTML

To understand how the parts of a dashboard work together, we first need to know how a Shiny UI is built, and how it relates to the HTML of a web page.

The HTML tag functions in Shiny, like div() and p() return objects that can be rendered as HTML. For example, when you run these commands at the R console, it will print out HTML:

Div content

Paragraph text

Some functions return more complex HTML fragments, and they insulate you, the user, from having to know all the ins and outs of the HTML required to create things like a text input or a sidebar:

The UI for a Shiny app is built out of these pieces of HTML. The shinydashboard package provides a set of functions designed to create HTML that will generate a dashboard. If you copy the UI code for a dashboard page (above) and paste into the R console, it will print out HTML for the dashboard.

Structure overview

The dashboardPage() function expects three components: a header, sidebar, and body:

For more complicated apps, splitting app into pieces can make it more readable:

Now we’ll look at each of the three main components of a shinydashboard.

Body

The body of a dashboard page can contain any regular Shiny content. However, if you’re creating a dashboard you’ll likely want to make something that’s more structured. The basic building block of most dashboards is a box. Boxes in turn can contain any content.

Boxes

Boxes are the main building blocks of dashboard pages. A basic box can be created with the box() function, and the contents of the box can be (most) any Shiny UI content.

In a typical dashboard, these boxes would be placed inside a fluidRow() (we’ll see more on dashboard layout later):

Basic boxes

Basic boxes

Boxes can have titles and header bar colors with the title and status options. The different possible statuses are shown here.

Box header color and title

Box header color and title

You can have solid headers with solidHeader=TRUE, and display a button in the upper right that will collapse the box with collapsible=TRUE:

Solid header and collapse

Solid header and collapse

If you want the boxes to not have a gray or colored bar on top, use solidHeader=TRUE and don’t give a value for status:

No colored bar

No colored bar

Finally, it’s also possible to have a solid background, with the background option. The different possible colors are shown here.

Solid background

Solid background

tabBox

If you want a box to have tabs for displaying different sets of content, you can use a tabBox.

Tabbed boxes

Tabbed boxes

The code to generate this app is below. A tabBox is similar to a tabsetPanel from Shiny in that it takes tabPanels as inputs, allows you to choose which tab is selected, and can be assigned an id. If id is present, you can access which tab is selected from the server; in the example below, it’s accessed with input$tabset1.

A tabBox also has similarities to a regular box from shinydashboard, in that you can control the height, width, and title. You can also choose which side the tabs appear on, with the side argument. Note that if side="right", the tabs will be displayed in reverse order.

infoBox

There is a special kind of box that is used for displaying simple numeric or text values, with an icon. Here are some examples:

Info boxes

Info boxes

The code to generate these infoBoxes is below. The first row of infoBoxes uses the default setting of fill=FALSE, while the second row uses fill=TRUE.

Since the content of an infoBox will usually be dynamic, shinydashboard contains the helper functions infoBoxOutput and renderInfoBox for dynamic content. The different possible colors are shown here.

Layouts

Laying out the boxes requires a little knowledge of the Bootstrap grid layout system. The body can be treated as a region divided in to 12 columns of equal width, and any number of rows, of variable height. When you place a box (or other item) in the grid, you can specify how many of the 12 columns you want it to occupy. In this screenshot, the first row of boxes each are 4 columns wide, and the second column of boxes are each 6 columns wide.

Broadly speaking, there are two ways of laying out boxes: with a row-based layout, or with a column-based layout.

Row-based layout

In a row-based layout, boxes must go in a row created by fluidRow(). Rows have a grid width of 12, so a box with width=4 takes up one-third of the width, and a box with width=6 (the default) takes up half of the width.

With a row-based layout, the tops of the boxes in each row will be aligned, but the bottoms may not be – it depends on the content of each box. A row-based layout might look like this:

Row-based layout

Row-based layout

This code is the basic scaffolding for these three rows of boxes:

It’s possible to force the boxes to all be the same height, by setting height. In contrast to width, which is set using the 12-wide Bootstrap gride, height is specified in pixels. (This difference is because HTML/CSS layout handles width and height differently. Unfortunately, there isn’t a straightforward way to get equal column heights with Bootstrap.)

For example:

If we set the height of all the boxes, we can get a dashboard like this:

Row-based layout with fixed height

Row-based layout with fixed height