--- title: "Content Collections: Deep Dive" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Content Collections: Deep Dive} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 5 ) ``` This vignette goes deep into content collections - the first layer of dashboardr's architecture. For a quick overview, see `vignette("getting-started")`. Throughout this vignette, we use the [General Social Survey](https://kjhealy.github.io/gssr/) as example data. Click below to see the data loading code.
📂 **Data Setup** (click to expand) ```{r setup, message=FALSE, warning=FALSE} library(dashboardr) library(dplyr) library(gssr) library(haven) # Load GSS data data(gss_all) # Latest wave only (for most examples) gss <- gss_all %>% select(year, age, sex, race, degree, happy, polviews, wtssps, # Continuous variables for scatter plots educ, childs, # Confidence in institutions (for multi-question stackedbar example) confinan, conbus, coneduc, confed, conmedic) %>% filter(year == max(year, na.rm = TRUE)) %>% # Filter to substantive responses for core variables filter( happy %in% 1:3, # very happy, pretty happy, not too happy polviews %in% 1:7, # extremely liberal to extremely conservative !is.na(age), !is.na(sex), !is.na(race), !is.na(degree) ) %>% # Convert to factors with proper labels mutate( happy = droplevels(as_factor(happy)), polviews = droplevels(as_factor(polviews)), degree = droplevels(as_factor(degree)), sex = droplevels(as_factor(sex)), race = droplevels(as_factor(race)), # Confidence variables: convert non-substantive (IAP, don't know, etc.) to NA # Then use drop_na_vars = TRUE in visualizations confinan = ifelse(confinan %in% 1:3, confinan, NA), conbus = ifelse(conbus %in% 1:3, conbus, NA), coneduc = ifelse(coneduc %in% 1:3, coneduc, NA), confed = ifelse(confed %in% 1:3, confed, NA), conmedic = ifelse(conmedic %in% 1:3, conmedic, NA), # Convert to labeled factors confinan = factor(confinan, levels = 1:3, labels = c("a great deal", "only some", "hardly any")), conbus = factor(conbus, levels = 1:3, labels = c("a great deal", "only some", "hardly any")), coneduc = factor(coneduc, levels = 1:3, labels = c("a great deal", "only some", "hardly any")), confed = factor(confed, levels = 1:3, labels = c("a great deal", "only some", "hardly any")), conmedic = factor(conmedic, levels = 1:3, labels = c("a great deal", "only some", "hardly any")) ) # Full time series (for timeline examples) gss_timeline <- gss_all %>% select(year, happy) %>% filter(happy %in% 1:3, !is.na(year)) %>% mutate(happy = droplevels(as_factor(happy))) ```
```{r, include = FALSE} library(dashboardr) ``` ## 📦 What Content Collections Store A content collection is a container that holds visualizations, content blocks, interactive inputs, and layout helpers. Here's what you can add:
Category Types Functions
Visualizations Bar, Stacked Bar, Histogram, Density, Boxplot, Timeline, Heatmap, Scatter, Treemap, Map add_viz(), add_vizzes()
Content Blocks Text, Callouts, Cards, Accordions, Quotes, Badges, Metrics, Value Boxes, Code, Images, Videos, iframes, HTML add_text(), add_callout(), add_card(), add_accordion(), add_quote(), add_badge(), add_metric(), add_value_box(), add_code(), add_image(), add_html()
Tables & Custom Charts gt Tables, Reactable, DT DataTables, Basic Tables, Custom Highcharter Charts add_gt(), add_reactable(), add_DT(), add_table(), add_hc()
Interactive Inputs (see Advanced Features) Dropdowns, Checkboxes, Sliders, Radio buttons add_input_row(), add_input()
Layout Helpers Dividers, Spacers, Pagination markers add_divider(), add_spacer(), add_pagination()
Everything is stored in a unified `items` list, and you can inspect it anytime: ```{r} content <- create_content(data = gss, type = "bar") %>% add_viz(x_var = "degree", title = "Education") %>% add_text("## Analysis", "", "Key findings:") %>% add_callout(paste0("Sample size: ", nrow(gss)), type = "note") print(content) ``` ```{r} preview(content) ``` ## ⚙️ The Defaults System The defaults system lets you **set once, use many times**. Instead of repeating the same parameters for every visualization, you define them once in `create_content()` and they automatically apply to all `add_viz()` calls. ### Why Use Defaults? Without defaults, you'd need to repeat parameters for every chart: ```r # Repetitive - don't do this! content %>% add_viz(x_var = "age", type = "bar", color_palette = c("#3498DB"), bar_type = "percent") %>% add_viz(x_var = "sex", type = "bar", color_palette = c("#3498DB"), bar_type = "percent") %>% add_viz(x_var = "race", type = "bar", color_palette = c("#3498DB"), bar_type = "percent") ``` With defaults, you set them once and they flow through: ```r # Clean - do this! create_content(data = gss, type = "bar", color_palette = c("#3498DB"), bar_type = "percent") %>% add_viz(x_var = "age") %>% add_viz(x_var = "sex") %>% add_viz(x_var = "race") ``` ### Override Hierarchy Parameters are resolved in this order (later wins): 1. **Collection defaults** - set in `create_content()` 2. **Individual viz settings** - set in `add_viz()` This means you can set sensible defaults for most charts, then override specific ones as needed: ```{r} # Default: horizontal percent bars in blue content <- create_content( data = gss, type = "bar", bar_type = "percent", horizontal = TRUE, color_palette = c("#3498DB") ) %>% # Uses all defaults add_viz(x_var = "degree", title = "Education") %>% # Override: vertical instead of horizontal add_viz(x_var = "race", title = "Race (vertical)", horizontal = FALSE) %>% # Override: count instead of percent add_viz(x_var = "sex", title = "Sex (count)", bar_type = "count") print(content) ``` ```{r} content %>% preview() ``` ### Any Parameter Can Be a Default **Any parameter** you can pass to `add_viz()` can be set as a default in `create_content()`. Common ones include: | Parameter | Description | Example Values | |-----------|-------------|----------------| | `type` | Visualization type | `"bar"`, `"histogram"`, `"stackedbar"`, `"timeline"` | | `color_palette` | Colors for charts | `c("#3498DB", "#E74C3C")` | | `bar_type` | Bar chart display | `"count"`, `"percent"`, `"mean"` | | `horizontal` | Flip chart orientation | `TRUE`, `FALSE` | | `weight_var` | Survey weight column | `"wtssps"` | | `drop_na_vars` | Remove NA values | `TRUE`, `FALSE` | | `stacked_type` | Stacked bar display | `"count"`, `"percent"` | | `bins` | Histogram bins | `20`, `30`, `50` | | `x_label` | Custom x-axis label | `"Age (years)"` | | `y_label` | Custom y-axis label | `"Number of Respondents"` | | `tooltip_suffix` | Text after tooltip values | `"%"`, `" people"` | | `error_bars` | Error bar type (for `bar_type = "mean"`) | `"none"`, `"sd"`, `"se"`, `"ci"` | | `value_var` | Numeric variable for means | `"score"`, `"income"` | See the [Visualization Types](#visualization-types) section for all parameters available for each chart type. ## 🏷️ Custom Labels and Tooltips Every visualization supports custom axis labels and tooltip formatting. These help make your charts clearer and more professional. ### Axis Labels By default, `dashboardr` uses your variable names as axis labels. Override them with `x_label` and `y_label`: ```{r} # Without custom labels (uses variable names) create_content(data = gss, type = "bar") %>% add_viz(x_var = "degree", title = "Education Levels") %>% preview() ``` ```{r} # With custom labels (more polished) create_content(data = gss, type = "bar") %>% add_viz( x_var = "degree", title = "Education Levels", x_label = "Highest Degree Earned", y_label = "Number of Respondents" ) %>% preview() ``` For stacked charts, you can also set `stack_label` to customize the legend title: ```{r} create_content(data = gss, type = "stackedbar") %>% add_viz( x_var = "degree", stack_var = "sex", title = "Education by Gender", x_label = "Highest Degree", y_label = "Count", stack_label = "Gender" ) %>% preview() ``` ### Tooltip Customization Tooltips are the interactive popups that appear when users hover over data points. Customize them with prefix and suffix options: | Parameter | Description | Example | |-----------|-------------|---------| | `tooltip_prefix` | Text before the value | `"Count: "`, `"$"` | | `tooltip_suffix` | Text after the value | `"%"`, `" respondents"` | | `x_tooltip_suffix` | Text after x-axis value | `" years"`, `" USD"` | ```{r} # Add units to tooltips create_content(data = gss, type = "histogram") %>% add_viz( x_var = "age", title = "Age Distribution", x_label = "Age", y_label = "Count", tooltip_suffix = " respondents", x_tooltip_suffix = " years old" ) %>% preview() ``` ```{r} # Percentage tooltips for stacked bars create_content(data = gss, type = "stackedbar") %>% add_viz( x_var = "happy", stack_var = "sex", title = "Happiness by Gender", stacked_type = "percent", y_label = "Percentage", tooltip_suffix = "%" ) %>% preview() ``` ## ➕ Combining Collections ### The + Operator Merge collections while preserving structure: ```{r} demographics <- create_content(data = gss, type = "bar") %>% add_viz(x_var = "degree", title = "Education", tabgroup = "Demo") attitudes <- create_content(data = gss, type = "bar") %>% add_viz(x_var = "happy", title = "Happiness", tabgroup = "Attitudes") combined <- demographics + attitudes print(combined) ``` ### combine_viz() Same as `+` but in pipe-friendly form: ```{r} all_content <- demographics %>% combine_viz(attitudes) print(all_content) ``` ## 📊 Visualization Types {#visualization-types} dashboardr supports 11 visualization types. Each is optimized for different data patterns. For detailed documentation on each type, see the individual vignettes: - [Bar Charts](bar_vignette.html) | [Stacked Bars](stackedbar_vignette.html) - [Histograms](histogram_vignette.html) | [Density Plots](density_vignette.html) | [Box Plots](boxplot_vignette.html) - [Timelines](timeline_vignette.html) | [Heatmaps](heatmap_vignette.html) | [Scatter Plots](scatter_vignette.html) - [Treemaps](treemap_vignette.html) | [Maps](map_vignette.html) ### Bar Charts Bar charts are the workhorse of categorical data. Use them when you want to compare counts or proportions across categories. The simplest bar chart counts occurrences of each category: ```{r} create_content(data = gss, type = "bar") %>% add_viz(x_var = "degree", title = "Education Levels") %>% preview() ``` Often you'll want percentages instead of raw counts. Set `bar_type = "percent"` to show proportions that sum to 100%: ```{r} create_content(data = gss, type = "bar") %>% add_viz(x_var = "race", title = "Race Distribution", bar_type = "percent") %>% preview() ``` To compare categories across groups, add `group_var`. This creates side-by-side bars: ```{r} create_content(data = gss, type = "bar") %>% add_viz(x_var = "degree", group_var = "sex", title = "Education by Sex") %>% preview() ``` For long category labels, flip to horizontal with `horizontal = TRUE`: ```{r} create_content(data = gss, type = "bar") %>% add_viz(x_var = "degree", title = "Education (Horizontal)", horizontal = TRUE) %>% preview() ``` #### Means with Error Bars For numeric outcomes, use `bar_type = "mean"` with `error_bars` to show statistical uncertainty: ```{r} # Sample data with numeric scores score_data <- data.frame( group = rep(c("Control", "Treatment"), each = 50), score = c(rnorm(50, 70, 10), rnorm(50, 78, 12)) ) create_content(data = score_data, type = "bar") %>% add_viz( x_var = "group", value_var = "score", bar_type = "mean", error_bars = "ci", # "sd", "se", or "ci" title = "Mean Scores (95% CI)" ) %>% preview() ``` | Error Type | Parameter | Shows | |------------|-----------|-------| | Standard Deviation | `error_bars = "sd"` | Spread of individual values | | Standard Error | `error_bars = "se"` | Precision of mean estimate | | Confidence Interval | `error_bars = "ci"` | Range likely to contain true mean | See the [Bar Chart vignette](bar_vignette.html) for more options including grouped means and error bar styling. ### Stacked Bars Stacked bars show composition - how a whole breaks down into parts. Use `stack_var` to specify what fills each bar. This shows the happiness distribution within each education level as raw counts: ```{r} create_content(data = gss, type = "stackedbar") %>% add_viz(x_var = "degree", stack_var = "happy", title = "Happiness by Education") %>% preview() ``` For easier comparison across groups of different sizes, use `stacked_type = "percent"`. Now each bar sums to 100%, making patterns clearer: ```{r} create_content(data = gss, type = "stackedbar") %>% add_viz(x_var = "degree", stack_var = "happy", title = "Happiness by Education (%)", stacked_type = "percent") %>% preview() ``` Horizontal stacked bars work well when you have many categories or long labels: ```{r} create_content(data = gss, type = "stackedbar") %>% add_viz(x_var = "degree", stack_var = "happy", title = "Horizontal Stacked", stacked_type = "percent", horizontal = TRUE) %>% preview() ``` See the [Stacked Bar vignette](stackedbar_vignette.html) for more options. ### Histograms Histograms show the distribution of continuous variables. The `bins` parameter controls granularity - more bins show more detail, fewer bins show smoother patterns. ```{r} create_content(data = gss, type = "histogram") %>% add_viz(x_var = "age", title = "Age Distribution", bins = 25, x_label = "Age (years)", y_label = "Frequency") %>% preview() ``` See the [Histogram vignette](histogram_vignette.html) for more options. ### Density Plots Density plots show smooth estimates of the distribution of a continuous variable. They're useful when you want a cleaner view of the distribution shape compared to histograms. ```{r} create_content(data = gss, type = "density") %>% add_viz(x_var = "age", title = "Age Distribution (Density)", x_label = "Age (years)") %>% preview() ``` Add `group_var` to compare distributions across groups: ```{r} create_content(data = gss, type = "density") %>% add_viz(x_var = "age", group_var = "sex", title = "Age Distribution by Sex") %>% preview() ``` See the [Density vignette](density_vignette.html) for more options. ### Box Plots Box plots (also called box-and-whisker plots) show the distribution of a numeric variable across categories. They display the median, quartiles, and outliers, making it easy to compare distributions. ```{r} create_content(data = gss, type = "boxplot") %>% add_viz(x_var = "degree", y_var = "age", title = "Age Distribution by Education Level", x_label = "Highest Degree", y_label = "Age") %>% preview() ``` See the [Box Plot vignette](boxplot_vignette.html) for more options. ### Multiple Stacked Bars (Likert Scales) When you have multiple survey questions with the same response scale (like Likert items), use `type = "stackedbar"` with `x_vars` to display them together for comparison. This is perfect for "confidence in institutions" batteries or agreement scales. Use `x_vars` for the question columns and `x_var_labels` for readable labels. Note: These confidence questions use a split-ballot design, so ~1/3 of respondents have NA (question not asked). We use `drop_na_vars = TRUE` to exclude those: ```{r} create_content(data = gss, type = "stackedbar", drop_na_vars = TRUE) %>% add_viz( x_vars = c("confinan", "conbus", "coneduc", "confed", "conmedic"), x_var_labels = c("Banks & financial institutions", "Major companies", "Education", "Federal government", "Medicine"), title = "Confidence in Institutions", stacked_type = "percent", horizontal = TRUE ) %>% preview() ``` See the [Stacked Bar vignette](stackedbar_vignette.html) for more options including multi-question mode. ### Timeline Timeline charts track how responses change over time. You need a time variable (`time_var`) and a response variable (`y_var`). Unlike other chart types, timelines need data spanning multiple time periods. ```{r} create_content(data = gss_timeline, type = "timeline") %>% add_viz( time_var = "year", y_var = "happy", title = "Happiness Over Time", chart_type = "line" ) %>% preview() ``` Use `chart_type = "stacked_area"` for a stacked area chart, which emphasizes cumulative patterns: ```{r} create_content(data = gss_timeline, type = "timeline") %>% add_viz( time_var = "year", y_var = "happy", title = "Happiness Trends (Stacked Area)", chart_type = "stacked_area" ) %>% preview() ``` See the [Timeline vignette](timeline_vignette.html) for more options. ### Heatmap Heatmaps visualize how a numeric value varies across two categorical dimensions, displayed as a color-coded grid. Each cell shows the aggregated value for that combination of categories. **Required parameters:** | Parameter | Description | |-----------|-------------| | `x_var` | Categorical variable for columns | | `y_var` | Categorical variable for rows | | `value_var` | Numeric variable to aggregate and color by | **How it works:** The heatmap automatically aggregates `value_var` for each unique combination of `x_var` and `y_var`. **By default, it calculates the mean** - so if you have 50 people with a bachelor's degree who are "very happy", the cell shows their average age. You can change this with `agg_fun` (e.g., `agg_fun = median` for medians). ```{r} create_content(data = gss, type = "heatmap") %>% add_viz( x_var = "degree", y_var = "happy", value_var = "age", title = "Average Age by Education & Happiness", color_palette = c("#FFF5F0", "#67000D"), label_decimals = 0, weight_var = "wtssps" ) %>% preview() ``` **Key optional parameters:** | Parameter | Description | Default | |-----------|-------------|---------| | `agg_fun` | Aggregation function (e.g., `mean`, `median`, `sum`) | `mean` | | `label_decimals` | Decimal places for cell labels and tooltips | `1` | | `color_palette` | Two colors for gradient (low, high) | `c("#FFFFFF", "#7CB5EC")` | | `color_min` / `color_max` | Fixed color scale bounds | Auto from data | | `x_order` / `y_order` | Custom category ordering | Auto | | `data_labels_enabled` | Show values in cells | `TRUE` | | `weight_var` | Column for weighted aggregation | `NULL` | See the [Heatmap vignette](heatmap_vignette.html) for more options. ### Scatter Plots Scatter plots show relationships between two numeric variables. Each point represents one observation. Key parameters: - `x_var` - Variable for horizontal axis - `y_var` - Variable for vertical axis - `color_var` - Optional grouping variable for colored points - `size_var` - Optional variable to control point sizes - `show_trend` - Add a trend line (`TRUE`/`FALSE`) - `alpha` - Point transparency (0-1) ```{r} # Filter to respondents with valid education and children data scatter_data <- gss %>% filter(!is.na(educ), !is.na(childs)) create_content(data = scatter_data, type = "scatter") %>% add_viz( x_var = "educ", y_var = "childs", color_var = "sex", title = "Education vs Number of Children", x_label = "Years of Education", y_label = "Number of Children", alpha = 0.4 ) %>% preview() ``` See the [Scatter Plot vignette](scatter_vignette.html) for more options. ### Treemap Treemaps display hierarchical data as nested rectangles. The size of each rectangle represents its value - larger rectangles mean larger values. Great for showing composition and proportions across many categories. **Important**: Treemaps require pre-aggregated data with a value column. You typically need to `count()` or `summarize()` your data first. Key parameters: - `group_var` - Primary grouping variable (creates the rectangles) - `subgroup_var` - Optional secondary grouping for hierarchical treemaps - `value_var` - Numeric column that determines rectangle size - `color_var` - Optional variable for coloring (defaults to group_var) ```{r} # Treemaps need pre-aggregated data degree_counts <- gss %>% count(degree, name = "n") create_content(data = degree_counts, type = "treemap") %>% add_viz( group_var = "degree", value_var = "n", title = "Education Distribution" ) %>% preview() ``` For hierarchical treemaps, add `subgroup_var`: ```{r} # Two-level hierarchy: degree within sex degree_sex_counts <- gss %>% count(sex, degree, name = "n") create_content(data = degree_sex_counts, type = "treemap") %>% add_viz( group_var = "sex", subgroup_var = "degree", value_var = "n", title = "Education by Sex" ) %>% preview() ``` See the [Treemap vignette](treemap_vignette.html) for more options. ### Map Geographic maps (choropleths) display data across regions using color intensity. Each region is shaded based on a numeric value, making it easy to see geographic patterns at a glance. **Key parameters:** | Parameter | Description | |-----------|-------------| | `value_var` | Numeric column for color intensity | | `join_var` | Column with geographic codes (must match map's internal codes) | | `map_type` | Map geography: `"custom/world"`, `"countries/us/us-all"`, etc. | | `color_palette` | Two colors for gradient (low, high) | | `tooltip_vars` | Variables to show in hover tooltips | **Important**: Maps require geographic identifier codes that match the map's internal region codes: - **World maps**: Use 2-letter ISO country codes (`iso2c`): "US", "DE", "FR", etc. - **US state maps**: Use postal codes: "CA", "NY", "TX", etc. ```{r} # Load gapminder data and add ISO country codes library(gapminder) library(countrycode) # Get latest year and convert country names to ISO codes map_data <- gapminder %>% filter(year == max(year)) %>% mutate(iso2c = countrycode(country, "country.name", "iso2c")) %>% filter(!is.na(iso2c)) ``` Now create a world map showing life expectancy: ```{r} create_content(data = map_data, type = "map") %>% add_viz( value_var = "lifeExp", join_var = "iso2c", map_type = "custom/world", title = "Life Expectancy by Country (2007)", color_palette = c("#fee5d9", "#a50f15") ) %>% preview() ``` **Available map types:** | Map Type | Region | Join Key | |----------|--------|----------| | `"custom/world"` | World countries | `iso2c` (2-letter ISO) | | `"custom/world-highres"` | World (high resolution) | `iso2c` | | `"countries/us/us-all"` | US states | Postal codes ("CA", "NY") | | `"countries/de/de-all"` | German states | State codes | | `"custom/europe"` | European countries | `iso2c` | See the [Map vignette](map_vignette.html) for more options. ## 📁 Organizing with Tabgroups Tabgroups create tabbed interfaces in your dashboard: ```{r} content <- create_content(data = gss, type = "bar") %>% add_viz(x_var = "degree", title = "Education", tabgroup = "demographics") %>% add_viz(x_var = "race", title = "Race", tabgroup = "demographics") %>% add_viz(x_var = "happy", title = "Happiness", tabgroup = "attitudes") %>% add_viz(x_var = "polviews", title = "Politics", tabgroup = "attitudes") print(content) ``` ### Nested Tabgroups For complex dashboards, you can create **multi-level tab hierarchies** using `/` as a separator: ```{r} nested <- create_content(data = gss, type = "bar") %>% # Top-level: "Demographics" with two sub-tabs add_viz(x_var = "degree", title = "Education Level", tabgroup = "Demographics/Education") %>% add_viz(x_var = "race", title = "Race Distribution", tabgroup = "Demographics/Race") %>% add_viz(x_var = "age", title = "Age Distribution", tabgroup = "Demographics/Age") %>% # Top-level: "Attitudes" with sub-tabs add_viz(x_var = "happy", title = "General Happiness", tabgroup = "Attitudes/Wellbeing") %>% add_viz(x_var = "polviews", title = "Political Views", tabgroup = "Attitudes/Politics") print(nested) ``` ```{r} preview(nested) ``` ### Custom Tab Labels Replace tabgroup IDs with readable labels using `set_tabgroup_labels()`: ```{r} labeled <- create_content(data = gss, type = "bar") %>% add_viz(x_var = "degree", title = "Education", tabgroup = "demo") %>% add_viz(x_var = "happy", title = "Happiness", tabgroup = "attitudes") %>% set_tabgroup_labels( demo = "Demographics", attitudes = "Attitudes & Values" ) print(labeled) ``` ```{r} labeled %>% preview() ``` ## 📝 Content Blocks Content blocks add non-visualization elements to your collections. ### Text Blocks `add_text()` is a flexible function for adding markdown content. It has several smart features: **Multiple arguments become lines** - Pass as many strings as you want, and they join with newlines: ```{r} create_content() %>% add_text( "## Survey Overview", "", "The General Social Survey (GSS) has been conducted since 1972.", "It covers demographics, attitudes, and social behaviors." ) %>% preview() ``` **Use empty strings for spacing** - An empty `""` creates a paragraph break: ```{r} create_content() %>% add_text( "## Section One", "", "First paragraph of content.", "", "## Section Two", "", "Second paragraph with a gap above." ) %>% preview() ``` **Full Markdown support** - Headers, lists, bold, italic, links, and more: ```{r} text_example <- create_content() %>% add_text( "## Key Findings", "", "This analysis reveals **three important patterns**:", "", "1. Education correlates with happiness", "2. Age distribution is *roughly normal*", "3. Political views show [polarization](https://en.wikipedia.org/wiki/Political_polarization)", "", "### Methodology Note", "", "> Data weighted using GSS survey weights" ) print(text_example) ``` ```{r} text_example %>% preview() ``` **Works standalone or in pipes** - Call it directly or chain it: ```r # Standalone - returns a content block block <- add_text("# Title") # In a pipe - adds to existing collection content %>% add_text("More content here") ``` ### Callouts Callouts draw attention to specific information with colored boxes and icons. Use them to highlight notes, tips, warnings, or critical information that readers shouldn't miss. **Five types for different purposes:** | Type | Use for | Color | |------|---------|-------| | `note` | Additional context, background info | Blue | | `tip` | Helpful suggestions, best practices | Green | | `warning` | Potential issues, things to watch out for | Yellow | | `caution` | Proceed carefully, possible problems | Orange | | `important` | Critical information, must-read | Red | ```{r} callout_gallery <- create_content() %>% add_callout("Notes provide additional context or information.", type = "note", title = "Note") %>% add_callout("Tips offer helpful suggestions to improve workflow.", type = "tip", title = "Pro Tip") %>% add_callout("Warnings alert users to potential issues.", type = "warning", title = "Warning") %>% add_callout("Caution indicates something that needs careful attention.", type = "caution", title = "Caution") %>% add_callout("Important highlights critical information.", type = "important", title = "Important") print(callout_gallery) ``` ```{r} callout_gallery %>% preview() ``` **Custom titles are optional** - If you omit `title`, the type name is used: ```{r} create_content() %>% add_callout("Sample size is smaller than recommended for this analysis.", type = "warning") %>% preview() ``` **Practical example** - Combine callouts with visualizations: ```{r} create_content(data = gss, type = "bar") %>% add_callout("This chart shows unweighted counts. See methodology for weighted estimates.", type = "note") %>% add_viz(x_var = "degree", title = "Education Distribution") %>% add_callout("Education data may reflect selection bias in survey response rates.", type = "tip", title = "Interpretation Tip") %>% preview() ``` ### Cards Styled content containers with optional titles: ```{r} card_example <- create_content() %>% add_card( title = "Key Finding", text = "Education level shows a strong positive correlation with reported happiness levels across all demographic groups." ) %>% add_card( text = "Cards without titles work too. Great for quick content blocks." ) print(card_example) ``` ```{r} card_example %>% preview() ``` ### Accordions Collapsible sections for supplementary or detailed content: ```{r} accordion_example <- create_content() %>% add_accordion( title = "Click to expand: Methodology", text = "This analysis uses weighted survey data from NORC. Sample size: 21,788 respondents." ) %>% add_accordion( title = "Click to expand: Data Sources", text = "General Social Survey (GSS), collected annually since 1972." ) print(accordion_example) ``` ```{r} accordion_example %>% preview() ``` ### Quotes Block quotes with optional attribution: ```{r} quote_example <- create_content() %>% add_quote( quote = "The only true wisdom is in knowing you know nothing.", attribution = "Socrates" ) print(quote_example) ``` ```{r} quote_example %>% preview() ``` ### Badges Inline status indicators: ```{r} badge_example <- create_content() %>% add_text("Status indicators:") %>% add_badge("Complete", color = "success") %>% add_badge("In Progress", color = "warning") %>% add_badge("Not Started", color = "danger") %>% add_badge("Info", color = "info") %>% add_badge("Primary", color = "primary") %>% add_badge("Secondary", color = "secondary") print(badge_example) ``` ```{r} badge_example %>% preview() ``` ### Metrics Single KPI value boxes: ```{r} metric_example <- create_content() %>% add_metric( title = "Total Respondents", value = "21,788", icon = "ph:users" ) print(metric_example) ``` ```{r} metric_example %>% preview() ``` ### Value Boxes Custom-styled value boxes with branding: ```{r} value_box_example <- create_content() %>% add_value_box( title = "Revenue", value = "$1.2M", bg_color = "#27AE60" ) print(value_box_example) ``` ```{r} value_box_example %>% preview() ``` ### Value Box Rows Multiple value boxes in a responsive row: ```{r} value_row_example <- create_content() %>% add_value_box_row() %>% add_value_box(title = "Users", value = "12,345", bg_color = "#3498DB") %>% add_value_box(title = "Sessions", value = "45,678", bg_color = "#9B59B6") %>% add_value_box(title = "Conversion", value = "3.2%", bg_color = "#E74C3C") %>% end_value_box_row() print(value_row_example) ``` ```{r} value_row_example %>% preview() ``` ### Code Blocks Syntax-highlighted code snippets: ```{r} code_example <- create_content() %>% add_code( code = "library(dashboardr)\n\ncreate_content(data = df) %>%\n add_viz(type = 'bar', x_var = 'category')", language = "r" ) print(code_example) ``` ```{r} code_example %>% preview() ``` ### Images Add images with optional captions. **Use full URLs** for images to ensure they display on GitHub Pages: ```{r} image_example <- create_content() %>% add_image( src = "https://favstats.github.io/dashboardr/reference/figures/logo.svg", alt = "dashboardr Logo", caption = "The dashboardr package logo", width = "200px" ) print(image_example) image_example %>% preview() ``` > **Tip**: Always use absolute URLs (starting with `https://`) for images in vignettes. Local file paths like `"logo.png"` work during development but won't display on GitHub Pages or pkgdown sites. ### Videos For local video files, use `add_video()` - but note these won't work on GitHub Pages unless hosted elsewhere: ```{r, eval=FALSE} # Local video (works locally, not on GitHub) create_content() %>% add_video( src = "presentation.mp4", caption = "Project overview video" ) ``` For video content, use YouTube or Vimeo embeds via `add_iframe()` - this is more reliable than direct video files: ```{r} # YouTube embed (recommended approach) video_example <- create_content() %>% add_iframe( src = "https://www.youtube.com/embed/dQw4w9WgXcQ", height = "315px" ) print(video_example) video_example %>% preview() ``` ### iframes Embed external content like interactive maps, dashboards, or other web pages: ```{r} iframe_example <- create_content() %>% add_iframe( src = "https://www.openstreetmap.org/export/embed.html?bbox=-0.1%2C51.5%2C0.0%2C51.52", height = "300px" ) print(iframe_example) iframe_example %>% preview() ``` ### Raw HTML Insert custom HTML when needed: ```{r} html_example <- create_content() %>% add_html('

