---
url: https://chartbuddy.io/embed/docs/axes/domain.md
---
# Domain axis

The **domain** axis carries categories (most charts) or a linear X domain (scatter / bubble; mekko / bar mekko use a special width domain). On a vertical chart it is usually `axes.bottom`; on a horizontal chart it is `axes.left`.

```js
axes: {
  bottom: {
    id: 'domain',
    labels: {
      visible: true,
      fitMechanism: 'wrap', // 'wrap' | 'rotation' | 'alternating' | 'none'
      wrapMaxLines: 5,
      position: 'bottom',   // often mirrors the side; 'auto' | 'bottom' | 'top' | 'chart-top'
      dateFormat: {
        treatAsDate: false,
        format: 'MMM D, YYYY',
      },
    },
  },
}
```

Domain axes **cannot be hidden** as a role (range axes can). You can still hide **labels** with `labels.visible: false`.

***

## Fit mechanisms

When labels collide, ChartBuddy applies the configured fit strategy:

| `fitMechanism` | Behavior | Best for |
|---|---|---|
| `'wrap'` (default) | Multi-line labels within the category column | Short phrases, vertical charts |
| `'rotation'` | Tilts labels (~−25° to −60°) | Many dense categories |
| `'alternating'` | Staggers labels on two (or more) rows | Medium crowding without rotation |
| `'none'` | No fitting – labels stay single-line horizontal | Few short labels, or when you control spacing |

If there is no overlap, labels stay horizontal even when a fit mechanism is set.

### Horizontal charts

Category labels sit on the **left** and need **height**. Prefer wrap or fewer categories; rotation eats horizontal plot width. Give the mount enough height (e.g. 480px+) – see [Orientation](/concepts/orientation).

```js
{
  orientation: 'horizontal',
  axes: {
    left: {
      labels: {
        fitMechanism: 'wrap',
        wrapMaxLines: 3,
      },
    },
  },
}
```

***

## Category dates

Category values that should format as dates use **`dateFormat`**, not `numberFormat`:

```js
axes: {
  bottom: {
    labels: {
      dateFormat: {
        treatAsDate: true,
        format: 'MMM YYYY',
      },
    },
  },
}
```

`format` is a date pattern string (e.g. `'MMM D, YYYY'`). Leave `treatAsDate: false` for ordinary category strings.

***

## Mekko / bar Mekko domain

Mekko and bar Mekko use a **linear 0–100 width domain** (column thickness), not a simple band of equal categories. Defaults seed mekko domain ticks with `%` postfix and `preferredTickInterval: 20`. Prefer exporting a finished mekko from the editor when authoring advanced domain chrome.

***

## Scatter / bubble

Scatter and bubble use **linear** scales on both domain and range (runtime forces linear domain even if a band default was seeded). Format both sides with `numberFormat` as needed; category `fitMechanism` / `dateFormat` usually do not apply.

***

## Pitfalls

* Crowding labels then blaming the value axis – fix `fitMechanism` or reduce categories
* Horizontal charts with tall wrapped labels and a short container
* Using `numberFormat` for calendar strings – use `dateFormat.treatAsDate`
* Hand-authoring mekko domain from scratch – start from `getChartData()` after editing

Next: [Value axis](/axes/value-axis) · [Titles & chrome](/axes/titles-and-chrome)
