# Chart Types

## Overview

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.

## Layer Compatibility

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.

## Basic Charts

### Line Chart

    myIO() |>
      addIoLayer(
        type = "line",
        color = "steelblue",
        label = "temperature",
        data = airquality,
        mapping = list(x_var = "Day", y_var = "Temp")
      )

### Point (Scatter) Chart

    myIO() |>
      addIoLayer(
        type = "point",
        color = "coral",
        label = "scatter",
        data = mtcars,
        mapping = list(x_var = "wt", y_var = "mpg")
      )

### Bar Chart

    myIO() |>
      addIoLayer(
        type = "bar",
        color = "steelblue",
        label = "bars",
        data = mtcars,
        mapping = list(x_var = "cyl", y_var = "mpg")
      ) |>
      defineCategoricalAxis(xAxis = TRUE)

### Area Chart

Area charts require `x_var`, `low_y`, and `high_y` in the mapping:

    aq <- airquality[complete.cases(airquality), ]
    aq$TempLow <- aq$Temp - 5
    aq$TempHigh <- aq$Temp + 5

    myIO() |>
      addIoLayer(
        type = "area",
        color = "lightsteelblue",
        label = "area",
        data = aq,
        mapping = list(x_var = "Day", low_y = "TempLow", high_y = "TempHigh")
      )

### Grouped Bar Chart

    myIO() |>
      addIoLayer(
        type = "groupedBar",
        color = "steelblue",
        label = "grouped",
        data = mtcars,
        mapping = list(x_var = "cyl", y_var = "mpg")
      ) |>
      defineCategoricalAxis(xAxis = TRUE)

### Histogram

Histograms use a `value` mapping instead of `x_var`/`y_var`:

    myIO() |>
      addIoLayer(
        type = "histogram",
        color = "steelblue",
        label = "hist",
        data = mtcars,
        mapping = list(value = "mpg")
      )

### Donut Chart

    myIO() |>
      addIoLayer(
        type = "donut",
        color = c("#E69F00", "#56B4E9", "#009E73"),
        label = "donut",
        data = aggregate(mpg ~ cyl, data = mtcars, FUN = mean),
        mapping = list(x_var = "cyl", y_var = "mpg")
      )

### Gauge Chart

Gauges use a `value` mapping:

    myIO() |>
      addIoLayer(
        type = "gauge",
        color = "steelblue",
        label = "gauge",
        data = data.frame(value = 0.75),
        mapping = list(value = "value")
      )

### Hexbin Chart

    myIO() |>
      addIoLayer(
        type = "hexbin",
        color = "steelblue",
        label = "hexbin",
        data = mtcars,
        mapping = list(x_var = "wt", y_var = "mpg", radius = 20)
      )

### Treemap

Treemaps use a different mapping with `level_1` and `level_2` instead of `x_var` and `y_var`:

    myIO() |>
      addIoLayer(
        type = "treemap",
        label = "cars",
        data = mtcars,
        mapping = list(level_1 = "vs", level_2 = "cyl")
      )

## Phase 2 Charts

### Heatmap

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 Heatmap

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 (OHLC)

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

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

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")
      )

### Boxplot (Composite)

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 (Composite)

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 (Composite)

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 Plot (Composite)

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 (Composite)

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).

### Bracket (Standalone Layer)

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")
      )

## Combining Chart Types

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")
      )