library(testthat)
library(ggplot2)
library(readr)
pkgload::load_all()

Extract the {ggplot2} theme from a Figma file

You can use the extract_ggplot_theme() function to extract the elements of the {ggplot2} theme from a Figma file.

The Figma file is red with the get_figma_file_content() function. You can see the vignette b - Figma API connection and file extraction for more details.

get_figma_file_content(file_key = "wRqIvMmymzSPuj0sEhnORb",
                       acess_token = Sys.getenv("FIGMA_TOKEN")) %>% 
extract_ggplot_theme()

Details of the functions

Addition of the type of the {ggplot2} elements (i.e. rect, line or text)

corresp_element_type <- readr::read_rds(
  system.file("corresp_element_type.rds",
              package = "architekter"))
corresp_element_type %>% 
  head() %>% 
  knitr::kable()
#' Add the type of the ggplot2 elements (i.e. "rect", "line" or "text")
#'
#' @param .data Tibble. An object returned by \code{architekter::\link{raw_to_design_tibble}()}
#' 
#' @importFrom readr read_rds 
#' @importFrom dplyr left_join mutate case_when filter select everything
#' @importFrom cli cli_alert_danger
#'
#' @return The same tibble with an extra column with the ggplot2 type (i.e. "rect", "line" or "text").
#' @export
add_ggplot_theme_type <- function(.data) {

  corresp_element_type <- read_rds(system.file("corresp_element_type.rds",
                                               package = "architekter"))
  joined_data <- .data %>% 
    left_join(corresp_element_type, 
              by = "element_name") %>% 
    mutate(check_type = case_when(
      type == "VECTOR" & (element_type %in% c("rect", "line")) ~ "ok",
      type == "TEXT" & element_type == "text" ~ "ok",
      TRUE ~ "not ok"
    ))

  unconsistent_type <- joined_data %>% 
    filter(check_type == "not ok")

  if (nrow(unconsistent_type) != 0) {
    stop(cli_alert_danger("Inconsistent type of the ggplot2 elements. Incoherence between the type returned by Figma and the type specified in ggplot2."))
  } 

  joined_data <- joined_data %>% 
    select(-type, -check_type) %>% 
    select(element_name, element_type, everything())

  return(joined_data)

}
data(toy_raw_file_content)

data_design <- toy_raw_file_content %>% 
  raw_to_design_tibble()

data_design %>% 
  add_ggplot_theme_type()