Custom HTML Block

Style anything with raw HTML!

') print(html_example) ``` ```{r} html_example %>% preview() ``` ## 📊 Tables and Custom Charts Beyond visualizations created with `add_viz()`, you can embed tables and custom charts directly into content collections. ### gt Tables Use `add_gt()` to embed publication-quality tables created with the [gt package](https://gt.rstudio.com/): ```{r, warning = FALSE} # Create a summary table summary_data <- gss %>% group_by(degree) %>% summarise( n = n(), mean_age = round(mean(age, na.rm = TRUE), 1), .groups = "drop" ) gt_example <- create_content() %>% add_text("### Summary Statistics by Education") %>% add_gt( gt::gt(summary_data) %>% gt::cols_label(degree = "Education", n = "Count", mean_age = "Mean Age") ) print(gt_example) ``` ```{r, warning = FALSE} gt_example %>% preview() ``` You can also pass a data frame directly - it will be converted to a gt table automatically: ```{r, warning = FALSE} simple_gt <- create_content() %>% add_gt(head(summary_data, 3), caption = "Top 3 Education Levels") simple_gt %>% preview() ``` ### Reactable Tables For interactive tables with sorting and filtering, use `add_reactable()`: ```{r} reactable_example <- create_content() %>% add_text("### Interactive Summary Table") %>% add_reactable( reactable::reactable(summary_data, searchable = TRUE, striped = TRUE) ) print(reactable_example) ``` ```{r} reactable_example %>% preview() ``` ### DT DataTables For feature-rich interactive tables, use `add_DT()`: ```{r} dt_example <- create_content() %>% add_text("### DataTable with Search and Pagination") %>% add_DT(summary_data, options = list(pageLength = 5)) print(dt_example) ``` ```{r} dt_example %>% preview() ``` ### Basic Tables For simple tables without dependencies, use `add_table()`: ```{r} table_example <- create_content() %>% add_table(head(summary_data, 3), caption = "Sample Data") print(table_example) ``` ```{r} table_example %>% preview() ``` ### Custom Highcharter Charts When you need a visualization that goes beyond what `add_viz()` offers, use `add_hc()` to embed any [highcharter](https://jkunst.com/highcharter/) chart: ```{r} library(highcharter) # Create a custom chart custom_chart <- highchart() %>% hc_chart(type = "pie") %>% hc_title(text = "Education Distribution") %>% hc_add_series( name = "Count", data = list( list(name = "Less than HS", y = sum(gss$degree == "less than high school")), list(name = "High School", y = sum(gss$degree == "high school")), list(name = "Junior College", y = sum(gss$degree == "junior college")), list(name = "Bachelor", y = sum(gss$degree == "bachelor")), list(name = "Graduate", y = sum(gss$degree == "graduate")) ) ) hc_example <- create_content() %>% add_text("### Custom Pie Chart") %>% add_hc(custom_chart) print(hc_example) ``` ```{r} hc_example %>% preview() ``` This is useful for: - Chart types not available in `add_viz()` (pie charts, gauges, etc.) - Highly customized visualizations - Integrating existing highcharter code ## 📈 Working with Pre-aggregated Data While dashboardr was designed with survey data in mind (where you typically count or aggregate responses), it works equally well with data that's already aggregated. ### Bar Charts with Pre-aggregated Data Use the `y_var` parameter to specify a column containing pre-computed values: ```{r} # Pre-aggregated data (e.g., from a database or API) country_stats <- data.frame( country = c("USA", "Germany", "France", "UK", "Japan"), population_millions = c(331, 83, 67, 67, 126), gdp_trillions = c(21.4, 3.8, 2.6, 2.8, 5.1) ) # Use y_var to plot pre-aggregated values directly preagg_bar <- create_content(data = country_stats) %>% add_viz( type = "bar", x_var = "country", y_var = "population_millions", # Pre-computed values title = "Population by Country (Millions)", x_order = c("USA", "Japan", "Germany", "UK", "France") ) preagg_bar %>% preview() ``` This also works for grouped bar charts: ```{r} # Pre-aggregated grouped data quarterly_sales <- data.frame( quarter = rep(c("Q1", "Q2", "Q3", "Q4"), each = 2), region = rep(c("North", "South"), 4), revenue = c(100, 80, 120, 95, 150, 110, 130, 100) ) grouped_preagg <- create_content(data = quarterly_sales) %>% add_viz( type = "bar", x_var = "quarter", group_var = "region", y_var = "revenue", title = "Quarterly Revenue by Region" ) grouped_preagg %>% preview() ``` ### Stacked Bars with Pre-aggregated Data The `y_var` parameter works the same way for stacked bar charts: ```{r} # Pre-aggregated stacked data satisfaction_data <- data.frame( department = rep(c("Sales", "Engineering", "HR"), each = 3), rating = rep(c("Satisfied", "Neutral", "Dissatisfied"), 3), count = c(45, 30, 10, 60, 25, 15, 35, 20, 5) ) stacked_preagg <- create_content(data = satisfaction_data) %>% add_viz( type = "stackedbar", x_var = "department", stack_var = "rating", y_var = "count", # Pre-computed counts title = "Employee Satisfaction by Department" ) stacked_preagg %>% preview() ``` ### Histograms with Pre-aggregated Data For pre-binned histogram data: ```{r} # Pre-binned data (e.g., from a reporting system) age_bins <- data.frame( age_group = c("18-25", "26-35", "36-45", "46-55", "56-65", "65+"), count = c(150, 280, 320, 290, 210, 180) ) hist_preagg <- create_content(data = age_bins) %>% add_viz( type = "histogram", x_var = "age_group", y_var = "count", # Pre-computed bin counts title = "Age Distribution" ) hist_preagg %>% preview() ``` ### Timelines with Pre-aggregated Data Use `agg = "none"` to skip aggregation for timeline data: ```{r} # Pre-aggregated time series yearly_metrics <- data.frame( year = c(2020, 2021, 2022, 2023), value = c(1250, 1380, 1420, 1510) ) timeline_preagg <- create_content(data = yearly_metrics) %>% add_viz( type = "timeline", time_var = "year", y_var = "value", agg = "none", # Use values directly, no aggregation title = "Yearly Performance Trend" ) timeline_preagg %>% preview() ``` ### Heatmaps with Pre-aggregated Data Use `pre_aggregated = TRUE` to skip the aggregation step: ```{r} # Pre-computed heatmap values (one row per cell) correlation_data <- data.frame( var1 = rep(c("Age", "Income", "Education"), each = 3), var2 = rep(c("Age", "Income", "Education"), 3), correlation = c(1.0, 0.35, 0.28, 0.35, 1.0, 0.52, 0.28, 0.52, 1.0) ) heatmap_preagg <- create_content(data = correlation_data) %>% add_viz( type = "heatmap", x_var = "var1", y_var = "var2", value_var = "correlation", pre_aggregated = TRUE, # Skip aggregation title = "Correlation Matrix", color_min = -1, color_max = 1 ) heatmap_preagg %>% preview() ``` ### Treemaps with Pre-aggregated Data Use `pre_aggregated = TRUE` to use values directly without summing: ```{r} # Pre-aggregated hierarchical data budget_data <- data.frame( category = c("Marketing", "Marketing", "Engineering", "Engineering", "Operations"), subcategory = c("Digital", "Events", "Frontend", "Backend", "Support"), amount = c(50000, 30000, 80000, 120000, 45000) ) treemap_preagg <- create_content(data = budget_data) %>% add_viz( type = "treemap", group_var = "category", subgroup_var = "subcategory", value_var = "amount", pre_aggregated = TRUE, # Use amounts directly title = "Budget Allocation" ) treemap_preagg %>% preview() ``` ## 🔲 Layout Helpers ### Dividers Visual separators between content sections: ```{r} divider_content <- create_content() %>% add_text("## Section One", "", "Content for the first section.") %>% add_divider() %>% add_text("## Section Two", "", "Content for the second section.") print(divider_content) ``` ```{r} divider_content %>% preview() ``` ### Spacers Add vertical spacing between elements: ```{r} spacer_example <- create_content() %>% add_text("Content above") %>% add_spacer(height = "3rem") %>% add_text("Content below (after 3rem spacer)") print(spacer_example) ``` ```{r} spacer_example %>% preview() ``` ## 👁️ Previewing Content Use `preview()` to quickly check your visualizations and content blocks during development. It automatically validates your visualization specs and catches errors like missing parameters or invalid column names before rendering: ```{r, eval=FALSE} # Quick preview (fast, no Quarto) content %>% preview() # Full Quarto preview (slower, full features) content %>% preview(quarto = TRUE) # Save to specific location content %>% preview(path = "my_preview.html") ``` ### Limitations of Preview > **Important:** `preview()` is a simplified rendering for quick checks during development. It does **not** show the final dashboard appearance. **What preview shows well:** - Individual visualizations and their data - Basic tabgroup organization - Content blocks (text, callouts, cards, etc.) - Simple nested tabs **What preview does NOT support:** - Full dashboard navigation and layout - Interactive inputs (dropdowns, sliders, checkboxes) - Complex multi-page structures - Dashboard theming and styling - Sidebar navigation - Mobile responsiveness **For a real view of your dashboard**, you must run `generate_dashboard()` and open the resulting Quarto site: ```r dashboard <- create_dashboard("My Dashboard") %>% add_page(my_page) # Generate the full dashboard generate_dashboard(dashboard) # Then open _site/index.html in your browser ``` Think of `preview()` as a "sanity check" for your charts and content, not a representation of the final product. ## ➡️ Next Steps Once you have content, add it to a page: ```r create_page("Analysis", data = gss) %>% add_content(demographics) %>% add_content(attitudes) ``` See `vignette("pages")` for page creation details.