---
title: "Advanced Customization"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Advanced Customization}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.width = 7,
  fig.height = 5
)
```

## Introduction

This vignette dives deeper into BFHtheme for users who need more than the
out-of-the-box defaults. You will learn how to:

- fine-tune theme parameters and override individual elements,
- craft bespoke colour palettes and gradients,
- add BFH-branded annotations such as footers, logos, and colour bars,
- organise multi-panel figures, and
- optimise fonts and performance for production workflows.

| Customisation area | Key functions |
| --- | --- |
| Theme tweaks | `theme_bfh_*()`, `theme()` |
| Colours & palettes | `bfh_cols()`, `bfh_pal()`, `scale_*_bfh_*()` |
| Branding elements | `add_bfh_logo()`, `add_bfh_footer()` |
| Layout helpers | `bfh_combine_plots()`, `bfh_save()` |

```{r load, message=FALSE}
library(BFHtheme)
library(ggplot2)
```

## Theme Customization

### Modifying Base Theme Parameters

All BFH themes expose the standard ggplot2 base arguments. Adjust them to fit
specific deliverables—larger fonts for accessibility, a fixed typeface for
compliance, or heavier lines for print.

```{r theme-params}
ggplot(mtcars, aes(x = wt, y = mpg)) +
  geom_point() +
  labs(title = "Custom Base Size") +
  theme_bfh(
    base_size = 14,           # Larger text
    base_family = "Arial",    # Specific font
    base_line_size = 0.6,     # Thicker lines
    base_rect_size = 0.6      # Thicker rectangles
  )
```

### Overriding Theme Elements

Layer additional ggplot2 theme calls on top of the BFH defaults to fine-tune
individual components such as titles, panels, or grids.

```{r theme-override}
ggplot(mtcars, aes(x = wt, y = mpg)) +
  geom_point() +
  labs(title = "Custom Theme Elements") +
  theme_bfh() +
  theme(
    plot.title = element_text(color = bfh_cols("hospital_blue"), size = 18),
    axis.title.x = element_text(face = "bold"),
    panel.grid.major = element_line(color = "grey90", linewidth = 0.3)
  )
```

### Legend Customisation

Legends inherit BFH styling but can be repositioned or reformatted to suit the
layout.

```{r legend-custom}
ggplot(mtcars, aes(x = wt, y = mpg, color = factor(cyl))) +
  geom_point(size = 3) +
  labs(
    title = "Custom Legend Position",
    color = "Cylinders"
  ) +
  scale_color_bfh() +
  theme_bfh() +
  theme(
    legend.position = "top",
    legend.direction = "horizontal",
    legend.box = "horizontal"
  )
```

## Colour Palette Customisation

### Using Different Palettes

Switch palettes dynamically to emphasise different aspects of the brand.

```{r palettes}
p <- ggplot(mtcars, aes(x = factor(cyl), fill = factor(cyl))) +
  geom_bar() +
  labs(title = "Hospital Blues Palette") +
  theme_bfh()

p + scale_fill_bfh(palette = "hospital_blues")
```

### Reversing Palettes

Reverse the palette order when a gradient needs to flow in the opposite
direction.

```{r reverse-palette}
ggplot(mtcars, aes(x = wt, y = mpg, color = hp)) +
  geom_point(size = 3) +
  labs(title = "Reversed Colour Scale") +
  scale_color_bfh_continuous(palette = "blues", reverse = TRUE) +
  theme_bfh()
```

### Creating Custom Palettes

Combine individual colours or build a bespoke gradient with `bfh_pal()` to match
department-specific requirements.

```{r custom-palette}
# Create a custom palette with specific colours
custom_colors <- c(
  bfh_cols("hospital_primary"),
  bfh_cols("regionh_grey"),
  bfh_cols("regionh_primary")
)

ggplot(mtcars, aes(x = factor(cyl), fill = factor(cyl))) +
  geom_bar() +
  labs(title = "Custom Colour Selection") +
  scale_fill_manual(values = custom_colors) +
  theme_bfh()
```

### Working with Colour Functions

Use `bfh_pal()` to generate smooth gradients or truncate palettes for a precise
number of categories.

```{r palette-function}
# Generate colour ramp
blues_pal <- bfh_pal("hospital_blues")

