2.3 Static Quarto Dashboards
2.3 Static Quarto Dashboards
Learning objectives
By the end of this chapter, you can:
- decide between a report and a dashboard using audience and update frequency.
- build a multipage dashboard from an existing Quarto document with
format: dashboard. - compose the initial screen’s information hierarchy using rows, columns, value boxes, and tabsets.
- control layout overflow through percentage heights and widths, scrolling, and expansion options.
- publish a static dashboard to Quarto Pub / GitHub Pages with
quarto publish.
Prerequisite check (≤5 minutes)
Continue when you can complete these checks independently; otherwise revisit the tidyverse prerequisites and Chapters 1.7/1.8.
- Render a
.qmdfile to HTML and change its title in YAML. - Use ggplot2 to plot bill length against body mass in
palmerpenguins::penguins, colored byspecies.
1. When to use a dashboard: Audience × update frequency
A report tells a story; a dashboard puts answers on display. A useful rule of thumb: if different people ask the same question every week, put the answer on a dashboard.
| Dimension | Report | Dashboard |
|---|---|---|
| Reading pattern | Linear reading that follows an argument | A quick scan to retrieve a number |
| Update frequency | One-off delivery, infrequent revision | Changing data, periodic rerendering |
| Initial screen’s responsibility | Context and question | KPI values and one main chart |
| Typical question | “Why has churn increased?” | “What is this week’s churn rate?” |
The short decision rule: give readers a report for explanation and a dashboard for monitoring. This chapter covers static dashboards: render once and host widely. Dynamic interaction comes in Chapter 2.4.
2. A minimal dashboard: format: dashboard
Dashboards are built into Quarto ≥ 1.4. Run quarto --version in a terminal to check first.
Build your first dashboard in three steps with this complete penguins-dash.qmd file:
---
title: "Penguins at a glance"
format: dashboard
---
```r
library(ggplot2)
penguins <- palmerpenguins::penguins
```
```r
#| title: Bill length × body mass
ggplot(penguins, aes(bill_length_mm, body_mass_g, color = species)) +
geom_point()
```Three essentials: a # heading creates a page; each code block that produces output becomes a card, so adding another plot adds another card; #| title: names the card.
Dashboard is not a separate R package. An Unknown format error usually means your Quarto version predates 1.4. Upgrade Quarto itself rather than calling install.packages().
3. Pages, rows, and columns: Thinking in grids
The structure uses only three heading levels. orientation: determines the default direction for ##; rows is the default:
# Pageadds a navigation tab;## Rowcreates a horizontal band.### Columndivides a row. Assignheight=to rows andwidth=to columns; percentages are normalized automatically.
Adapt the §2 file into two rows: metrics and charts.
# Penguins at a glance
## Metrics {height="25%"}
```r
#| content: valuebox
#| title: Mean body mass (g)
list(value = round(mean(penguins$body_mass_g, na.rm = TRUE)))
```
## Charts {height="75%"}
### Scatterplot {width="70%"}
```r
#| title: Bill length × body mass
ggplot(penguins, aes(bill_length_mm, body_mass_g)) + geom_point()
```
### Composition {width="30%"}
```r
#| title: Species composition
ggplot(penguins, aes(species, fill = species)) + geom_bar()
```Without running the code, sketch a wireframe of the rendered file. Change orientation to columns, draw a second sketch, and explain the difference. Catch layout errors at this stage.
With orientation: rows, a width= on a ## heading is silently ignored. Width belongs to columns; height belongs to rows. An incorrect assignment simply has no effect.
4. Value boxes and content cards
A value box is a dashboard’s signal light: one number and one semantic color. Use semantic color names such as success, danger, and info, and names from Bootstrap Icons for icons.
#| content: valuebox
#| title: Heaviest penguin (g)
#| color: success
list(value = max(penguins$body_mass_g, na.rm = TRUE))icon: and color: may be omitted or supplied inside list(). A plain Markdown alternative is ::: {.valuebox icon="search" color="info"}; its body can mix text and inline `r ` expressions, useful for a label plus a number.
Cards can hold more than charts: use knitr::kable() for a static table or DT::datatable() for a sortable table that works entirely in the browser, including on static hosting. Each card should communicate one thing.
5. Tabsets and sizing
## Details {.tabset}
### Summary table
```r
#| title: Means by species
penguins |>
dplyr::group_by(species) |>
dplyr::summarise(mean_bill = mean(bill_length_mm, na.rm = TRUE)) |>
knitr::kable(digits = 1)
```For a second tab, add ### Scatterplot followed by a plot block as usual.
Three size-related controls, under format: dashboard: in YAML unless stated otherwise:
scrolling: trueallows scrolling instead of squeezing everything into one screen; often useful for analysis.- Per-block
#| expansion: truelets readers expand a card; globalexpandable: falsedisables expansion.
6. Themes and branding: brand.yml and light/dark modes
format:
dashboard:
theme:
light: flatly
dark: darkly
brand: _brand.yml # Quarto ≥ 1.6; share the same brand with Chapter 2.8 reportsLight and dark themes let readers follow their system preference. A brand.yml file centralizes colors, fonts, and logos across deliverables. Brand colors take precedence over the theme: establish the brand first, then refine the theme.
7. Publishing a static dashboard
A rendered static dashboard is HTML plus resources, so it can use any static host:
quarto publish quarto-pub # One command for coursework and prototypes
quarto publish gh-pages # Host alongside a repository on GitHub PagesFor daily-changing data, schedule quarto render and publication through GitHub Actions. This gives you a periodically refreshed static dashboard: the scheduled mode in Chapter 2.4 §1.
On public static hosting, data travel with the page and become public. De-identify personal information first. Host internal data on your organization’s intranet, not a public service.
Recreate the §2–§4 penguins dashboard from a blank file: three value boxes for mean body mass, sample size, and species count, plus scatterplot and bar-chart cards. Give every card a title. A successful render meets the requirement.
Move a chart you styled in Chapter 1.8 into a two-page dashboard. Page 1, “Overview,” uses rows of 25%/75% height. Page 2, “Details,” uses a tabset for a summary table and the original chart. Use width= to divide columns at least once.
Round 1 (AI prohibited): Design an airline-delay dashboard with nycflights13::flights: four KPI value boxes of your choice and one main chart. Before coding, write down the most important number a reader should find within five seconds. Round 2 (AI allowed): Give Posit Assistant the layout YAML and card titles. Ask only: “Can a reader find that number in five seconds? What distracts their attention?” Record which change you accepted and why.
Capstone
Task: Choose a health-check, penguins, or nycflights dataset and create a two-page static dashboard. Page 1, “Overview,” contains three value boxes and one main chart. Page 2, “Details,” uses a tabset for a kable table and a distribution chart. Apply a consistent brand.yml theme, publish, and submit a link. Use Quarto Pub for public data; for internal data, submit the rendered directory and screenshots.
| Dimension | Meets expectations | Strong | Excellent |
|---|---|---|---|
| Layout | Two pages; no grid overflow | Row/column proportions support reading order | Passes the five-second test with a classmate |
| Content | KPIs and main chart address the same question | Tabset grouping is logical | Each KPI includes a one-line definition |
| Theme | Default theme; light/dark modes work | brand.yml takes effect | Shares a brand file with the Chapter 2.8 report |
| Publication | Renders locally | Published at an accessible link | States data snapshot date and update process |
SOURCES
| Chapter section | Material | Use |
|---|---|---|
| §2–§5 cards, grids, value boxes, and tabsets | posit::conf(2024) quarto-dashboards, 1-hello-dashboards, 2-dashboard-components (Mine Çetinkaya-Rundel and teaching assistant team; README: CC-BY 4.0; LICENSE.md: CC-BY-SA 4.0) |
Adaptation |
| §6–§7 themes, publishing, and deployment modes | Same workshop, 3-theming-styling, 4-parameters-interactivity-deployment, plus official Quarto Dashboards documentation |
Adaptation / reference |
| brand.yml integration, health-check / nycflights exercises, and rubric | This project | Original |
This chapter is published under CC-BY-SA 4.0.