diff --git a/NAMESPACE b/NAMESPACE index 8499006..c93a915 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,19 +1,6 @@ # Generated by roxygen2: do not edit by hand -export(ro_ply_add_theme) -export(ro_ply_cursor) -export(ro_ply_dim) -export(ro_ply_disable_toolbar) -export(ro_ply_focus_linechart) -export(ro_ply_keyboard_nav_barchart) -export(ro_ply_keyboard_nav_bargraph) -export(ro_ply_keyboard_nav_legend) -export(ro_ply_keyboard_nav_linechart) -export(ro_ply_keyboard_nav_trendline) -export(ro_ply_legend_theme) export(ro_ply_standard) -export(ro_ply_theme) -export(ro_ply_title) import(rlang) importFrom(ROvis.utils, ro_check_if_font_available, diff --git a/R/ro_ply_add_theme.R b/R/ro_ply_add_theme.R index 2690bb0..fd4a2a8 100644 --- a/R/ro_ply_add_theme.R +++ b/R/ro_ply_add_theme.R @@ -4,7 +4,6 @@ #' #' @param fig A Plotly figure object created by \code{plotly::plot_ly()} or similar. #' @param theme A named list of layout parameters to apply as a theme (e.g., font, colors, margins). -#' @export #' @family plotly #' @return A Plotly figure object with the specified theme applied. #' diff --git a/R/ro_ply_cursor.R b/R/ro_ply_cursor.R index c73f023..e64c8e3 100644 --- a/R/ro_ply_cursor.R +++ b/R/ro_ply_cursor.R @@ -5,7 +5,6 @@ #' @param fig A Plotly figure object created by \code{plotly::plot_ly()} or similar. #' #' @return A Plotly figure object with the cursor style set to "default" (arrow). -#' @export #' @family plotly #' @family ggplotly #' @examples diff --git a/R/ro_ply_dim.R b/R/ro_ply_dim.R index 98e8650..67ef3b9 100644 --- a/R/ro_ply_dim.R +++ b/R/ro_ply_dim.R @@ -8,7 +8,6 @@ #' @param height Desired plot height in pixels. Default is 400. #' #' @return A Plotly figure object with updated sizing policy and layout. -#' @export #' @family plotly #' @examples #' \dontrun{ diff --git a/R/ro_ply_disable_toolbar.R b/R/ro_ply_disable_toolbar.R index bfc8af4..ab348e6 100644 --- a/R/ro_ply_disable_toolbar.R +++ b/R/ro_ply_disable_toolbar.R @@ -10,7 +10,6 @@ #' #' @return A \code{plotly} object without the modebar and with improved legend accessibility. #' -#' @export #' @family ggplotly #' @family plotly #' @examples diff --git a/R/ro_ply_focus_linechart.R b/R/ro_ply_focus_linechart.R index 65faf43..0bb2c87 100644 --- a/R/ro_ply_focus_linechart.R +++ b/R/ro_ply_focus_linechart.R @@ -9,7 +9,6 @@ #' #' @return HTML code (using `tags$head` and `tags$style`) to be included in a Shiny UI. #' @family plotly -#' @export #' @examples #' if (interactive()) { #' ui <- fluidPage( diff --git a/R/ro_ply_keyboard_accessibility.R b/R/ro_ply_keyboard_accessibility.R index 91bb756..7c11b9d 100644 --- a/R/ro_ply_keyboard_accessibility.R +++ b/R/ro_ply_keyboard_accessibility.R @@ -17,7 +17,6 @@ #' @family ggplotly #' @return A \code{plotly} object with improved accessibility features for keyboard and screen reader users. #' @seealso \code{\link{ro_ply_keyboard_nav_bargraph}} -#' @export #' #' @examples #' \dontrun{ @@ -596,7 +595,6 @@ ro_ply_keyboard_nav_barchart <- function(fig) { #' @return A \code{plotly} object with improved keyboard accessibility. #' @family ggplotly #' @family plotly -#' @export #' #' @examples #' \dontrun{ @@ -1098,7 +1096,6 @@ ro_ply_keyboard_nav_bargraph <- function(fig) { #' #' @return A \code{plotly} object with improved keyboard accessibility. #' -#' @export #' @family ggplotly #' @family plotly #' @examples @@ -1511,7 +1508,6 @@ ro_ply_keyboard_nav_trendline <- function(fig) { #' @return A \code{plotly} object with improved keyboard accessibility for line charts. #' @family ggplotly #' @family plotly -#' @export #' #' @examples #' \dontrun{ diff --git a/R/ro_ply_keyboard_nav_legend.R b/R/ro_ply_keyboard_nav_legend.R index e5668e4..8672c18 100644 --- a/R/ro_ply_keyboard_nav_legend.R +++ b/R/ro_ply_keyboard_nav_legend.R @@ -11,7 +11,6 @@ #' #' @return A \code{plotly} object with improved legend accessibility. #' -#' @export #' @family ggplotly #' @family plotly #' @examples diff --git a/R/ro_ply_legend_theme.R b/R/ro_ply_legend_theme.R index 7c6ecf8..b37010a 100644 --- a/R/ro_ply_legend_theme.R +++ b/R/ro_ply_legend_theme.R @@ -7,7 +7,6 @@ #' @param fig A Plotly figure object created by \code{plotly::plot_ly()} or similar. #' #' @return The Plotly figure object with the custom legend styling applied. -#' @export #' @family plotly #' @examples #' \dontrun{ diff --git a/R/ro_ply_theme.R b/R/ro_ply_theme.R index a27e017..46b6cf4 100644 --- a/R/ro_ply_theme.R +++ b/R/ro_ply_theme.R @@ -51,7 +51,6 @@ #' @return A named list with plotly theming options, suitable for passing #' to \code{plotly::layout()} or as a theme in a plotly chart. #' -#' @export #' #' @examples #' \dontrun{ diff --git a/R/ro_ply_title.R b/R/ro_ply_title.R index d440be6..cd45ab7 100644 --- a/R/ro_ply_title.R +++ b/R/ro_ply_title.R @@ -21,7 +21,6 @@ #' @family plotly #' @return The plotly figure object with added (and styled) title and/or axis labels as annotations. #' -#' @export #' #' @examples #' \dontrun{ diff --git a/vignettes/ggplotly-and-plotly-keyboard-accessibility.qmd b/vignettes/ggplotly-and-plotly-keyboard-accessibility.qmd deleted file mode 100644 index 5adbf8a..0000000 --- a/vignettes/ggplotly-and-plotly-keyboard-accessibility.qmd +++ /dev/null @@ -1,741 +0,0 @@ ---- -title: "ggplotly and plotly keyboard accessibility" -format: html -vignette: > - %\VignetteIndexEntry{ggplotly-and-plotly-keyboard-accessibility} - %\VignetteEngine{quarto::html} - %\VignetteEncoding{UTF-8} ---- - -```{r, include = FALSE} -knitr::opts_chunk$set( - collapse = TRUE, - comment = "#>" -) -options(rmarkdown.html_vignette.check_title = FALSE) -``` - -```{r, setup} -library(ROvis.plotly) # nolint: missing_package_linter. -``` -# Introduction -This vignette demonstrates the use of accessibility functions for interactive `plotly` and `ggplotly` plots. -These functions are designed to improve keyboard and screen reader accessibility for various types of interactive charts. - -Note: The example plots in this vignette are for demonstration only and do not themselves comply with the Rijksoverheid style requirements. - -Key Accessibility Features - -- Keyboard navigation: Users can focus bars, points, and legend items using Tab and Arrow keys. -- Accessible tooltips: Tooltip content is made available for screen readers and keyboard navigation. -- Screen reader support: Meaningful ARIA labels are provided for plot elements. -- Legend accessibility: Legends can be reached and toggled via keyboard. -- Toolbar control: The plotly modebar (toolbar) can be disabled for improved accessibility. - -The functions covered in this vignette are: - -- ro_ply_keyboard_nav_barchart() -- ro_ply_keyboard_nav_bargraph() -- ro_ply_keyboard_nav_trendline() -- ro_ply_keyboard_nav_linechart() -- ro_ply_keyboard_nav_legend() -- ro_ply_disable_toolbar() - - -# Keyboard accessibility - ggplotly and plotly plots -Each section below demonstrates how to add accessibility to a ggplotly or plotly graph using the functions from this package. -For each plot type, you will see an example with and without accessibility enhancements. - -## Horizontal Barchart -This section demonstrates how to make a horizontal bar chart created with ggplotly or plotly keyboard accessible. The example shows how to use `ro_ply_keyboard_nav_barchart()` to enable keyboard navigation and accessible tooltips for all bars. - -### Example data -```{r example data horizontal barchart} -data <- tidyr::tibble( - expand.grid(`Age group` = c("A", "B", "C", "D", "E"), `Sex` = c("Man", "Vrouw")), - `Number of Cases` = sample(1:50, 10, TRUE) -) -``` - -### ggplotly - Horizontal Barchart -```{r ggplotly horizontal barchart} -library(ggplot2) -library(plotly) - -p <- ggplot(data, aes( - x = `Number of Cases`, - y = `Age group`, - fill = Sex, - text = paste0( - "Leeftijdsgroep: ", `Age group`, "
", - "Geslacht: ", Sex, "
", - "Aantal cases: ", `Number of Cases`, "" - ) -)) + - geom_col(position = "dodge") + - labs( - x = "Aantal cases", - y = "Leeftijdsgroep", - fill = "Geslacht" - ) - -# Convert to plotly and add accessibility -fig <- ggplotly(p, tooltip = "text") - -# Add the keyboard accessibility in the plot -fig <- ro_ply_keyboard_nav_barchart(fig) -fig -``` - -### plotly - Horizontal Barchart -```{r plotly horizontal barchart} -library(plotly) - -fig <- plot_ly(data = data, - x = ~`Number of Cases`, - y = ~`Age group`, - color = ~`Sex`, - type = "bar", - orientation = "h", # horizontal bars - hovertext = ~paste0( - "Leeftijdsgroep: ", `Age group`, "
", - "Geslacht: ", `Sex`, "
", - "Aantal cases: ", `Number of Cases`, "" - ), - text = ~paste0( - "Leeftijdsgroep: ", `Age group`, "
", - "Geslacht: ", `Sex`, "
", - "Aantal cases: ", `Number of Cases`, "" - ), - textposition = "none", - hoverinfo = "text" -) -# Add the keyboard accessibility in the plot -fig <- ro_ply_keyboard_nav_barchart(fig) -fig - -``` -## Grouped Bar Graph / Column Chart -This section demonstrates how to make a column chart created with ggplotly or plotly keyboard accessible. The example shows how to use `ro_ply_keyboard_nav_barchart()` to enable keyboard navigation and accessible tooltips for all bars. - -### Example data -```{r example data column chart} -age_levels <- c( - "0", "1-9", "10-19", "20-29", - "30-39", "40-49", "50-59", - "60-69", "70-79", "80-89", "90+" -) - -base_data <- tidyr::expand_grid( - `Age group` = age_levels, - Sex = c("Men", "Women") -) |> - dplyr::mutate( - `Number of Cases` = sample(1:50, length(age_levels) * 2, TRUE) - ) - -summary_data <- base_data |> - dplyr::summarize( - `Number of Cases` = sum(`Number of Cases`), - .by = `Age group` - ) |> - dplyr::mutate(Sex = "Total") - -data <- dplyr::bind_rows(base_data, summary_data) |> - dplyr::mutate( - `Age group` = factor(`Age group`, levels = age_levels), - Sex = factor(Sex, levels = c("Men", "Women", "Total")) - ) - -``` -### ggplotly Grouped Bar Graph / Column Chart -```{r ggplotly column chart} -p <- ggplot(data, aes( - x = `Age group`, - y = `Number of Cases`, - fill = Sex, - text = paste0( - "Geslacht: ", Sex, "", - "
Leeftijdsgroep: ", `Age group`, - "
Aantal cases: ", - format(round(`Number of Cases`, 0), big.mark = ".", decimal.mark = ",", scientific = FALSE), "" - ) -)) + - geom_col(position = position_dodge(width = 0.7), width = 0.7) + - labs(x = "Leeftijdsgroep", y = "Aantal cases", fill = "Geslacht") - -# Convert to interactive plotly plot -fig <- ggplotly(p, tooltip = "text") -fig <- ro_ply_keyboard_nav_bargraph(fig) -fig -``` -### plotly Grouped Bar Graph / Column Chart -```{r plotly column chart} -fig <- plot_ly( - data = data, - x = ~`Age group`, - y = ~`Number of Cases`, - type = "bar", - color = ~Sex, - text = ~paste0( - "Geslacht: ", Sex, "", - "
Leeftijdsgroep: ", `Age group`, - "
Aantal cases: ", - format(round(`Number of Cases`, 0), big.mark = ".", decimal.mark = ",", scientific = FALSE), "" - ), - textposition = "none", - hoverinfo = "text" -) |> - layout(barmode = "group") - -# Add the keyboard accessibility in the plot -fig <- ro_ply_keyboard_nav_bargraph(fig) -fig -``` - -## Bar Graph -This section demonstrates how to make a bar graph created with ggplotly or plotly keyboard accessible. The example shows how to use `ro_ply_keyboard_nav_barchart()` to enable keyboard navigation and accessible tooltips for all bars. - -### Example data -```{r example data bargrpaph} -data <- tidyr::tibble( - Sex = factor(c("Vrouw", "Man"), levels = c("Vrouw", "Man")), - n = sample(1e6:5e6, 2) -) - -``` -### ggplotly Bar Graph -library(ggplot2) -library(plotly) - -```{r ggplotly bar graph} -p <- ggplot(data, aes(x = Sex, y = n, fill = Sex, - text = paste0( - "Geslacht: ", Sex, "", - "
Aantal cases: ", - format(round(n, 0), big.mark = ".", decimal.mark = ",", scientific = FALSE), "" - ))) + - geom_col(width = 0.6) + - labs(x = "Geslacht", y = "Aantal cases") + - theme_minimal() - -# Convert to plotly and add accessibility -fig <- ggplotly(p, tooltip = "text") - -# Add the keyboard accessibility in the plot -fig <- ro_ply_keyboard_nav_bargraph(fig) -fig -``` -### plotly Bar Graph -```{r plotly bar graph} -fig <- plot_ly( - data = data, - x = ~Sex, - y = ~n, - type = "bar", - color = ~Sex, - text = ~paste0( - "Geslacht: ", Sex, "", - "
Aantal cases: ", - format(round(n, 0), big.mark = ".", decimal.mark = ",", scientific = FALSE), "" - ), - hoverinfo = "text", - width = 0.6 -) - -# Add the keyboard accessibility in the plot -fig <- ro_ply_keyboard_nav_bargraph(fig) -fig -``` -## Stacked Bar Graph -This section demonstrates how to make a stacked bar graph created with ggplotly or plotly keyboard accessible. The example shows how to use `ro_ply_keyboard_nav_barchart()` to enable keyboard navigation and accessible tooltips for all bars. - -### Example data -```{r example data stacked bar graph} -agegroups <- c("0-9", "10-19", "20-29", "30-39", "40-49", "50-59", "60-69", "70-79", "80-89", "90+") -sex <- c("Vrouw", "Man", "Onbekend") - -data <- expand.grid( - Agegroup = agegroups, - Sex = sex, - stringsAsFactors = FALSE -) |> - tibble::as_tibble() |> - dplyr::rowwise() |> - dplyr::mutate( - n = if (Sex == "Onbekend") sample(200:3000, 1) else sample(200000:700000, 1) - ) |> - dplyr::ungroup() |> - dplyr::mutate(Sex = factor(Sex, levels = c("Vrouw", "Man", "Onbekend"))) - -``` -### ggplotly Stacked Bar Graph -```{r ggplotly stacked bar graph} -library(ggplot2) -library(plotly) - -p <- ggplot(data, aes(x = Agegroup, y = n, fill = Sex, - text = paste0( - "Aantal cases: ", format(n, big.mark = ".", decimal.mark = ",", scientific = FALSE), - "
Leeftijdsgroep: ", Agegroup, - "
Geslacht: ", Sex - ))) + - geom_col(width = 0.7, position = "stack") + - labs(x = "Leeftijdsgroep", y = "Aantal cases", fill = "Geslacht") - -# Convert to plotly and add accessibility -fig <- ggplotly(p, tooltip = "text") - -# Add the keyboard accessibility in the plot -fig <- ro_ply_keyboard_nav_bargraph(fig) -fig -``` -### plotly Stacked Bar Graph -```{r plotly stacked bar graph} -library(plotly) - -fig <- plot_ly( - data = data, # your tibble - x = ~Agegroup, - y = ~n, - color = ~Sex, - type = "bar", - text = ~paste0( - "Aantal cases: ", format(n, big.mark = ".", decimal.mark = ",", scientific = FALSE), - "
Leeftijdsgroep: ", Agegroup, - "
Geslacht: ", Sex - ), - textposition = "none", - hoverinfo = "text" -) |> - layout(barmode = "stack") - -# Add the keyboard accessibility in the plot -fig <- ro_ply_keyboard_nav_bargraph(fig) -fig -``` - -## Proportional Stacked Bar Graph -This section demonstrates how to make a proportional stacked bar graph created with plotly keyboard accessible. The example shows how to use `ro_ply_keyboard_nav_barchart()` to enable keyboard navigation and accessible tooltips for all bars. - -Note: Proportional stacked bar graphs are not supported via ggplotly, only via plotly. - - -### Example data -```{r example data proportional stacked bar graph} -age_cat <- c("0-19", "20-39", "40-59", "60+") -sex <- c("Vrouw", "Man") -period <- c("Na", "Voor") - -data <- expand.grid( - age_cat = age_cat, - omicron_period = period, - stringsAsFactors = FALSE -) |> - tibble::as_tibble() |> - dplyr::rowwise() |> - dplyr::mutate( - # Simuleer totaal aantal cases per groep - total_n = sample(50000:1200000, 1), - # Simuleer random verhouding tussen vrouw/man - vrouw_prop = runif(1, 0.45, 0.55), - man_prop = 1 - vrouw_prop, - n_vrouw = as.integer(total_n * vrouw_prop), - n_man = total_n - n_vrouw - ) |> - dplyr::ungroup() |> - # Zet weer om naar long format per sex - tidyr::pivot_longer( - cols = c(n_vrouw, n_man), - names_to = "Sex", - values_to = "n", - names_prefix = "n_" - ) |> - dplyr::group_by(age_cat, omicron_period) |> - dplyr::mutate( - prop = n / sum(n), - bar_label = paste0(age_cat, " (", omicron_period, ")"), - prop_label = paste0(format(round(prop * 100, 1), decimal.mark = ","), "%") - ) |> - dplyr::ungroup() |> - dplyr::select(age_cat, Sex, omicron_period, n, prop, bar_label, prop_label) - -# Order the labels -data <- data |> - dplyr::mutate( - Sex = dplyr::recode(Sex, "vrouw" = "Vrouw", "man" = "Man") - ) -bar_label_levels <- as.vector(outer(age_cat, period, function(a, p) paste0(a, " (", p, ")"))) -data <- data |> - dplyr::mutate( - bar_label = factor(bar_label, levels = bar_label_levels), - Sex = factor(Sex, levels = c("Vrouw", "Man")) - ) |> - dplyr::arrange(bar_label, Sex) |> - dplyr::select(age_cat, Sex, omicron_period, n, prop, bar_label, prop_label) - -# Show the structure of the data -str(data) -``` - -```{r ggplotly proportional stacked bar graph, include = FALSE} -### ggplotly Proportional Stacked Bar Graph -library(ggplot2) -library(plotly) - -``` -### plotly Proportional Stacked Bar Graph -```{r plotly proportional stacked bar graph} -library(plotly) - -fig <- plot_ly( - data = data, - y = ~bar_label, - x = ~prop, - color = ~Sex, - orientation = "h", - type = "bar", - text = ~paste0( - "Leeftijdsgroep: ", age_cat, "
", - "Omicron periode: ", omicron_period, "
", - "Geslacht: ", Sex, "
", - "Percentage: ", prop_label, "
" - ), - textposition = "auto", - hovertemplate = ~paste0( - "Leeftijdsgroep: ", age_cat, "
", - "Omicron periode: ", omicron_period, "
", - "Geslacht: ", Sex, "
", - "Percentage: ", prop_label, "
" - ), - hoverinfo = "text" -) |> layout(barmode = "stack") - -fig <- ro_ply_keyboard_nav_barchart(fig) -fig -``` - - - - -## Trendline -This section demonstrates how to make a trendline created with ggplotly or plotly keyboard accessible. The `ro_ply_keyboard_nav_trendline()` function allows users to focus on individual points (not lines), with tooltips and ARIA labels for screen readers. - -### Example data -```{r example data Trendline} -dates <- seq(as.Date("2021-10-04"), by = "day", length.out = 100) -n <- round(2500 + 700 * sin(seq_along(dates) / 25) + seq_along(dates) * 3 + rnorm(length(dates), 0, 150)) -moving_average <- stats::filter(n, rep(1 / 7, 7), sides = 2) -text <- paste0( - "Dag: ", format(dates, "%d-%m-%Y"), "
", - "Aantal cases: ", format(n, big.mark = ".", decimal.mark = ",", scientific = FALSE), "
", - "7-daags gemiddelde: ", format(round(moving_average, 0), - big.mark = ".", decimal.mark = ",", scientific = FALSE), "" -) - -data <- tibble::tibble( - Date_statistics = dates, - n = n, - moving_average = as.numeric(moving_average), - text = text -) -``` -### ggplotly Trendline -```{r ggplotly Trendline} -p <- ggplot(data, aes(x = Date_statistics, y = n, text = text, group = 1)) + - geom_line() + - geom_point() - -# Convert to plotly and add accessibility -fig <- ggplotly(p, tooltip = "text") - -# Add the keyboard accessibility in the plot -fig <- ro_ply_keyboard_nav_trendline(fig) -fig -``` -### plotly Trendline -```{r plotly Trendline} -library(plotly) - -fig <- plot_ly() -fig <- fig |> - plotly::add_trace( - data = data, - x = ~Date_statistics, - y = ~n, - type = "scatter", - mode = "markers", - name = "Aantal cases", - text = ~text, - hoverinfo = "text" - ) -# Add line for moving average -fig <- fig |> - plotly::add_trace( - data = data, - x = ~Date_statistics, - y = ~moving_average, - type = "scatter", - mode = "lines", - name = "7-daags gemiddelde", - text = ~text, - hoverinfo = "text" - ) - -# Add the keyboard accessibility in the plot -fig <- ro_ply_keyboard_nav_trendline(fig) -fig -``` - -## Grouped Trendline -This section demonstrates how to make a grouped trendline created with ggplotly or plotly keyboard accessible. The `ro_ply_keyboard_nav_trendline()` function allows users to focus on individual points (not lines), with tooltips and ARIA labels for screen readers. - -### Example data -```{r example data Grouped Trendline} -categories <- LETTERS[1:5] # "A", "B", "C", "D", "E" -weeks <- seq(as.Date("2023-01-02"), as.Date("2023-05-29"), by = "week") - -data <- tidyr::expand_grid( - week = weeks, - Category = categories -) |> - dplyr::mutate( - n = dplyr::case_when( - Category == "A" ~ round(100 + 10 * as.numeric(week - min(week)) / 7 + stats::rnorm(dplyr::n(), 0, 15)), - Category == "B" ~ round(50 + 2 * as.numeric(week - min(week)) / 7 + stats::rnorm(dplyr::n(), 0, 7)), - Category == "C" ~ round(80 + 5 * sin(dplyr::row_number() / 4) + stats::rnorm(dplyr::n(), 0, 10)), - Category == "D" ~ round(200 - 5 * as.numeric(week - min(week)) / 7 + stats::rnorm(dplyr::n(), 0, 18)), - Category == "E" ~ round(70 + 8 * cos(dplyr::row_number() / 5) + stats::rnorm(dplyr::n(), 0, 12)) - ) - ) -data <- data |> - dplyr::mutate( - text = paste0( - "Week: ", format(week, "%d-%m-%Y"), "
", - "Categorie: ", Category, "
", - "Aantal cases: ", format(n, big.mark = ".", decimal.mark = ",", scientific = FALSE), "" - ) - ) -cat_names <- unique(data$Category) -``` -### ggplotly Grouped Trendline -```{r ggplotly Grouped Trendline} -library(ggplot2) -library(plotly) - -p <- ggplot(data, aes(x = week, y = n, color = Category, group = Category, text = text)) + - geom_line() + - geom_point() - -# Convert to plotly and add accessibility -fig <- ggplotly(p, tooltip = "text") - -# Add the keyboard accessibility in the plot -fig <- ro_ply_keyboard_nav_trendline(fig) -fig -``` - -### plotly Grouped Trendline - -```{r plotly Grouped Trendline} -library(plotly) - - - -fig <- plot_ly() -for (cat in cat_names) { - subset <- data[data$Category == cat, ] - fig <- fig |> - plotly::add_trace( - data = subset, - x = ~week, - y = ~n, - type = "scatter", - mode = "lines+markers", - name = cat, - text = ~text, - hoverinfo = "text" - ) -} - -# Add the keyboard accessibility in the plot -fig <- ro_ply_keyboard_nav_trendline(fig) -fig -``` - -## Line Chart - -This section demonstrates how to make a line chart created with ggplotly or plotly keyboard accessible. The `ro_ply_keyboard_nav_linechart()` adds keyboard focus to lines, and shows a focus-point. - -### Example data -```{r example data Line Chart} -base_data <- tidyr::tibble(expand.grid( - Jaar = 2001:2020, - Geslacht = c("Man", "Vrouw") -)) |> - dplyr::mutate(value = sample(1:50, dplyr::n(), TRUE)) - -total_data <- base_data |> - dplyr::group_by(Jaar) |> - dplyr::summarize(value = sum(value), .groups = "drop") |> - dplyr::mutate(Geslacht = "Totaal") - -data <- dplyr::bind_rows(base_data, total_data) |> - dplyr::mutate(Geslacht = factor(Geslacht, levels = c("Man", "Vrouw", "Totaal"))) - -``` -### ggplotly Line Chart -`ro_ply_keyboard_nav_linechart` -```{r ggplotly Line Chart} -library(ggplot2) -library(plotly) - - -p <- ggplot(data, aes(x = Jaar, y = value, color = Geslacht, group = Geslacht, - text = paste0( - "Geslacht: ", Geslacht, - "
Jaar: ", Jaar, - "
Aantal cases: ", value - ))) + - geom_line() - -# Convert to plotly and add accessibility -fig <- ggplotly(p, tooltip = "text") - -# Add the keyboard accessibility in the plot -fig <- ro_ply_keyboard_nav_linechart(fig) -fig -``` -### plotly Line Chart -```{r plotly Line Chart} -library(plotly) - - -fig <- plot_ly() - -for (geslacht in levels(data$Geslacht)) { - subset <- data |> filter(Geslacht == geslacht) - - fig <- fig |> - add_trace( - data = subset, - x = ~Jaar, - y = ~value, - type = "scatter", - mode = "lines", - name = geslacht, - text = paste0( - "Geslacht: ", subset$Geslacht, - "
Jaar: ", subset$Jaar, - "
Aantal cases: ", subset$value - ), - hoverinfo = "text" - ) -} - -# Add the keyboard accessibility in the plot -fig <- ro_ply_keyboard_nav_linechart(fig) -fig -``` - -# Keyboard accessibility - ggplotly and plotly legends - -By default, plotly legends are not keyboard accessible. -The `ro_ply_keyboard_nav_legend()` function makes it possible to reach and toggle legend items using the keyboard, with visual focus indication and ARIA attributes for screen readers. - -Note: For stacked bar graphs for ggplot, it is advised to disable the legend filtering (also with the mouse) altogether, as the image is not re-rendered after filtering, which can lead to 'floating' bars. - -### Example data and plot (horizontal barchart from above) - -The example data is used from the horizontal barchart as shown above. - -```{r example data horizontal barchart for the legend} -data <- tidyr::tibble( - expand.grid(`Age group` = c("A", "B", "C", "D", "E"), `Sex` = c("Man", "Vrouw")), - `Number of Cases` = sample(1:50, 10, TRUE) -) -library(ggplot2) -library(plotly) - -p <- ggplot(data, aes( - x = `Number of Cases`, - y = `Age group`, - fill = Sex, - text = paste0( - "Leeftijdsgroep: ", `Age group`, "
", - "Geslacht: ", Sex, "
", - "Aantal cases: ", `Number of Cases`, "" - ) -)) + - geom_col(position = "dodge") + - labs( - x = "Aantal cases", - y = "Leeftijdsgroep", - fill = "Geslacht" - ) - -# Convert to plotly and add accessibility -fig <- ggplotly(p, tooltip = "text") - -# Add the keyboard accessibility in the plot -fig <- ro_ply_keyboard_nav_barchart(fig) -``` -After the figure is made, the legend can be made accessible. - -```{r legend example horizontal barchart} -# Add the keyboard accessibility to the legend -fig <- ro_ply_keyboard_nav_legend(fig) -fig - -``` - - -# ggplotly and plotly disable toolbar -The plotly modebar / toolbar can be distracting or inaccessible for keyboard users. - -The `ro_ply_disable_toolbar()` function removes the toolbar and disables legend popup further improving accessibility. - -### Example data and plot - -The example data is used from the horizontal barchart as shown above. - -```{r example data horizontal barchart for disabling the toolbar} -data <- tidyr::tibble( - expand.grid(`Age group` = c("A", "B", "C", "D", "E"), `Sex` = c("Man", "Vrouw")), - `Number of Cases` = sample(1:50, 10, TRUE) -) -library(ggplot2) -library(plotly) - -p <- ggplot(data, aes( - x = `Number of Cases`, - y = `Age group`, - fill = Sex, - text = paste0( - "Leeftijdsgroep: ", `Age group`, "
", - "Geslacht: ", Sex, "
", - "Aantal cases: ", `Number of Cases`, "" - ) -)) + - geom_col(position = "dodge") + - labs( - x = "Aantal cases", - y = "Leeftijdsgroep", - fill = "Geslacht" - ) - -# Convert to plotly and add accessibility -fig <- ggplotly(p, tooltip = "text") - -# Add the keyboard accessibility in the plot -fig <- ro_ply_keyboard_nav_barchart(fig) -# Add keyboard accessibility to the legend -fig <- ro_ply_keyboard_nav_legend(fig) -``` -Then the toolbar / modbar can be disabled, and the pop-up on filtering can be disabled as well, as this not accessible with the keyboard - -```{r modbar example horizontal barchart} -# Disable the modbar and filtering pop-up -fig <- ro_ply_disable_toolbar(fig) -fig -``` diff --git a/vignettes/plotly-figures-in-rivm-style.qmd b/vignettes/plotly-figures-in-rivm-style.qmd deleted file mode 100644 index e3dd715..0000000 --- a/vignettes/plotly-figures-in-rivm-style.qmd +++ /dev/null @@ -1,542 +0,0 @@ ---- -title: "plotly figures in Rijksoverheid style" -format: html -vignette: > - %\VignetteIndexEntry{plotly figures in Rijksoverheid style} - %\VignetteEngine{quarto::html} - %\VignetteEncoding{UTF-8} ---- - -```{r eval, include = FALSE} -knitr::opts_chunk$set(collapse = TRUE, echo = TRUE) -``` - -```{r setup} -library(plotly) -library(ROvis.plotly) # nolint: missing_package_linter. -library(ROvis.utils) -``` - -# Introduction - -This vignette demonstrates how to create clear, publication-ready visualizations in R using the [plotly](https://plotly.com/r/) package, styled according to the Rijksoverheids style The provided functions allow you to quickly apply consistent fonts, colors, grid lines, axes, legends, tooltips, and annotation styling across all your Plotly charts. - -# Key Functions - -- **`ro_ply_theme()`** - Returns a list of theming options (colors, fonts, grid, axis, legend, tooltip styles, etc.) based on the Rijksoverheid visual identity. You can customize many aspects, such as the color palette, fonts, grid lines, and axis formatting. - -- **`ro_ply_add_theme()`** - Applies the Rijksoverheid / RIVM theme (from `ro_ply_theme()`) to any Plotly figure. - -- **`ro_ply_title()`** - Adds a custom, left-aligned main title and axis labels as annotations, in line with the Rijksoverheid / RIVM style. - -- **`ro_ply_cursor()`** - Changes the mouse cursor in interactive Plotly charts from a crosshair to a standard arrow for a friendlier user experience. - -- **`ro_ply_legend_theme()`** - Enhances the legend styling by adding boxes around legend items. - -- **`ro_ply_dim()`** - Ensures all charts have the correct dimensions for Rijksoverheid / RIVM reports, and are responsive in Shiny applications. - -# Code Examples - -## Column chart - -This example shows how to create a grouped vertical bar chart (column chart) displaying the number of cases by age group and sex. - -The Rijksoverheid / RIVM theme is set with: -`theme_rivm <- ro_ply_theme(barmode = "group")` -where `barmode = "group"` ensures grouped bars for each age group. - -```{r example column chart} -age_levels <- c( - "0", "1-9", "10-19", "20-29", - "30-39", "40-49", "50-59", - "60-69", "70-79", "80-89", "90+" -) - -base_data <- tidyr::expand_grid( - `Age group` = age_levels, - Sex = c("Men", "Women") -) |> - dplyr::mutate( - `Number of Cases` = sample(1:50, length(age_levels) * 2, TRUE) - ) - -summary_data <- base_data |> - dplyr::summarize( - `Number of Cases` = sum(`Number of Cases`), - .by = `Age group` - ) |> - dplyr::mutate(Sex = "Total") - -data <- dplyr::bind_rows(base_data, summary_data) |> - dplyr::mutate( - `Age group` = factor(`Age group`, levels = age_levels), - Sex = factor(Sex, levels = c("Men", "Women", "Total")) - ) - - -theme_rivm <- ro_ply_theme(barmode = "group") -kleuren <- c(theme_rivm$colorway[1], theme_rivm$colorway[3], theme_rivm$colorway[4]) - -fig <- plot_ly( - data = data, - x = ~`Age group`, - y = ~`Number of Cases`, - type = "bar", - color = ~Sex, - colors = kleuren, - text = ~paste0( - "Geslacht: ", Sex, "", - "
Leeftijdsgroep: ", `Age group`, - "
Aantal cases: ", - format(round(`Number of Cases`, 0), big.mark = ".", decimal.mark = ",", scientific = FALSE), "" - ), - textposition = "none", - hoverinfo = "text" -) - -fig <- ro_ply_add_theme(fig = fig, theme = theme_rivm) -fig <- ro_ply_title(fig, y_data = data$"Age group", y_label = "cases", title = "fancy title", x_label = "groups") -fig <- ro_ply_cursor(fig) -fig <- ro_ply_legend_theme(fig) -fig <- ro_ply_dim(fig) -fig -``` - - -## Bar Graph - -This example demonstrates a simple vertical bar chart, showing the number of cases per sex, with the default Rijksoverheid / RIVM theme. - -```{r example bar graph} -# Create example data: counts per group -bar_data <- tibble::tibble( - Sex = c("Man", "Vrouw"), - n = c(1234, 1675) -) - -# Use the color function for Rijksoverheid / RIVM colors -sex_colors <- c( - "Man" = ro_color("hemelblauw"), - "Vrouw" = ro_color("robijnrood") -) - -# Create plotly bar chart -fig <- plot_ly( - data = bar_data, - x = ~Sex, - y = ~n, - type = "bar", - color = ~Sex, - colors = sex_colors, - text = ~paste0( - "Geslacht: ", Sex, "", - "
Aantal cases: ", - format(round(n, 0), big.mark = ".", decimal.mark = ",", scientific = FALSE), "" - ), - hoverinfo = "text" -) - -# Apply Rijksoverheid / RIVM theme -fig <- ro_ply_add_theme(fig, ro_ply_theme()) - -# Add custom title and axis labels -fig <- ro_ply_title( - fig, - y_data = bar_data$n, - y_label = "Aantal cases", - title = "COVID-19 cases per geslacht", - x_label = "Geslacht" -) - -# Apply cursor and legend theming -fig <- ro_ply_cursor(fig) -fig <- ro_ply_legend_theme(fig) -fig <- ro_ply_dim(fig) - -fig -``` - -## Horizontal Bar Chart - -This example demonstrates how to create a horizontal bar chart grouped by age group and sex. -The Rijksoverheid / RIVM theme is customized to: -- show a spike line on the y-axis only, -- show the y-axis line and hide the x-axis line, -- show grid lines only for the x-axis. - - -```{r example horizontal barchart} -# Generate random data -data <- tibble::tibble(expand.grid(`Age group` = c("A", "B", "C", "D", "E"), - `Sex` = c("Man", "Vrouw")), - `Number of Cases` = sample(1:50, 10, TRUE)) - -theme_rivm <- ro_ply_theme(y_axis_spike = TRUE, - x_axis_spike = FALSE, - y_axis_showline = TRUE, - x_axis_showline = FALSE, - y_axis_showgrid = FALSE, - x_axis_showgrid = TRUE) -kleuren <- c(theme_rivm$colorway[1], theme_rivm$colorway[3]) - -fig <- plot_ly() |> - plotly::add_trace(data = data, - x = ~`Number of Cases`, - y = ~`Age group`, - color = ~`Sex`, - colors = kleuren, - type = "bar", - orientation = "h", # horizontal bars - hovertext = ~paste0( - "Leeftijdsgroep: ", `Age group`, "
", - "Geslacht: ", `Sex`, "
", - "Aantal cases: ", `Number of Cases`, "" - ), - hoverinfo = "text" - ) -fig <- ro_ply_add_theme(fig = fig, theme = theme_rivm) -fig <- ro_ply_title(fig, y_data = data$"Age group", y_label = "group", title = "fancy title", x_label = "cases") -fig <- ro_ply_cursor(fig) -fig <- ro_ply_legend_theme(fig) -fig <- ro_ply_dim(fig) -fig -``` - -## Stacked Bar Graph - -This example demonstrates how to create a stacked bar chart displays the number of cases per age group and sex. - -The theme uses: -`theme_rivm <- ro_ply_theme(barmode = "stack")` -where `barmode = "stack"` stacks the bars by sex within each age group. - -```{r example stacked bar graph} -library(dplyr) - -# Example data: number of cases per age group and sex -stacked_data <- tibble::tibble( - Agegroup = rep(c("0-9", "10-19", "20-29", "30-39"), each = 3), - Sex = rep(c("Man", "Vrouw", "Onbekend"), times = 4), - n = c(10, 14, 2, 15, 17, 1, 23, 18, 0, 9, 11, 3) -) - -# Define color palette using your color function -sex_colors <- c( - "Man" = ro_color("hemelblauw"), - "Vrouw" = ro_color("robijnrood"), - "Onbekend" = ro_color("donkergeel") -) - -# Use ro_ply_theme with barmode = "stack" -theme_rivm <- ro_ply_theme(barmode = "stack") - -# Create the plotly stacked bar chart -fig <- plot_ly( - data = stacked_data, - x = ~Agegroup, - y = ~n, - type = "bar", - color = ~Sex, - colors = sex_colors, - text = ~paste0( - "Leeftijdsgroep: ", Agegroup, "", - "
Geslacht: ", Sex, "", - "
Aantal cases: ", - format(round(n, 0), big.mark = ".", decimal.mark = ",", scientific = FALSE), "" - ), - hoverinfo = "text" -) - -fig <- ro_ply_add_theme(fig, theme_rivm) -fig <- ro_ply_title( - fig, - y_data = stacked_data |> group_by(Agegroup) |> summarise(n_total = sum(n)) |> pull(n_total), - y_label = "Aantal cases", - title = "COVID-19 cases per leeftijdsgroep en geslacht", - x_label = "Leeftijdsgroep" -) -fig <- ro_ply_cursor(fig) -fig <- ro_ply_legend_theme(fig) -fig <- ro_ply_dim(fig) - -fig -``` -## Proportional Stacked Bar Graph - -This example demonstrates how to create aroportional stacked bar chart, displaying the proportion of cases per age group and sex as a horizontal. - -The theme uses: -`theme_rivm <- ro_ply_theme(barmode = "stack")` -where `barmode = "stack"` stacks the bars by sex within each age group. - -```{r example proportional stacked bar graph} -library(dplyr) - -# Example data: Age group, Sex, and number of cases -prop_data <- tibble::tibble( - age_cat = rep(c("0-9", "10-19", "20-29", "30-39"), each = 2), - Sex = rep(c("Man", "Vrouw"), times = 4), - n = c(12, 8, 15, 12, 20, 18, 10, 7) -) |> - group_by(age_cat) |> - mutate( - total = sum(n), - prop = n / total, - prop_label = paste0(round(prop * 100, 1), "%"), - bar_label = age_cat - ) |> - ungroup() - -# Define color palette using your color function -sex_colors <- c( - "Man" = ro_color("hemelblauw"), - "Vrouw" = ro_color("robijnrood") -) - -# Use ro_ply_theme with barmode = "stack" -theme_rivm <- ro_ply_theme(barmode = "stack") - -# Create the proportional stacked bar chart (horizontal) -fig <- plot_ly( - data = prop_data, - y = ~bar_label, - x = ~prop, - color = ~Sex, - colors = sex_colors, - type = "bar", - orientation = "h", - text = ~paste0( - "Leeftijdsgroep: ", age_cat, "
", - "Geslacht: ", Sex, "
", - "Percentage: ", prop_label, "" - ), - textposition = "auto", - hovertemplate = ~paste0( - "Leeftijdsgroep: ", age_cat, "
", - "Geslacht: ", Sex, "
", - "Percentage: ", prop_label, "" - ), - hoverinfo = "text" -) - -fig <- ro_ply_add_theme(fig, theme_rivm) -fig <- ro_ply_title( - fig, - y_data = prop_data$bar_label, - y_label = "Leeftijdsgroep", - title = "Percentage COVID-19 cases per leeftijdsgroep en geslacht", - x_label = "Percentage" -) -fig <- ro_ply_cursor(fig) -fig <- ro_ply_legend_theme(fig) -fig <- ro_ply_dim(fig) - -# Format x-axis as percentage -fig <- fig |> - layout( - xaxis = list( - tickformat = ".0%", - range = c(0, 1), - title = "Percentage" - ) - ) - -fig - -``` - -## Trendline - -This example shows a trendline (with points and a moving average) for daily case counts. - -Here, the x-axis is formatted to display as "day month" for better readability: -`theme_rivm <- ro_ply_theme(x_axis_tick_format = "%d %b")` where x_axis_tick_format customizes the date format on the x-axis. - -```{r example trendline} -library(dplyr) -library(zoo) -library(stringr) - -# Example data: daily cases with a 7-day rolling average -tab_cases_rolling_average <- tibble::tibble( - Date_statistics = seq(as.Date("2022-11-01"), as.Date("2022-12-31"), by = "day"), - n = round(seq(100, 400, length.out = 61) + rnorm(61, 0, 20)) # trend + noise -) |> - mutate( - moving_average = zoo::rollmean(n, k = 7, fill = NA, align = "right"), - text = str_c( - "Dag: ", format(Date_statistics, "%d-%m-%Y"), "
", - "Aantal cases: ", format(n, big.mark = ".", decimal.mark = ",", scientific = FALSE), "
", - "7-daags gemiddelde: ", format(round(moving_average, 0), - big.mark = ".", decimal.mark = ",", scientific = FALSE), "" - ) - ) - -theme_rivm <- ro_ply_theme(x_axis_tick_format = "%d %b") - -fig <- plot_ly( - data = tab_cases_rolling_average, - x = ~Date_statistics -) |> - plotly::add_markers( - y = ~n, - name = "Aantal cases", - marker = list(color = ro_color("robijnrood_tint60"), size = 5), - text = ~text, - hoverinfo = "text" - ) |> - plotly::add_lines( - y = ~moving_average, - name = "7-daags gemiddelde", - line = list(color = ro_color("robijnrood"), width = 2), - text = ~text, - hoverinfo = "text" - ) - -fig <- ro_ply_add_theme(fig, theme_rivm) -fig <- ro_ply_title( - fig, - y_data = tab_cases_rolling_average$n, - y_label = "Aantal gevallen", - title = "COVID-19 gevallen per dag en 7-daags gemiddelde", - x_label = "Datum" -) -fig <- ro_ply_cursor(fig) -fig <- ro_ply_legend_theme(fig) -fig <- ro_ply_dim(fig) - -fig - -``` - -## Grouped Trendline -This example shows a grouped trendline for multiple provinces. - -Here, the x-axis is formatted to display as "day month" for better readability: -`theme_rivm <- ro_ply_theme(x_axis_tick_format = "%d %b")` where x_axis_tick_format customizes the date format on the x-axis. - -```{r example grouped trendline} -library(dplyr) - -# Example: Simulated COVID-19 cases per week for 2 provinces -weeks <- seq(as.Date("2022-11-01"), as.Date("2022-12-31"), by = "week") -tab_cases_week_by_prov <- tibble::tibble( - week = rep(weeks, 2), - Province = rep(c("Groningen", "Zeeland"), each = length(weeks)), - n = c( - seq(100, 200, length.out = length(weeks)) + rnorm(length(weeks), 0, 10), # Slightly increasing with noise - seq(100, 200, length.out = length(weeks)) + rnorm(length(weeks), 0, 10) - ) -) - -theme_rivm <- ro_ply_theme(x_axis_tick_format = "%d %b") -prov_names <- unique(tab_cases_week_by_prov$Province) -prov_colors <- setNames(theme_rivm$colorway[seq_along(prov_names)], prov_names) - -fig <- plot_ly() -for (prov in prov_names) { - prov_data <- filter(tab_cases_week_by_prov, Province == prov) - fig <- fig |> - plotly::add_trace( - data = prov_data, - x = ~week, - y = ~n, - type = "scatter", - mode = "lines", # Or use mode = "lines+markers" for lines and points - name = prov, - line = list(color = prov_colors[prov], width = 2), - text = ~paste0( - "Provincie: ", Province, "", - "
Week: ", format(week, "%e %b %Y"), "", - "
Aantal cases: ", format(round(n, 0), big.mark = ".", decimal.mark = ",", scientific = FALSE), "" - ), - hoverinfo = "text" - ) -} -fig <- ro_ply_add_theme(fig, theme_rivm) -fig <- ro_ply_title( - fig, - y_data = tab_cases_week_by_prov$n, - y_label = "Aantal gevallen", - title = "COVID-19 gevallen per week voor 5 provincies", - x_label = "Week" -) -fig <- ro_ply_cursor(fig) -fig <- ro_ply_legend_theme(fig) -fig <- ro_ply_dim(fig) -fig -``` - -## Line chart - -This example creates a grouped line chart showing cases by year and sex. -The theme is set to display the x-axis as a plain number (year), without the default thousand separator: -`theme_rivm <- ro_ply_theme(x_axis_tick_format = ".0f")` -so years appear as 2001, 2002, etc. - -```{r example line chart} -library(dplyr) -library(stringr) - -# Generate random data -data <- tibble::tibble( - expand.grid(Jaar = 2001:2020, Geslacht = c("Man", "Vrouw")), - value = sample(1:50, 40, TRUE) -) -data_sum <- data |> - group_by(Jaar) |> - summarize(value = sum(value), .groups = "drop") |> - mutate(Geslacht = "Totaal") -data_all <- bind_rows(data, data_sum) |> - mutate(Geslacht = factor(Geslacht, levels = c("Man", "Vrouw", "Totaal"))) - -# Use Rijksoverheid / RIVM theme and color palette -theme_rivm <- ro_ply_theme(x_axis_tick_format = ".0f") # No thousand seperator for the x-axis -kleuren <- c( - "Man" = theme_rivm$colorway[1], - "Vrouw" = theme_rivm$colorway[3], - "Totaal" = theme_rivm$colorway[4] -) - -# Create the plotly line chart -fig <- plot_ly() -for (geslacht in levels(data_all$Geslacht)) { - subset <- filter(data_all, Geslacht == geslacht) - fig <- fig |> - plotly::add_trace( - data = subset, - x = ~Jaar, - y = ~value, - type = "scatter", - mode = "lines", - name = geslacht, - line = list(color = kleuren[geslacht], width = 2), - text = ~str_c( - "Geslacht: ", Geslacht, - "
Jaar: ", Jaar, - "
Aantal cases: ", value - ), - hoverinfo = "text" - ) -} - -fig <- ro_ply_add_theme(fig, theme = theme_rivm) -fig <- ro_ply_title( - fig, - y_data = data_all$value, - y_label = "Aantal cases", - title = "COVID-19 cases per geslacht", - x_label = "" #For the year, no x-axis title is needed -) -fig <- ro_ply_cursor(fig) -fig <- ro_ply_legend_theme(fig) -fig <- ro_ply_dim(fig) -fig -``` -