---
url: https://chartbuddy.io/embed/docs/axes.md
---
# Axes

Axes map categories and values onto the chart. Config covers ticks, bounds, formats, dual scales, and label fit.

Axes are keyed by **physical side** (`left` | `right` | `top` | `bottom`). Each side holds a **role**:

| Role | Meaning |
|---|---|
| `domain` | Categories (or linear X on scatter / mekko width) |
| `primaryRange` | Main value scale |
| `secondaryRange` | Second value scale (dual-axis) |
| `unused` | Placeholder for the side not used by the current orientation |

```js
axes: {
  bottom: { id: 'domain', /* … */ },
  left: { id: 'primaryRange', /* … */ },
  right: { id: 'secondaryRange', enabled: false, boundSeries: [], /* … */ },
  top: { id: 'unused', enabled: false, /* … */ },
}
```

Which role sits on which side depends on [orientation](/concepts/orientation). When orientation changes, the embed moves each role to its new side. Put settings on the side that holds that role *after* the flip (for example, value formats go on `left` when vertical and on `bottom` when horizontal).

| Orientation | Domain | Primary range | Secondary range |
|---|---|---|---|
| `vertical` (default) | bottom | left | right |
| `horizontal` | left | bottom | **top** |

***

## Checklist

Typical order:

1. **Format the value axis** – currency, `%`, decimals ([Number formats](/configuration/number-formats), [Value axis](/axes/value-axis))
2. **Tick density** – leave auto, or set `preferredTickInterval` ([Value axis](/axes/value-axis#preferred-interval))
3. **Bounds** – pin min/max only when you mean it (zero rules, zoom) ([Value axis](/axes/value-axis#bounds))
4. **Gridlines** – usually on the primary range side ([Gridlines](/configuration/gridlines))
5. **Category labels** – wrap / rotate / dates when crowded ([Domain axis](/axes/domain))
6. **Titles** – units on the value axis when the format alone is not enough ([Titles & chrome](/axes/titles-and-chrome))
7. **Dual axis / breaks** – when you need two scales or a collapsed gap ([Secondary](/axes/secondary), [Breaks](/axes/breaks))

***

## Defaults (what you get)

From `getDefaultAxesConfig` (new charts):

* Domain: band scale, `fitMechanism: 'wrap'`, titles **hidden**
* Primary range: linear, `preferredTickInterval: null` (auto sparse ticks), gridlines **off**, titles **hidden**
* Secondary: `enabled: false`, `visible: false`, `boundSeries: []`
* `%` chart types (`stackedBar100`, mekko, …) seed `postfix: '%'` on the relevant labels
* Bar Mekko hides the primary range **axis line** by default (`visible: false`); labels stay available when you turn it on
* Pie / donut: axes disabled

`axes` **deep-merges** on `setChartData` / `update` – see [Defaults & merging](/concepts/defaults). Prefer exporting a full tree from the editor (`getChartData()`) when you need a complete starting point, then patch.

***

## Pages

| Page | Use when |
|---|---|
| [Value axis](/axes/value-axis) | Ticks, bounds, `%` charts, zero rules, currency |
| [Domain axis](/axes/domain) | Category labels, wrap/rotate, dates |
| [Titles & chrome](/axes/titles-and-chrome) | Axis titles, visibility, tick marks, colors |
| [Secondary / dual axis](/axes/secondary) | Second scale + `boundSeries` (incl. horizontal **top**) |
| [Axis breaks](/axes/breaks) | Collapse a dead range on the value axis |
| [By chart type](/axes/by-chart-type) | What each type exposes / fixes / hides |
| [Orientation & roles](/axes/orientation) | Remap rules and the “0,1,2,3,4” pitfall |

Also: [Gridlines](/configuration/gridlines) · [Number formats](/configuration/number-formats) · [Orientation](/concepts/orientation)

***

## Samples

* [Currency ticks](/samples/currency-ticks) – format + preferred interval + title
* [Dual-axis line](/samples/dual-axis-line) – secondary + `boundSeries`
* [Percent axis](/samples/percent-axis) – pinned 0–100 `%` ticks
* [Horizontal bar](/samples/horizontal-bar) – orientation remap (format the **bottom** range)
