--- title: "Transforms & Theming" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Transforms & Theming} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) library(myIO) ``` ## Transforms Transforms derive new data from an existing layer before rendering. You specify a transform with the `transform` argument in `addIoLayer()`. ### Available Transforms | Transform | Description | Used by | |-----------|-------------|---------| | `"identity"` | Default. Passes data through unchanged. | All types | | `"lm"` | Fits a linear model and returns fitted values. | `line` | | `"loess"` | LOESS non-linear smoothing. Options: `span`, `degree`, `n_grid`. | `line` | | `"polynomial"` | Polynomial regression. Options: `degree`, `n_grid`. | `line` | | `"ci"` | Confidence or prediction interval band. Options: `method`, `level`, `interval`. | `area` | | `"smooth"` | Simple or exponential moving average. Options: `method` (`"sma"`/`"ema"`), `window`, `alpha`. | `line` | | `"mean"` | Group mean aggregation. | `point`, `bar` | | `"mean_ci"` | Group mean ± confidence interval. Options: `level`, `method` (`"t"`/`"se"`). | `rangeBar` | | `"residuals"` | Regression residuals vs. fitted values. Options: `method`. | `point` | | `"summary"` | General aggregation. Options: `stat` (`"count"`/`"sum"`/`"sd"`/`"var"`/`"min"`/`"max"`). | `point`, `bar` | | `"cumulative"` | Computes running totals with base/cumulative columns. | `waterfall` (auto-applied) | | `"quantiles"` | Computes Q1, median, Q3, whisker bounds per group. | `boxplot` (internal) | | `"median"` | Computes group medians. | `boxplot`, `violin` (internal) | | `"outliers"` | Returns rows beyond 1.5x IQR fences. | `boxplot` (internal) | | `"density"` | Kernel density estimation via `stats::density()`. | `violin`, `ridgeline` (internal) | Transforms marked "internal" are applied automatically by composite chart types. The first 10 transforms are user-facing — use them directly in `addIoLayer()`. ### Linear Model Trend Line Add a trend line to a scatter plot by combining a `"point"` layer with a `"line"` layer that uses `transform = "lm"`: ```{r lm-example, eval = FALSE} myIO() |> addIoLayer( type = "point", color = "#E69F00", label = "points", data = mtcars, mapping = list(x_var = "wt", y_var = "mpg") ) |> addIoLayer( type = "line", transform = "lm", color = "red", label = "trend", data = mtcars, mapping = list(x_var = "wt", y_var = "mpg") ) ``` The `lm` transform fits `y ~ x` using `stats::lm()` and replaces the y values with the fitted values. The resulting line is sorted by x so it renders as a smooth trend. ### Cumulative Transform (Waterfall) The `"cumulative"` transform is auto-applied when you use `type = "waterfall"`. It computes running totals and produces `_base_y` and `_cumulative_y` columns that the waterfall renderer uses for floating bars: ```{r cumulative-example, eval = FALSE} df <- data.frame( step = c("Start", "Sales", "Returns", "Total"), value = c(100, 50, -20, NA), is_total = c(FALSE, FALSE, FALSE, TRUE) ) myIO() |> addIoLayer( type = "waterfall", label = "bridge", data = df, mapping = list(x_var = "step", y_var = "value", total = "is_total") ) |> defineCategoricalAxis(xAxis = TRUE) ``` ### Confidence Interval Band Overlay a confidence interval on a scatter plot: ```{r ci-example, eval = FALSE} myIO(data = mtcars) |> addIoLayer(type = "point", color = "#4E79A7", label = "Data", mapping = list(x_var = "wt", y_var = "mpg")) |> addIoLayer(type = "line", color = "#E15759", label = "Trend", transform = "lm", mapping = list(x_var = "wt", y_var = "mpg")) |> addIoLayer(type = "area", color = "#E15759", label = "95% CI", transform = "ci", mapping = list(x_var = "wt", y_var = "mpg"), options = list(level = 0.95)) ``` The `ci` transform accepts `method` (`"lm"` or `"loess"`), `level` (default 0.95), and `interval` (`"confidence"` or `"prediction"`). The mapping only needs `x_var` and `y_var` — `low_y`/`high_y` are auto-injected. ### LOESS Smoothing Non-linear smoothing with adjustable span: ```{r loess-example, eval = FALSE} myIO(data = mtcars) |> addIoLayer(type = "point", color = "#4E79A7", label = "Data", mapping = list(x_var = "wt", y_var = "mpg")) |> addIoLayer(type = "line", color = "#E15759", label = "LOESS", transform = "loess", mapping = list(x_var = "wt", y_var = "mpg"), options = list(span = 0.5)) ``` ### Mean ± CI Error Bars Group means with confidence intervals: ```{r mean-ci-example, eval = FALSE} myIO(data = iris) |> addIoLayer(type = "rangeBar", color = "#4E79A7", label = "Mean ± 95% CI", transform = "mean_ci", mapping = list(x_var = "Species", y_var = "Sepal.Length"), options = list(level = 0.95)) |> defineCategoricalAxis(xAxis = TRUE) ``` ### Regression Composite One-call scatter + trend + CI + R²: ```{r regression-composite, eval = FALSE} myIO(data = mtcars) |> addIoLayer(type = "regression", label = "MPG vs Weight", mapping = list(x_var = "wt", y_var = "mpg"), options = list(method = "lm", showCI = TRUE, showStats = TRUE)) ``` ### Moving Average ```{r smooth-example, eval = FALSE} df <- data.frame(x = 1:100, y = cumsum(rnorm(100))) myIO(data = df) |> addIoLayer(type = "line", color = "#CCCCCC", label = "Raw", mapping = list(x_var = "x", y_var = "y")) |> addIoLayer(type = "line", color = "#E15759", label = "SMA-10", transform = "smooth", mapping = list(x_var = "x", y_var = "y"), options = list(method = "sma", window = 10)) ``` Use `method = "ema"` with `alpha` for exponential moving average. ### Transform + Type Compatibility Not every transform works with every chart type. The table below shows valid combinations: | Type | Supported Transforms | |------|---------------------| | `"line"` | `"identity"`, `"lm"`, `"loess"`, `"polynomial"`, `"smooth"` | | `"point"` | `"identity"`, `"mean"`, `"summary"`, `"residuals"` | | `"bar"` | `"identity"`, `"mean"`, `"summary"` | | `"area"` | `"identity"`, `"ci"` | | `"rangeBar"` | `"identity"`, `"mean_ci"` | | `"groupedBar"` | `"identity"` | | `"histogram"` | `"identity"` | | `"hexbin"` | `"identity"` | | `"treemap"` | `"identity"` | | `"donut"` | `"identity"` | | `"gauge"` | `"identity"` | | `"heatmap"` | `"identity"` | | `"candlestick"` | `"identity"` | | `"waterfall"` | `"identity"`, `"cumulative"` | | `"sankey"` | `"identity"` | | `"boxplot"` | `"identity"` | | `"violin"` | `"identity"` | | `"ridgeline"` | `"identity"` | | `"text"` | `"identity"` | If you pass an incompatible combination, `addIoLayer()` will error with a clear message. ## Theming Use `setTheme()` to customize chart appearance with CSS custom properties. ### Basic Theming ```{r theme-basic, eval = FALSE} myIO() |> addIoLayer( type = "point", color = "#56B4E9", label = "scatter", data = mtcars, mapping = list(x_var = "wt", y_var = "mpg") ) |> setTheme( text_color = "#e0e0e0", grid_color = "#333333", bg = "#1a1a2e", font = "Fira Code, monospace" ) ``` ### Theme Parameters | Parameter | CSS Property | Description | |-----------|-------------|-------------| | `text_color` | `--chart-text-color` | Axis labels and tick text | | `grid_color` | `--chart-grid-color` | Grid and axis lines | | `bg` | `--chart-bg` | Chart background color | | `font` | `--chart-font` | Font family | ### Custom Properties Pass additional CSS custom properties via `...` (the `chart-` prefix is added automatically): ```{r theme-custom, eval = FALSE} myIO() |> addIoLayer( type = "bar", color = "coral", label = "bars", data = mtcars, mapping = list(x_var = "cyl", y_var = "mpg") ) |> defineCategoricalAxis(xAxis = TRUE) |> setTheme( bg = "#fafafa", text_color = "#333", "border-radius" = "8px" ) ``` ### Dark Mode Example Combine theming with color choices for a dark-mode chart: ```{r dark-mode, eval = FALSE} aq <- airquality aq$Month <- paste0("M", aq$Month) myIO() |> addIoLayer( type = "line", color = c("#00d2ff", "#ff6b6b", "#feca57", "#48dbfb", "#ff9ff3"), label = "Month", data = aq, mapping = list(x_var = "Day", y_var = "Temp", group = "Month") ) |> setTheme( text_color = "#b0b0b0", grid_color = "#2d2d2d", bg = "#0d1117", font = "Inter, system-ui, sans-serif" ) ```