test_that("add_ggplot_theme_type works", {

  data(toy_raw_file_content)

  data_with_type <- toy_raw_file_content %>% 
    raw_to_design_tibble() %>% 
    add_ggplot_theme_type()

  # long dput ----
  expect_equal(object = data_with_type, 
               expected = structure(list(element_name = c("panel_background", "legend_text", 
                                                          "legend_title", "panel_grid", "axis_text", "axis_title", "plot_subtitle", 
                                                          "plot_title"), element_type = c("rect", "text", "text", "line", 
                                                                                          "text", "text", "text", "text"), strokeWeight = c(5, 1, 1, 1, 
                                                                                                                                            1, 1, 1, 1), fontFamily = c(NA, "Roboto", "Roboto", NA, "Roboto", 
                                                                                                                                                                        "Roboto", "Roboto", "Roboto"), fontPostScriptName = c(NA, NA, 
                                                                                                                                                                                                                              NA, NA, NA, NA, "Roboto-Light", "Roboto-Light"), fontWeight = c(NA, 
                                                                                                                                                                                                                                                                                              400L, 400L, NA, 400L, 400L, 300L, 300L), textAutoResize = c(NA, 
                                                                                                                                                                                                                                                                                                                                                          "HEIGHT", "HEIGHT", NA, NA, NA, "HEIGHT", "WIDTH_AND_HEIGHT"), 
                                         fontSize = c(NA, 9, 11, NA, 9, 11, 12, 20), textAlignHorizontal = c(NA, 
                                                                                                             "LEFT", "LEFT", NA, "LEFT", "LEFT", "LEFT", "LEFT"), textAlignVertical = c(NA, 
                                                                                                                                                                                        "TOP", "TOP", NA, "TOP", "TOP", "TOP", "BOTTOM"), letterSpacing = c(NA, 
                                                                                                                                                                                                                                                            0.36, 0.44, NA, 0, 0.44, 0.48, 0.8), lineHeightPx = c(NA, 
                                                                                                                                                                                                                                                                                                                  10.546875, 12.890625, NA, 10.546875, 12.890625, 14.0625, 
                                                                                                                                                                                                                                                                                                                  23.4375), lineHeightPercent = c(NA, 100, 100, NA, 100, 100, 
                                                                                                                                                                                                                                                                                                                                                  100, 100), lineHeightUnit = c(NA, "INTRINSIC_%", "INTRINSIC_%", 
                                                                                                                                                                                                                                                                                                                                                                                NA, "INTRINSIC_%", "INTRINSIC_%", "INTRINSIC_%", "INTRINSIC_%"
                                                                                                                                                                                                                                                                                                                                                  ), fills_blendMode = c("NORMAL", "NORMAL", "NORMAL", "NORMAL", 
                                                                                                                                                                                                                                                                                                                                                                         "NORMAL", "NORMAL", "NORMAL", "NORMAL"), fills_type = c("SOLID", 
                                                                                                                                                                                                                                                                                                                                                                                                                                 "SOLID", "SOLID", "SOLID", "SOLID", "SOLID", "SOLID", "SOLID"
                                                                                                                                                                                                                                                                                                                                                                         ), fills_color = c("#5FBDDEFF", "#000000FF", "#000000FF", 
                                                                                                                                                                                                                                                                                                                                                                                            "#5FBDDEFF", "#B0B0B0FF", "#000000FF", "#000000FF", "#FDA6E3FF"
                                                                                                                                                                                                                                                                                                                                                                         ), strokes_blendMode = c("NORMAL", NA, NA, NA, NA, NA, NA, 
                                                                                                                                                                                                                                                                                                                                                                                                  NA), strokes_type = c("SOLID", NA, NA, NA, NA, NA, NA, NA
                                                                                                                                                                                                                                                                                                                                                                                                  ), strokes_color = c("#000000FF", NA, NA, NA, NA, NA, NA, 
                                                                                                                                                                                                                                                                                                                                                                                                                       NA), strokeDashes = c(TRUE, NA, NA, NA, NA, NA, NA, NA)), row.names = c(NA, 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               -8L), class = c("tbl_df", "tbl", "data.frame")))
  # end of long dput ----

  data_with_error_type <- toy_raw_file_content %>% 
    raw_to_design_tibble() %>% 
    dplyr::mutate(type = dplyr::case_when(
      element_name == "panel_background" ~ "TEXT",
      TRUE ~ element_name
    ))

  expect_error(data_with_error_type %>% add_ggplot_theme_type())

})

Determination of the {ggplot2} theme elements

