myIO supports 20 chart types via the type argument in
addIoLayer(). This vignette shows an example of each.
All examples use built-in R datasets so you can copy and run them directly.
Chart types are organized into compatibility groups. You can freely combine types within compatible groups (e.g. point + line + area), but standalone types like treemap or gauge cannot be mixed with other types.
| Group | Types |
|---|---|
| Continuous axes | line, point, area,
candlestick, bracket, qq |
| Categorical axes | bar, groupedBar, waterfall,
boxplot, violin, comparison |
| Binned axes | histogram, ridgeline |
| Matrix axes | heatmap |
| Calendar | calendarHeatmap |
| Standalone | hexbin, treemap, donut,
gauge, sankey |
Continuous, categorical, and binned groups can be combined with each other. Matrix and standalone groups cannot be mixed with other groups.
Area charts require x_var, low_y, and
high_y in the mapping:
Histograms use a value mapping instead of
x_var/y_var:
Gauges use a value mapping:
Heatmaps display a matrix of values with a continuous color scale.
Both axes are categorical. Mapping requires x_var,
y_var, and value:
df <- expand.grid(
quarter = c("Q1", "Q2", "Q3", "Q4"),
segment = c("Low", "Mid", "High"),
stringsAsFactors = FALSE
)
df$value <- c(2, 4, 6, 5, 7, 9, 4, 6, 8, 3, 5, 7)
myIO() |>
addIoLayer(
type = "heatmap",
color = "#4E79A7",
label = "Revenue",
data = df,
mapping = list(x_var = "quarter", y_var = "segment", value = "value")
) |>
defineCategoricalAxis(xAxis = TRUE, yAxis = TRUE) |>
setAxisFormat(xLabel = "Quarter", yLabel = "Segment")Calendar heatmaps render daily values as a GitHub-contributions-style
grid: one cell per day, seven rows per week, with month labels across
the top. The chart is scoped to a single calendar year in v1.2. Mapping
requires date (any Date or ISO "YYYY-MM-DD"
string) and value (numeric):
set.seed(42)
df <- data.frame(
day = as.Date("2026-01-01") + 0:364,
commits = rpois(365, lambda = 3)
)
myIO() |>
addIoLayer(
type = "calendarHeatmap",
color = "#4E79A7",
label = "Daily commits",
data = df,
mapping = list(date = "day", value = "commits")
)Use options$weekStart = "monday" for ISO week ordering.
Two calendars linked via
linkCharts(a, b, on = "day", cursor = TRUE) synchronize the
hover crosshair by date across both charts.
Candlestick charts show open-high-low-close data. Green bars indicate
close >= open, red bars indicate close < open. Mapping requires
x_var, open, high,
low, and close:
df <- data.frame(
day = 1:10,
open = c(10, 12, 11, 14, 13, 15, 14, 16, 15, 17),
high = c(14, 15, 14, 17, 16, 18, 17, 19, 18, 20),
low = c(9, 11, 10, 13, 12, 14, 13, 15, 14, 16),
close = c(12, 11, 14, 13, 15, 14, 16, 15, 17, 19)
)
myIO() |>
addIoLayer(
type = "candlestick",
label = "Price",
data = df,
mapping = list(
x_var = "day", open = "open",
high = "high", low = "low", close = "close"
)
) |>
setAxisFormat(xAxis = ".0f", yAxis = "$,.0f",
xLabel = "Day", yLabel = "Price")Waterfall charts show how an initial value is affected by sequential
positive and negative changes. The cumulative transform is
auto-applied. Mark summary rows with a total mapping:
df <- data.frame(
step = c("Revenue", "COGS", "Gross Profit", "OpEx", "Net Income"),
value = c(500, -200, NA, -150, NA),
is_total = c(FALSE, FALSE, TRUE, FALSE, TRUE)
)
myIO() |>
addIoLayer(
type = "waterfall",
label = "P&L",
data = df,
mapping = list(x_var = "step", y_var = "value", total = "is_total")
) |>
defineCategoricalAxis(xAxis = TRUE) |>
setAxisFormat(yAxis = "$,.0f", xLabel = "Step", yLabel = "Amount")Sankey diagrams show flows between nodes. Mapping requires
source, target, and value. This
is a standalone type and cannot be mixed with other charts:
df <- data.frame(
source = c("Budget", "Budget", "Sales", "Sales", "Marketing"),
target = c("Sales", "Marketing", "Revenue", "Leads", "Leads"),
value = c(40, 20, 30, 10, 15)
)
myIO() |>
addIoLayer(
type = "sankey",
color = c("#4E79A7", "#F28E2B", "#E15759", "#76B7B2", "#59A14F"),
label = "Flow",
data = df,
mapping = list(source = "source", target = "target", value = "value")
)Boxplots are composite charts that automatically expand into area
(IQR box), point (whiskers, median), and optional outlier layers.
Mapping requires x_var (categorical) and y_var
(numeric):
myIO() |>
addIoLayer(
type = "boxplot",
color = "#4E79A7",
label = "Sepal Length",
data = iris,
mapping = list(x_var = "Species", y_var = "Sepal.Length"),
options = list(showOutliers = TRUE)
) |>
setAxisFormat(xLabel = "Species", yLabel = "Sepal Length (cm)")Options: showOutliers (default TRUE),
whiskerType (“tukey” or “minmax”).
Violin plots show the distribution shape via a mirrored kernel density estimate. They expand into area (density), optional box (IQR), and optional median point layers:
myIO() |>
addIoLayer(
type = "violin",
color = "#59A14F",
label = "Distribution",
data = iris,
mapping = list(x_var = "Species", y_var = "Sepal.Length"),
options = list(showBox = TRUE, showMedian = TRUE)
) |>
setAxisFormat(xLabel = "Species", yLabel = "Sepal Length (cm)")Options: showBox (TRUE), showMedian (TRUE),
showPoints (FALSE), bandwidth (KDE bandwidth,
default “nrd0”).
Ridgeline plots stack multiple density curves vertically for
comparing distributions across groups. They expand into one area
sub-layer per group value. Mapping requires x_var (numeric
values), y_var (numeric), and group
(categorical):
df <- mtcars
df$cyl <- as.character(df$cyl)
myIO() |>
addIoLayer(
type = "ridgeline",
color = c("#4E79A7", "#F28E2B", "#E15759"),
label = "MPG by Cylinders",
data = df,
mapping = list(x_var = "hp", y_var = "mpg", group = "cyl"),
options = list(overlap = 0.5)
) |>
setAxisFormat(xLabel = "Horsepower", yLabel = "Density")Options: overlap (0-1, default 0.6),
bandwidth (KDE bandwidth).
Q-Q (quantile-quantile) plots compare sample quantiles against a
theoretical distribution to assess normality. The composite expands into
a point layer (Q-Q scatter), a reference line (through Q1/Q3), and an
optional confidence envelope. Only y_var is required in the
mapping:
myIO() |>
addIoLayer(
type = "qq",
color = "#4E79A7",
label = "MPG Normality",
data = mtcars,
mapping = list(y_var = "mpg")
) |>
setAxisFormat(xLabel = "Theoretical Quantiles", yLabel = "Sample Quantiles")Options: envelope (TRUE), conf_level
(0.95), distribution (“norm”), qfunc (custom
quantile function). Supports grouped Q-Q via group
mapping.
Comparison plots combine boxplots with pairwise significance brackets showing p-values from hypothesis tests. The composite expands into boxplot sub-layers plus a bracket layer with test results:
myIO() |>
addIoLayer(
type = "comparison",
color = "#4E79A7",
label = "Species Comparison",
data = iris,
mapping = list(x_var = "Species", y_var = "Sepal.Width"),
options = list(method = "t.test", p_adjust = "bonferroni")
) |>
setAxisFormat(xLabel = "Species", yLabel = "Sepal Width (cm)")Options: method (“t.test” or “wilcox.test”),
p_adjust (“none”, “bonferroni”, “holm”, “BH”),
comparisons (list of specific pairs),
showOutliers (TRUE).
Brackets can also be added as a standalone layer on top of any
grouped chart. Use transform = "pairwise_test" to compute
significance tests:
myIO() |>
addIoLayer(
type = "boxplot", color = "#4E79A7",
label = "Sepal Width", data = iris,
mapping = list(x_var = "Species", y_var = "Sepal.Width")
) |>
addIoLayer(
type = "bracket", label = "Tests",
transform = "pairwise_test", data = iris,
mapping = list(x_var = "Species", y_var = "Sepal.Width"),
options = list(method = "wilcox.test", p_adjust = "holm")
)You can overlay compatible chart types on a single widget. Here we layer points, a connecting line, and a linear model trend line:
myIO() |>
addIoLayer(
type = "point",
color = "steelblue",
label = "points",
data = mtcars,
mapping = list(x_var = "wt", y_var = "mpg")
) |>
addIoLayer(
type = "line",
color = "orange",
label = "line",
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")
)