# Use in continuous scale
ggplot(faithfuld, aes(waiting, eruptions, fill = density)) +
  geom_tile() +
  scale_fill_gradientn(colours = blues_pal(100)) +
  theme_bfh()
```

## Plot Enhancements

Extend a finished plot with branded components and annotations to convey
context, ownership, or emphasis without redesigning the underlying chart.

### Adding BFH Branding

Anchor a plot with official branding using `add_bfh_footer()`:

```{r footer, eval=FALSE}
p <- ggplot(mtcars, aes(x = wt, y = mpg)) +
  geom_point() +
  theme_bfh()

add_bfh_footer(
  p,
  text = "Bispebjerg og Frederiksberg Hospital - 2024",
  color = bfh_cols("hospital_primary")
)
```

### Multi-Panel Figures

Combine multiple plots with a shared legend for consistent storytelling:

```{r multi-panel, eval=FALSE}
library(patchwork)

p1 <- ggplot(mtcars, aes(wt, mpg, color = factor(cyl))) +
  geom_point() +
  labs(title = "Weight vs MPG") +
  scale_color_bfh() +
  theme_bfh()

p2 <- ggplot(mtcars, aes(hp, mpg, color = factor(cyl))) +
  geom_point() +
  labs(title = "Horsepower vs MPG") +
  scale_color_bfh() +
  theme_bfh()

# Combine with shared legend
p1 + p2 + plot_layout(guides = "collect") &
  theme(legend.position = "bottom")
```

Alternatively, call the BFH helper directly:

```{r combine-plots, eval=FALSE}
plots <- list(p1, p2)
bfh_combine_plots(plots, ncol = 2, legend_position = "bottom")
```

## Axis Customisation

### Formatting Axes

Tidy up axes with breaks, limits, and units that match your narrative:

```{r axis-format}
ggplot(mtcars, aes(x = wt, y = mpg)) +
  geom_point() +
  labs(
    title = "Custom Axis Formatting",
    x = "Vehicle Weight (1000 lbs)",
    y = "Fuel Efficiency (MPG)"
  ) +
  scale_y_continuous(
    breaks = seq(10, 35, 5),
    limits = c(10, 35)
  ) +
  theme_bfh()
```

### Date Axes

For time-series data, combine date scales with BFH colours:

```{r date-axis, eval=FALSE}
library(lubridate)

date_data <- data.frame(
  date = seq(as.Date("2024-01-01"), by = "month", length.out = 12),
  value = cumsum(rnorm(12, 10, 3))
)

ggplot(date_data, aes(x = date, y = value)) +
  geom_line(color = bfh_cols("hospital_primary"), linewidth = 1) +
  labs(
    title = "Monthly Trends",
    x = "Month",
    y = "Value"
  ) +
  scale_x_date(
    date_breaks = "2 months",
    date_labels = "%b %Y"
  ) +
  theme_bfh()
```

## Text and Labels

Typography and copy tone are central to the BFH identity. These helpers keep
labels consistent while still giving you room for context-specific annotations.

### Uppercase Labels

Use `bfh_labs()` to align subtitles, axis titles, and captions with the
uppercase convention while preserving the main title casing:

```{r uppercase-labels}
ggplot(mtcars, aes(x = wt, y = mpg)) +
  geom_point() +
  bfh_labs(
    title = "Fuel efficiency analysis",      # Title unchanged
    subtitle = "Motor trend data",            # Converted to uppercase
    x = "weight (1000 lbs)",                  # Converted to uppercase
    y = "miles per gallon",                   # Converted to uppercase
    caption = "Source: Motor Trend, 1974"     # Converted to uppercase
  ) +
  theme_bfh()
```

### Uppercase Axis Tick Labels

For complete typographic consistency, use the position scale functions to
convert axis tick labels (the actual values on the axes) to uppercase. This
is particularly useful for date labels and categorical data:

```{r uppercase-axis-labels}
# Discrete/categorical data with uppercase labels
ggplot(mtcars, aes(x = factor(cyl), y = mpg)) +
  geom_boxplot() +
  scale_x_discrete_bfh() +  # "4" becomes "4", but categories like "low" become "LOW"
  bfh_labs(
    title = "Fuel efficiency by cylinder count",
    x = "cylinders",
    y = "miles per gallon"
  ) +
  theme_bfh()