#' Determine the ggplot2 theme elements.
#'
#' @param .data Tibble. An object returned by \code{architekter::\link{add_ggplot_theme_type}()}
#' 
#' @importFrom dplyr mutate case_when select rename
#' @importFrom cli cli_alert_success
#' 
#' @return A tibble with the values of the ggplot2 theme elements.
#' @export
determine_ggplot_theme_elements <- function(.data) {

  data_ggplot_theme_elements <- .data %>%
    # _family
    mutate(
      family = case_when(
        !is.na(fontPostScriptName) ~ fontPostScriptName,
        !is.na(fontFamily) ~ fontFamily,
        TRUE ~ NA_character_
      )
    ) %>% 
    select(-fontFamily, -fontPostScriptName, -fontWeight) %>% 
    # _size (depending if it is a text or not)
    mutate(
      size = case_when(
        element_type == "text" ~ fontSize,
        TRUE ~ strokeWeight
      )
    ) %>% 
    select(-fontSize, -strokeWeight, -textAutoResize) %>% 
    # _letter_spacing
    rename(letter_spacing = letterSpacing) %>% 
    # _lineheight
    rename(lineheight = lineHeightPx) %>% 
    select(-lineHeightPercent, -lineHeightUnit) %>% 
    # _hjust & vjust
    mutate(
      hjust = case_when(
        textAlignHorizontal == "LEFT" ~ 0,
        textAlignHorizontal == "CENTER" ~ 0.5,
        textAlignHorizontal == "RIGHT" ~ 1,
        TRUE ~ NA_real_
      )
    ) %>% 
    select(-textAlignHorizontal) %>% 
    mutate(
      hjust = case_when(
        textAlignVertical == "BOTTOM" ~ 0,
        textAlignVertical == "CENTER" ~ 0.5,
        textAlignVertical == "TOP" ~ 1,
        TRUE ~ NA_real_
      )
    ) %>% 
    select(-textAlignVertical) %>% 
    # _color
    mutate(
      color = case_when(
        element_type %in% c("rect", "line") ~ strokes_color,
        TRUE ~ fills_color
      )
    ) %>% 
    mutate(
      fill = case_when(
        element_type == "rect" ~ fills_color,
        TRUE ~ NA_character_
      )
    ) %>% 
    select(-fills_color, -strokes_color, -fills_blendMode, -strokes_blendMode) 
    # _linetype
    if ("strokeDashes" %in% colnames(data_ggplot_theme_elements)) {
      data_ggplot_theme_elements <- data_ggplot_theme_elements %>% 
        mutate(
          linetype = case_when(
            element_type %in% c("rect", "line") & strokeDashes == TRUE ~ "dashed",
            element_type %in% c("rect", "line") & is.na(strokeDashes) ~ "solid",
            TRUE ~ NA_character_
          )
        ) %>% 
        select(-strokeDashes, -strokes_type, -fills_type)
    } else {
      data_ggplot_theme_elements <- data_ggplot_theme_elements %>% 
        mutate(
          linetype = case_when(
            element_type %in% c("rect", "line") == TRUE ~ "solid",
            TRUE ~ NA_character_
          )
        ) %>% 
        select(-strokes_type, -fills_type)
    }

    cli_alert_success("The ggplot2 theme elements have been extracted.")

    return(data_ggplot_theme_elements)

}
data(toy_raw_file_content)

toy_raw_file_content %>% 
  raw_to_design_tibble() %>% 
  add_ggplot_theme_type() %>% 
  determine_ggplot_theme_elements()
test_that("determine_ggplot_theme_elements works", {

  data(toy_raw_file_content)

  result <- toy_raw_file_content %>% 
    raw_to_design_tibble() %>% 
    add_ggplot_theme_type() %>% 
    determine_ggplot_theme_elements()

  # long dput ----
  expect_equal(object = result, 
               expected = structure(list(element_name = c("panel_background", "legend_text", 
                                                          "legend_title", "panel_grid", "axis_text", "axis_title", "plot_subtitle", 
                                                          "plot_title"), element_type = c("rect", "text", "text", "line", 
                                                                                          "text", "text", "text", "text"), letter_spacing = c(NA, 0.36, 
                                                                                                                                              0.44, NA, 0, 0.44, 0.48, 0.8), lineheight = c(NA, 10.546875, 
                                                                                                                                                                                            12.890625, NA, 10.546875, 12.890625, 14.0625, 23.4375), family = c(NA, 
                                                                                                                                                                                                                                                               "Roboto", "Roboto", NA, "Roboto", "Roboto", "Roboto-Light", "Roboto-Light"
                                                                                                                                                                                            ), size = c(5, 9, 11, 1, 9, 11, 12, 20), hjust = c(NA, 1, 1, 
                                                                                                                                                                                                                                               NA, 1, 1, 1, 0), color = c("#000000FF", "#000000FF", "#000000FF", 
                                                                                                                                                                                                                                                                          NA, "#B0B0B0FF", "#000000FF", "#000000FF", "#FDA6E3FF"), fill = c("#5FBDDEFF", 
                                                                                                                                                                                                                                                                                                                                            NA, NA, NA, NA, NA, NA, NA), linetype = c("dashed", NA, NA, "solid", 
                                                                                                                                                                                                                                                                                                                                                                                      NA, NA, NA, NA)), row.names = c(NA, -8L), class = c("tbl_df", 
                                                                                                                                                                                                                                                                                                                                                                                                                                          "tbl", "data.frame")))

  # end of long dput ----

  expect_error(object = toy_raw_file_content %>% 
                 raw_to_design_tibble() %>% 
                 add_ggplot_theme_type() %>% 
                 determine_ggplot_theme_elements(), 
               regexp = NA)

})

