feat: expand color system to 53 colors/10 palettes, add grid/slide themes, and README gallery
R-CMD-check / R CMD check (push) Successful in 3m41s
R-CMD-check / R CMD check (push) Successful in 3m41s
Replace the 16-color / 3-palette system with the full Civilytics design system: 53 named colors (full navy, ember, violet ramps plus teal, plum, moss, brass supporting hues) and 10 visualization palettes (qual, qual_warm, qual_cool, seq_ember, seq_navy, seq_violet, seq_paper_ink, div_navy_ember, div_violet_ember). Enrich theme_civilytics() with grid and paper_bg parameters, add theme_civilytics_slide() for presentations, and load all four brand fonts (Inter, Libre Franklin, Source Serif 4, JetBrains Mono). Add README.Rmd with rendered gallery showing all palettes, theme variants, grid options, dark/slide modes, facets, and scale usage.
This commit is contained in:
+122
-27
@@ -9,46 +9,67 @@ test_that("civilytics_colors is a named character vector of hex codes", {
|
||||
})
|
||||
|
||||
test_that("civilytics_colors contains expected brand keys", {
|
||||
expected <- c("paper", "ink", "accent", "navy", "navy_dark",
|
||||
"accent_dark", "paper_2", "rule")
|
||||
expected <- c("paper", "ink", "navy_600", "ember_600", "teal_600",
|
||||
"plum_600", "moss_600", "paper_2", "rule")
|
||||
expect_true(all(expected %in% names(civilytics_colors)))
|
||||
})
|
||||
|
||||
test_that("civilytics_colors values match brand specification", {
|
||||
expect_equal(unname(civilytics_colors["paper"]), "#FAF7F2")
|
||||
expect_equal(unname(civilytics_colors["ink"]), "#0E1A2B")
|
||||
expect_equal(unname(civilytics_colors["accent"]), "#C25311")
|
||||
expect_equal(unname(civilytics_colors["navy_dark"]), "#1A2E4A")
|
||||
expect_equal(unname(civilytics_colors["accent_dark"]),"#E07840")
|
||||
expect_equal(unname(civilytics_colors["ink"]), "#0E1A2B")
|
||||
expect_equal(unname(civilytics_colors["ember_600"]), "#C25311")
|
||||
expect_equal(unname(civilytics_colors["navy_700"]), "#1A2E4A")
|
||||
expect_equal(unname(civilytics_colors["ember_400"]), "#EA8A49")
|
||||
})
|
||||
|
||||
# --- civilytics_pal ----------------------------------------------------------
|
||||
# --- civilytics_palettes / civilytics_palette --------------------------------
|
||||
|
||||
test_that("civilytics_pal returns character vector of hex codes", {
|
||||
result <- civilytics_pal()
|
||||
test_that("civilytics_palettes contains all expected palettes", {
|
||||
expected <- c("qual", "qual_warm", "qual_cool",
|
||||
"seq_ember", "seq_navy", "seq_violet", "seq_paper_ink",
|
||||
"div_navy_ember", "div_violet_ember")
|
||||
expect_true(all(expected %in% names(civilytics_palettes)))
|
||||
})
|
||||
|
||||
test_that("civilytics_palette returns character vector of hex codes", {
|
||||
result <- civilytics_palette()
|
||||
expect_type(result, "character")
|
||||
expect_true(all(grepl("^#[0-9A-Fa-f]{6}$", result)))
|
||||
})
|
||||
|
||||
test_that("civilytics_pal respects n argument", {
|
||||
expect_length(civilytics_pal("main", n = 3), 3)
|
||||
expect_length(civilytics_pal("sequential", n = 5), 5)
|
||||
test_that("civilytics_palette respects n argument", {
|
||||
expect_length(civilytics_palette("qual", n = 3), 3)
|
||||
expect_length(civilytics_palette("seq_navy", n = 5), 5)
|
||||
})
|
||||
|
||||
test_that("civilytics_pal interpolates when n exceeds palette size", {
|
||||
result <- civilytics_pal("main", n = 10)
|
||||
expect_length(result, 10)
|
||||
test_that("civilytics_palette interpolates sequential palettes", {
|
||||
result <- civilytics_palette("seq_ember", n = 20)
|
||||
expect_length(result, 20)
|
||||
expect_true(all(grepl("^#[0-9A-Fa-f]{6}$", result)))
|
||||
})
|
||||
|
||||
test_that("civilytics_pal errors on unknown palette name", {
|
||||
expect_error(civilytics_pal("nope"), "'nope' is not a valid Civilytics palette")
|
||||
test_that("civilytics_palette warns when recycling qualitative", {
|
||||
expect_warning(civilytics_palette("qual", n = 10), "recycling")
|
||||
})
|
||||
|
||||
test_that("civilytics_pal supports all three named palettes", {
|
||||
expect_no_error(civilytics_pal("main"))
|
||||
expect_no_error(civilytics_pal("sequential"))
|
||||
expect_no_error(civilytics_pal("diverging"))
|
||||
test_that("civilytics_palette reverse works", {
|
||||
fwd <- civilytics_palette("seq_navy")
|
||||
rev <- civilytics_palette("seq_navy", reverse = TRUE)
|
||||
expect_equal(fwd, rev(rev))
|
||||
})
|
||||
|
||||
test_that("civilytics_palette errors on unknown palette name", {
|
||||
expect_error(civilytics_palette("nope"), "'nope' is not a valid palette")
|
||||
})
|
||||
|
||||
# --- civilytics_pal (closure) ------------------------------------------------
|
||||
|
||||
test_that("civilytics_pal returns a function", {
|
||||
f <- civilytics_pal()
|
||||
expect_type(f, "closure")
|
||||
result <- f(4)
|
||||
expect_length(result, 4)
|
||||
expect_true(all(grepl("^#[0-9A-Fa-f]{6}$", result)))
|
||||
})
|
||||
|
||||
# --- scale_color/fill_civilytics ---------------------------------------------
|
||||
@@ -59,7 +80,7 @@ test_that("scale_color_civilytics returns a Scale object (discrete)", {
|
||||
})
|
||||
|
||||
test_that("scale_color_civilytics returns a Scale object (continuous)", {
|
||||
sc <- scale_color_civilytics("sequential", discrete = FALSE)
|
||||
sc <- scale_color_civilytics("seq_navy", discrete = FALSE)
|
||||
expect_s3_class(sc, "Scale")
|
||||
})
|
||||
|
||||
@@ -69,7 +90,12 @@ test_that("scale_fill_civilytics returns a Scale object (discrete)", {
|
||||
})
|
||||
|
||||
test_that("scale_fill_civilytics returns a Scale object (continuous)", {
|
||||
sc <- scale_fill_civilytics("sequential", discrete = FALSE)
|
||||
sc <- scale_fill_civilytics("seq_ember", discrete = FALSE)
|
||||
expect_s3_class(sc, "Scale")
|
||||
})
|
||||
|
||||
test_that("scale_color_civilytics reverse parameter works", {
|
||||
sc <- scale_color_civilytics("qual", reverse = TRUE)
|
||||
expect_s3_class(sc, "Scale")
|
||||
})
|
||||
|
||||
@@ -128,6 +154,42 @@ test_that("theme_civilytics font_size parameter scales text elements", {
|
||||
expect_gt(th_big$text$size, th_sml$text$size)
|
||||
})
|
||||
|
||||
test_that("theme_civilytics grid parameter controls gridlines", {
|
||||
th_y <- theme_civilytics(grid = "y")
|
||||
th_x <- theme_civilytics(grid = "x")
|
||||
th_both <- theme_civilytics(grid = "both")
|
||||
th_none <- theme_civilytics(grid = "none")
|
||||
|
||||
# grid="y" shows y gridlines, blanks x
|
||||
expect_s3_class(th_y$panel.grid.major.y, "element_line")
|
||||
expect_s3_class(th_y$panel.grid.major.x, "element_blank")
|
||||
|
||||
# grid="x" shows x gridlines, blanks y
|
||||
expect_s3_class(th_x$panel.grid.major.x, "element_line")
|
||||
expect_s3_class(th_x$panel.grid.major.y, "element_blank")
|
||||
|
||||
# grid="both" shows both
|
||||
|
||||
expect_s3_class(th_both$panel.grid.major.x, "element_line")
|
||||
expect_s3_class(th_both$panel.grid.major.y, "element_line")
|
||||
|
||||
# grid="none" blanks both
|
||||
expect_s3_class(th_none$panel.grid.major.x, "element_blank")
|
||||
expect_s3_class(th_none$panel.grid.major.y, "element_blank")
|
||||
})
|
||||
|
||||
test_that("theme_civilytics paper_bg=FALSE gives transparent background", {
|
||||
th <- theme_civilytics(paper_bg = FALSE)
|
||||
expect_true(is.na(th$plot.background$fill))
|
||||
expect_true(is.na(th$panel.background$fill))
|
||||
})
|
||||
|
||||
test_that("theme_civilytics has plot-aligned title and caption", {
|
||||
th <- theme_civilytics()
|
||||
expect_equal(th$plot.title.position, "plot")
|
||||
expect_equal(th$plot.caption.position, "plot")
|
||||
})
|
||||
|
||||
# --- theme_civilytics_dark ---------------------------------------------------
|
||||
|
||||
test_that("theme_civilytics_dark returns a complete ggplot2 theme", {
|
||||
@@ -148,14 +210,47 @@ test_that("theme_civilytics_dark uses paper color as ink (light text on dark bg)
|
||||
expect_equal(th$text$colour, unname(civilytics_colors["paper"]))
|
||||
})
|
||||
|
||||
test_that("theme_civilytics_dark uses navy_dark as background", {
|
||||
test_that("theme_civilytics_dark uses navy_700 as background", {
|
||||
th <- theme_civilytics_dark()
|
||||
expect_equal(th$plot.background$fill, unname(civilytics_colors["navy_dark"]))
|
||||
expect_equal(th$plot.background$fill, unname(civilytics_colors["navy_700"]))
|
||||
})
|
||||
|
||||
test_that("theme_civilytics_dark uses navy for strip background", {
|
||||
test_that("theme_civilytics_dark uses navy_600 for strip background", {
|
||||
th <- theme_civilytics_dark()
|
||||
expect_equal(th$strip.background$fill, unname(civilytics_colors["navy"]))
|
||||
expect_equal(th$strip.background$fill, unname(civilytics_colors["navy_600"]))
|
||||
})
|
||||
|
||||
test_that("theme_civilytics_dark inherits grid parameter", {
|
||||
th <- theme_civilytics_dark(grid = "both")
|
||||
expect_s3_class(th$panel.grid.major.x, "element_line")
|
||||
expect_s3_class(th$panel.grid.major.y, "element_line")
|
||||
})
|
||||
|
||||
# --- theme_civilytics_slide --------------------------------------------------
|
||||
|
||||
test_that("theme_civilytics_slide returns a complete ggplot2 theme", {
|
||||
th <- theme_civilytics_slide()
|
||||
expect_s3_class(th, "theme")
|
||||
expect_true(attr(th, "complete"))
|
||||
})
|
||||
|
||||
test_that("theme_civilytics_slide has transparent background by default", {
|
||||
th <- theme_civilytics_slide()
|
||||
expect_true(is.na(th$plot.background$fill))
|
||||
})
|
||||
|
||||
test_that("theme_civilytics_slide uses larger base font", {
|
||||
th_slide <- theme_civilytics_slide()
|
||||
th_base <- theme_civilytics()
|
||||
expect_gt(th_slide$text$size, th_base$text$size)
|
||||
})
|
||||
|
||||
test_that("theme_civilytics_slide applies to a ggplot without error", {
|
||||
p <- ggplot(mpg, aes(displ, hwy, colour = class)) +
|
||||
geom_point() +
|
||||
scale_color_civilytics() +
|
||||
theme_civilytics_slide()
|
||||
expect_no_error(ggplot_build(p))
|
||||
})
|
||||
|
||||
# --- make_logo_grob ----------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user