# Date data with uppercase month labels
df <- data.frame(
  date = seq.Date(as.Date("2023-01-01"), as.Date("2023-12-31"), by = "month"),
  value = rnorm(12, mean = 100, sd = 10)
)

ggplot(df, aes(x = date, y = value)) +
  geom_line(color = bfh_cols("hospital_primary"), linewidth = 1) +
  scale_x_date_bfh(date_labels = "%b %Y") +  # "Jan 2023" becomes "JAN 2023"
  scale_y_continuous_bfh() +
  bfh_labs(
    title = "Monthly trends",
    x = "month",
    y = "value"
  ) +
  theme_bfh()
```

The available position scale functions with uppercase support are:

- `scale_x_continuous_bfh()` / `scale_y_continuous_bfh()` - For numeric axes
- `scale_x_discrete_bfh()` / `scale_y_discrete_bfh()` - For categorical data
- `scale_x_date_bfh()` / `scale_y_date_bfh()` - For date axes
- `scale_x_datetime_bfh()` / `scale_y_datetime_bfh()` - For datetime axes

All functions accept a custom `labels` argument if you need different formatting.

### Advanced: Integration with scales Package

The BFH position scales integrate seamlessly with the `scales` package for
even smarter formatting. You can use `breaks_pretty()` for intelligent break
positioning and any `label_*()` function—output is automatically uppercased:

```{r scales-integration}
library(scales)

# Use label_date_short() for compact, hierarchical labels
ggplot(df, aes(x = date, y = value)) +
  geom_line(color = bfh_cols("hospital_primary"), linewidth = 1) +
  scale_x_date_bfh(
    breaks = breaks_pretty(n = 8),           # Smart break positioning
    labels = label_date_short()              # Compact labels (auto-uppercased)
  ) +
  bfh_labs(
    title = "Compact date labels with breaks_pretty",
    x = "date",
    y = "value"
  ) +
  theme_bfh()

# Combine custom formatting with breaks
ggplot(df, aes(x = date, y = value)) +
  geom_line(color = bfh_cols("hospital_blue"), linewidth = 1) +
  scale_x_date_bfh(
    breaks = breaks_width("2 months"),       # Break every 2 months
    labels = label_date("%B")                # Full month names (uppercased)
  ) +
  bfh_labs(
    title = "Full month names with custom breaks",
    x = "month",
    y = "value"
  ) +
  theme_bfh()
```

**Useful scales functions:**

- `breaks_pretty(n)` - Pretty breaks with desired count
- `breaks_width("2 weeks")` - Breaks at regular intervals
- `label_date("%b %Y")` - Custom date format
- `label_date_short()` - Compact hierarchical labels
- `label_time()` - Time formatting

### Best Practice: label_date_short() for Space Efficiency

The `label_date_short()` function is particularly powerful for time series with
many data points. It creates a hierarchical labeling system that only shows
what has changed, dramatically reducing horizontal space requirements:

```{r label-date-short-example}
# Standard labels - repetitive and space-consuming
ggplot(df, aes(x = date, y = value)) +
  geom_line(color = bfh_cols("hospital_primary"), linewidth = 1) +
  scale_x_date_bfh(
    date_breaks = "2 months",
    labels = label_date("%b %Y")  # "JAN. 2023", "MAR. 2023", etc.
  ) +
  bfh_labs(title = "Standard labels", x = "date", y = "value") +
  theme_bfh() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))  # Rotation needed!

# label_date_short() - compact and hierarchical
ggplot(df, aes(x = date, y = value)) +
  geom_line(color = bfh_cols("hospital_primary"), linewidth = 1) +
  scale_x_date_bfh(
    date_breaks = "2 months",
    labels = label_date_short()  # Shows year only when it changes
  ) +
  bfh_labs(title = "Compact hierarchical labels", x = "date", y = "value") +
  theme_bfh()  # No rotation needed!
```

**Recommended combinations based on data duration:**

```{r eval=FALSE}
# Short time series (< 1 year)
scale_x_date_bfh()  # Default is fine