Extract the {ggplot2} theme elements from a Figma file

#' Extract the {ggplot2} theme elements from a Figma file
#' 
#' @param .data List. An object returned by \code{architekter::\link{get_figma_file_content}()}
#' 
#' @return A tibble with the {ggplot2} theme elements extracted from the Figma file.
#' 
#' @export
extract_ggplot_theme <- function(.data) {

  .data %>% 
    raw_to_design_tibble() %>% 
    add_ggplot_theme_type() %>% 
    determine_ggplot_theme_elements()

}
data(toy_raw_file_content)

toy_raw_file_content %>% 
  extract_ggplot_theme()
test_that("extract_ggplot_theme works", {

  data(toy_raw_file_content)

  result <- toy_raw_file_content %>% 
    extract_ggplot_theme()

  # long dput ----
  expect_equal(object = result, 
               expected = structure(list(element_name = c("panel_background", "legend_text", 
                                                          "legend_title", "panel_grid", "axis_text", "axis_title", "plot_subtitle", 
                                                          "plot_title"), element_type = c("rect", "text", "text", "line", 
                                                                                          "text", "text", "text", "text"), letter_spacing = c(NA, 0.36, 
                                                                                                                                              0.44, NA, 0, 0.44, 0.48, 0.8), lineheight = c(NA, 10.546875, 
                                                                                                                                                                                            12.890625, NA, 10.546875, 12.890625, 14.0625, 23.4375), family = c(NA, 
                                                                                                                                                                                                                                                               "Roboto", "Roboto", NA, "Roboto", "Roboto", "Roboto-Light", "Roboto-Light"
                                                                                                                                                                                            ), size = c(5, 9, 11, 1, 9, 11, 12, 20), hjust = c(NA, 1, 1, 
                                                                                                                                                                                                                                               NA, 1, 1, 1, 0), color = c("#000000FF", "#000000FF", "#000000FF", 
                                                                                                                                                                                                                                                                          NA, "#B0B0B0FF", "#000000FF", "#000000FF", "#FDA6E3FF"), fill = c("#5FBDDEFF", 
                                                                                                                                                                                                                                                                                                                                            NA, NA, NA, NA, NA, NA, NA), linetype = c("dashed", NA, NA, "solid", 
                                                                                                                                                                                                                                                                                                                                                                                      NA, NA, NA, NA)), row.names = c(NA, -8L), class = c("tbl_df", 
                                                                                                                                                                                                                                                                                                                                                                                                                                          "tbl", "data.frame")))

  # end of long dput ----

  expect_error(object = toy_raw_file_content %>% 
                 extract_ggplot_theme(), 
               regexp = NA)

})
# Run but keep eval=FALSE to avoid infinite loop
# Execute in the console directly
fusen::inflate(flat_file = "dev/flat_figma_ggplot_correspondance.Rmd", 
               vignette_name = "d - Extract the {ggplot2} theme elements from a Figma file", 
               open_vignette = FALSE,
               check = FALSE,
               overwrite = TRUE)


ThinkR-open/swatch documentation built on April 7, 2022, 6:08 p.m.