Nothing
#' @title Set chart theme
#' @description Modify chart theme with function \code{set_theme}.
#' @param x an `ms_chart` object.
#' @param value a [mschart_theme()] object.
#' @examples
#' library(officer)
#' mytheme <- mschart_theme(
#' axis_title = fp_text(color = "red", font.size = 24, bold = TRUE),
#' grid_major_line_y = fp_border(width = 1, color = "orange"),
#' axis_ticks_y = fp_border(width = 0.4, color = "gray")
#' )
#'
#'
#' my_bc <- ms_barchart(
#' data = browser_data, x = "browser",
#' y = "value", group = "serie"
#' )
#' my_bc <- chart_settings(my_bc,
#' dir = "horizontal", grouping = "stacked",
#' gap_width = 150, overlap = 100
#' )
#' my_bc <- set_theme(my_bc, mytheme)
#'
#' my_bc_2 <- ms_barchart(
#' data = browser_data, x = "browser",
#' y = "value", group = "serie"
#' )
#' my_bc_2 <- chart_theme(my_bc_2,
#' grid_major_line_y = fp_border(width = 0.5, color = "cyan")
#' )
#'
#' # Manual legend layout: place the legend in the top-right corner
#' # using fractions of the chart area (0 to 1).
#' my_bc_3 <- ms_barchart(
#' data = browser_data, x = "browser",
#' y = "value", group = "serie"
#' )
#' my_bc_3 <- chart_theme(my_bc_3,
#' legend_position = "r",
#' legend_x = 0.80, legend_y = 0.15,
#' legend_w = 0.18, legend_h = 0.30
#' )
#' @return An `ms_chart` object.
#' @export
set_theme <- function(x, value) {
if (!inherits(value, "mschart_theme")) {
stop("value must be an mschart_theme object.", call. = FALSE)
}
x$theme <- value
x
}
#' helper class to check function input
#' @param x input argument to check
#' @param class a class to check against
#' @keywords internal
#' @noRd
assert_class <- function(x, class) {
if (!is.logical(x) && !inherits(x, class)) {
stop("input must be logical or ", class, " not ", x)
}
}
#' @importFrom officer fp_text fp_border
#' @description Use \code{mschart_theme()} to create a chart theme.
#' @param axis_title,axis_title_x,axis_title_y axis title formatting properties (see [officer::fp_text()])
#' @param main_title title formatting properties (see [officer::fp_text()])
#' @param legend_text legend text formatting properties (see [officer::fp_text()])
#' @param table_text table text formatting properties (see [officer::fp_text()])
#' @param axis_text,axis_text_x,axis_text_y axis text formatting properties (see [officer::fp_text()])
#' @param title_rot,title_x_rot,title_y_rot rotation angle
#' @param axis_ticks,axis_ticks_x,axis_ticks_y axis ticks formatting properties (see [officer::fp_border()])
#' @param grid_major_line,grid_major_line_x,grid_major_line_y major grid lines formatting properties (see [officer::fp_border()])
#' @param grid_minor_line,grid_minor_line_x,grid_minor_line_y minor grid lines formatting properties (see [officer::fp_border()])
#' @param plot_border plot area border lines formatting properties (see [officer::fp_border()])
#' @param chart_border chart area border lines formatting properties (see [officer::fp_border()])
#' @param plot_background plot area background fill color - single character value (e.g. "#000000" or "black")
#' @param chart_background chart area background fill color - single character value (e.g. "#000000" or "black")
#' @param date_fmt date format
#' @param str_fmt string or factor format
#' @param double_fmt double format
#' @param integer_fmt integer format
#' @param legend_position it specifies the position of the legend. It should be
#' one of 'b', 'tr', 'l', 'r', 't', 'n' (for 'none').
#' @param legend_x,legend_y,legend_w,legend_h optional fractions between
#' 0 and 1 to manually position and size the legend box within the chart
#' area. Each value is a fraction of the chart width (`legend_x`,
#' `legend_w`) or height (`legend_y`, `legend_h`). Any `NULL` value
#' keeps the default automatic layout; setting at least one triggers
#' manual placement via `<c:manualLayout>`.
#' @rdname set_theme
#' @return An `mschart_theme` object (for `mschart_theme()`).
#' @seealso [ms_barchart()], [ms_areachart()], [ms_scatterchart()], [ms_linechart()]
#' @export
mschart_theme <- function(
axis_title = fp_text(bold = TRUE, font.size = 16),
axis_title_x = axis_title,
axis_title_y = axis_title,
main_title = fp_text(bold = TRUE, font.size = 20),
legend_text = fp_text(font.size = 14),
table_text = fp_text(bold = FALSE, font.size = 9),
axis_text = fp_text(),
axis_text_x = axis_text,
axis_text_y = axis_text,
title_rot = 0,
title_x_rot = 0,
title_y_rot = 270,
axis_ticks = fp_border(color = "#99999999"),
axis_ticks_x = axis_ticks,
axis_ticks_y = axis_ticks,
grid_major_line = fp_border(color = "#99999999", style = "dashed"),
grid_major_line_x = grid_major_line,
grid_major_line_y = grid_major_line,
grid_minor_line = fp_border(width = 0),
grid_minor_line_x = grid_minor_line,
grid_minor_line_y = grid_minor_line,
chart_background = NULL,
chart_border = fp_border(color = "transparent"),
plot_background = NULL,
plot_border = fp_border(color = "transparent"),
date_fmt = "yyyy/mm/dd",
str_fmt = "General",
double_fmt = "#,##0.00",
integer_fmt = "0",
legend_position = "b",
legend_x = NULL,
legend_y = NULL,
legend_w = NULL,
legend_h = NULL
) {
# strict check: these must be fp_text objects
stopifnot(inherits(main_title, "fp_text"))
stopifnot(inherits(table_text, "fp_text"))
stopifnot(inherits(legend_text, "fp_text"))
stopifnot(inherits(axis_title, "fp_text"))
stopifnot(inherits(axis_title_x, "fp_text"))
stopifnot(inherits(axis_title_y, "fp_text"))
stopifnot(inherits(axis_text, "fp_text"))
stopifnot(inherits(axis_text_x, "fp_text"))
stopifnot(inherits(axis_text_y, "fp_text"))
# strict check: these must be fp_border objects
stopifnot(inherits(axis_ticks, "fp_border"))
stopifnot(inherits(axis_ticks_x, "fp_border"))
stopifnot(inherits(axis_ticks_y, "fp_border"))
# assert_class: accept fp_border or logical (FALSE to disable the grid line)
assert_class(grid_major_line, "fp_border")
assert_class(grid_major_line_x, "fp_border")
assert_class(grid_major_line_y, "fp_border")
assert_class(grid_minor_line, "fp_border")
assert_class(grid_minor_line_x, "fp_border")
assert_class(grid_minor_line_y, "fp_border")
# strict check: these must be fp_border objects
stopifnot(inherits(chart_border, "fp_border"))
stopifnot(inherits(plot_border, "fp_border"))
if (title_rot < 0 || title_rot > 359) {
stop("title_rot must be between 0 and 359")
}
if (title_x_rot < 0 || title_x_rot > 359) {
stop("title_x_rot must be between 0 and 359")
}
if (title_y_rot < 0 || title_y_rot > 359) {
stop("title_y_rot must be between 0 and 359")
}
if (!legend_position %in% st_legendpos) {
stop(
"legend_position should be one of ",
paste0(shQuote(st_legendpos), collapse = ", ")
)
}
validate_legend_fraction(legend_x, "legend_x")
validate_legend_fraction(legend_y, "legend_y")
validate_legend_fraction(legend_w, "legend_w")
validate_legend_fraction(legend_h, "legend_h")
out <- list(
main_title = main_title,
legend_text = legend_text,
table_text = table_text,
axis_title_x = axis_title_x,
axis_title_y = axis_title_y,
title_rot = title_rot,
title_x_rot = title_x_rot,
title_y_rot = title_y_rot,
axis_text_x = axis_text_x,
axis_text_y = axis_text_y,
axis_ticks_x = axis_ticks_x,
axis_ticks_y = axis_ticks_y,
grid_major_line_x = grid_major_line_x,
grid_major_line_y = grid_major_line_y,
grid_minor_line_x = grid_minor_line_x,
grid_minor_line_y = grid_minor_line_y,
chart_background = chart_background,
chart_border = chart_border,
plot_background = plot_background,
plot_border = plot_border,
legend_position = legend_position,
date_fmt = date_fmt,
str_fmt = str_fmt,
double_fmt = double_fmt,
integer_fmt = integer_fmt,
legend_x = legend_x,
legend_y = legend_y,
legend_w = legend_w,
legend_h = legend_h
)
class(out) <- "mschart_theme"
out
}
validate_legend_fraction <- function(value, name) {
if (is.null(value)) {
return(invisible(NULL))
}
if (
!is.numeric(value) ||
length(value) != 1 ||
is.na(value) ||
value < 0 ||
value > 1
) {
stop(
"`",
name,
"` must be NULL or a single numeric value between 0 and 1.",
call. = FALSE
)
}
}
#' @rdname set_theme
#' @return An `ms_chart` object (for `set_theme()` and `chart_theme()`).
#' @export
#' @description Use \code{chart_theme()} to modify components of the theme of a chart.
chart_theme <- function(
x,
axis_title_x,
axis_title_y,
main_title,
legend_text,
title_rot,
title_x_rot,
title_y_rot,
axis_text_x,
axis_text_y,
axis_ticks_x,
axis_ticks_y,
grid_major_line_x,
grid_major_line_y,
grid_minor_line_x,
grid_minor_line_y,
chart_background,
chart_border,
plot_background,
plot_border,
date_fmt,
str_fmt,
double_fmt,
integer_fmt,
legend_position,
legend_x,
legend_y,
legend_w,
legend_h
) {
if (!missing(axis_title_x)) {
if (!all(class(axis_title_x) %in% class(x$theme$axis_title_x))) {
stop("axis_title_x should be of class ", class(x$theme$axis_title_x))
}
x$theme$axis_title_x <- axis_title_x
}
if (!missing(axis_title_y)) {
if (!all(class(axis_title_y) %in% class(x$theme$axis_title_y))) {
stop("axis_title_y should be of class ", class(x$theme$axis_title_y))
}
x$theme$axis_title_y <- axis_title_y
}
if (!missing(legend_text)) {
if (!all(class(legend_text) %in% class(x$theme$legend_text))) {
stop("legend_text should be of class ", class(x$theme$legend_text))
}
x$theme$legend_text <- legend_text
}
if (!missing(main_title)) {
if (!all(class(main_title) %in% class(x$theme$main_title))) {
stop("main_title should be of class ", class(x$theme$main_title))
}
x$theme$main_title <- main_title
}
if (!missing(axis_text_x)) {
if (!all(class(axis_text_x) %in% class(x$theme$axis_text_x))) {
stop("axis_text_x should be of class ", class(x$theme$axis_text_x))
}
x$theme$axis_text_x <- axis_text_x
}
if (!missing(axis_text_y)) {
if (!all(class(axis_text_y) %in% class(x$theme$axis_text_y))) {
stop("axis_text_y should be of class ", class(x$theme$axis_text_y))
}
x$theme$axis_text_y <- axis_text_y
}
if (!missing(axis_ticks_x)) {
if (!all(class(axis_ticks_x) %in% class(x$theme$axis_ticks_x))) {
stop("axis_ticks_x should be of class ", class(x$theme$axis_ticks_x))
}
x$theme$axis_ticks_x <- axis_ticks_x
}
if (!missing(axis_ticks_y)) {
if (!all(class(axis_ticks_y) %in% class(x$theme$axis_ticks_y))) {
stop("axis_ticks_y should be of class ", class(x$theme$axis_ticks_y))
}
x$theme$axis_ticks_y <- axis_ticks_y
}
if (!missing(grid_major_line_x)) {
assert_class(grid_major_line_x, class(x$theme$grid_major_line_x))
x$theme$grid_major_line_x <- grid_major_line_x
}
if (!missing(grid_major_line_y)) {
assert_class(grid_major_line_y, class(x$theme$grid_major_line_y))
x$theme$grid_major_line_y <- grid_major_line_y
}
if (!missing(grid_minor_line_x)) {
if (!all(class(grid_minor_line_x) %in% class(x$theme$grid_minor_line_x))) {
stop(
"grid_minor_line_x should be of class ",
class(x$theme$grid_minor_line_x)
)
}
x$theme$grid_minor_line_x <- grid_minor_line_x
}
if (!missing(grid_minor_line_y)) {
if (!all(class(grid_minor_line_y) %in% class(x$theme$grid_minor_line_y))) {
stop(
"grid_minor_line_y should be of class ",
class(x$theme$grid_minor_line_y)
)
}
x$theme$grid_minor_line_y <- grid_minor_line_y
}
if (!missing(chart_border)) {
if (!all(class(chart_border) %in% class(x$theme$chart_border))) {
stop("chart_border should be of class ", class(x$theme$chart_border))
}
x$theme$chart_border <- chart_border
}
if (!missing(plot_border)) {
if (!all(class(plot_border) %in% class(x$theme$plot_border))) {
stop("plot_border should be of class ", class(x$theme$plot_border))
}
x$theme$plot_border <- plot_border
}
if (!missing(date_fmt)) {
if (!all(class(date_fmt) %in% class(x$theme$date_fmt))) {
stop("date_fmt should be of class ", class(x$theme$date_fmt))
}
x$theme$date_fmt <- date_fmt
}
if (!missing(str_fmt)) {
if (!all(class(str_fmt) %in% class(x$theme$str_fmt))) {
stop("str_fmt should be of class ", class(x$theme$str_fmt))
}
x$theme$str_fmt <- str_fmt
}
if (!missing(double_fmt)) {
if (!all(class(double_fmt) %in% class(x$theme$double_fmt))) {
stop("double_fmt should be of class ", class(x$theme$double_fmt))
}
x$theme$double_fmt <- double_fmt
}
if (!missing(integer_fmt)) {
if (!all(class(integer_fmt) %in% class(x$theme$integer_fmt))) {
stop("integer_fmt should be of class ", class(x$theme$integer_fmt))
}
x$theme$integer_fmt <- integer_fmt
}
if (!missing(legend_position)) {
if (!legend_position %in% st_legendpos) {
stop(
"legend_position should be one of ",
paste0(shQuote(st_legendpos), collapse = ", ")
)
}
x$theme$legend_position <- legend_position
}
if (!missing(legend_x)) {
validate_legend_fraction(legend_x, "legend_x")
x$theme$legend_x <- legend_x
}
if (!missing(legend_y)) {
validate_legend_fraction(legend_y, "legend_y")
x$theme$legend_y <- legend_y
}
if (!missing(legend_w)) {
validate_legend_fraction(legend_w, "legend_w")
x$theme$legend_w <- legend_w
}
if (!missing(legend_h)) {
validate_legend_fraction(legend_h, "legend_h")
x$theme$legend_h <- legend_h
}
if (!missing(title_rot)) {
if (title_rot < 0 && title_rot > 359) {
stop("title_rot must be between 0 and 359")
}
x$theme$title_rot <- title_rot
}
if (!missing(title_x_rot)) {
if (title_x_rot < 0 && title_x_rot > 359) {
stop("title_x_rot must be between 0 and 359")
}
x$theme$title_x_rot <- title_x_rot
}
if (!missing(title_y_rot)) {
if (title_y_rot < 0 && title_y_rot > 359) {
stop("title_y_rot must be between 0 and 359")
}
x$theme$title_y_rot <- title_y_rot
}
x
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.