# Medium time series (1-3 years)
scale_x_date_bfh(
  breaks = breaks_pretty(n = 6),
  labels = label_date_short()
)

# Long time series (> 3 years)
scale_x_date_bfh(
  breaks = breaks_pretty(n = 8),
  labels = label_date_short()
)

# Weekly data
scale_x_date_bfh(
  breaks = breaks_width("2 weeks"),
  labels = label_date_short()
)
```

### Custom Text Elements

Layer additional annotations for storytelling while staying within the BFH
colour system:

```{r annotations}
ggplot(mtcars, aes(x = wt, y = mpg)) +
  geom_point() +
  annotate(
    "text",
    x = 4.5, y = 30,
    label = "High efficiency zone",
    color = bfh_cols("hospital_primary"),
    size = 4
  ) +
  annotate(
    "rect",
    xmin = 1.5, xmax = 3.5,
    ymin = 25, ymax = 35,
    alpha = 0.1,
    fill = bfh_cols("hospital_blue")
  ) +
  labs(title = "Annotated Plot") +
  theme_bfh()
```

## Faceting

Facets inherit BFH defaults, but subtle tweaks can make multi-panel layouts feel
polished and balanced.

### Facet Customisation

Adjust strip backgrounds and text to reinforce brand colours:

```{r facets}
ggplot(mtcars, aes(x = wt, y = mpg)) +
  geom_point(color = bfh_cols("hospital_primary")) +
  facet_wrap(~cyl, labeller = labeller(cyl = function(x) paste(x, "cylinders"))) +
  labs(title = "Fuel Efficiency by Cylinder Count") +
  theme_bfh() +
  theme(
    strip.background = element_rect(fill = bfh_cols("hospital_light_blue1")),
    strip.text = element_text(color = bfh_cols("hospital_primary"), face = "bold")
  )
```

## Export and File Formats

Produce publication-ready figures while keeping file sizes manageable.

### High-Resolution Export

Use `bfh_save()` presets for common outputs, or override the size when you need
an exact width and height.

```{r export, eval=FALSE}
p <- ggplot(mtcars, aes(x = wt, y = mpg)) +
  geom_point() +
  theme_bfh()

# High-resolution PNG
bfh_save("figure.png", p, preset = "report_full", dpi = 600)

# Vector format for editing
bfh_save("figure.pdf", p, preset = "report_full")

# Custom dimensions
bfh_save("figure.png", p, width = 10, height = 8, units = "cm", dpi = 300)
```

### Dimension Presets

Query the recommended sizes directly from the helper for reproducible reporting:

```{r dimensions}
# Get dimensions for different output types (internal function)
report_dims <- BFHtheme:::get_bfh_dimensions(type = "report", format = "standard")
print(report_dims)

presentation_dims <- BFHtheme:::get_bfh_dimensions(type = "presentation", format = "wide")
print(presentation_dims)
```

## Performance Optimisation

Keep your workflow responsive when working with fonts or large datasets.

### Font Caching

Font detection results are cached for speed. Clear or refresh the cache after
adding or removing fonts mid-session:

```{r cache, eval=FALSE}
# Font detection is cached automatically
get_bfh_font()  # First call: detects font
get_bfh_font()  # Subsequent calls: uses cache

# Clear cache if needed
clear_bfh_font_cache()

# Force re-detection
get_bfh_font(force_refresh = TRUE)
```

### Large Datasets

High-volume data can strain rendering. Consider these approaches:

```{r performance, eval=FALSE}
# Use alpha for overplotting
ggplot(large_data, aes(x, y)) +
  geom_point(alpha = 0.3) +
  theme_bfh()

# Use geom_hex or geom_bin2d
ggplot(large_data, aes(x, y)) +
  geom_hex() +
  scale_fill_bfh_continuous(palette = "blues") +
  theme_bfh()

# Reduce point size
ggplot(large_data, aes(x, y)) +
  geom_point(size = 0.5) +
  theme_bfh()
```

## Wrap-Up

- Revisit `vignette("getting-started")` for the foundational workflow.
- Explore `vignette("theming")` when you need hospital vs Region H branding.
- Consult the function reference (`help(package = "BFHtheme")`) for parameter details.
