Appearance
Value axis
The primary range (and secondary range) axes are linear value scales. On a vertical chart that is usually axes.left; on a horizontal chart it is axes.bottom. Always write to the side that holds id: 'primaryRange' (or 'secondaryRange') after orientation remap – see Orientation.
js
axes: {
left: {
id: 'primaryRange',
labels: {
preferredTickInterval: null, // auto
customMin: null,
customMax: null,
numberFormat: {
mode: 'custom',
customFormat: {
prefix: '',
postfix: '',
thousandSeparator: ',',
decimalSeparator: '.',
decimalPlaces: 0,
forceDecimals: true,
signDisplay: 'auto',
scaleDown: 0,
},
},
},
},
}Full format field reference: Number formats.
Two modes: interval vs bounds
Ticks and bounds are mutually exclusive drivers. Change one; do not fight both at once.
| Interval / auto mode | Bounds mode | |
|---|---|---|
| Trigger | Leave min/max null; optionally set preferredTickInterval | Set customMin and/or customMax |
| Bounds | Auto-round to multiples of the chosen interval | Fixed to your min/max |
| Interval | Prefers your preferredTickInterval when allowed | Auto-picked so ticks land on the bounds |
If you pin bounds and a preferred interval that cannot divide the span, the engine adjusts the interval (or ignores the preference). Chasing both by hand causes a feedback loop – pick one mode.
Preferred interval
preferredTickInterval is a step size (e.g. 10, 25, 50), not “number of labels.”
js
axes: {
left: {
labels: {
preferredTickInterval: 25,
},
},
}Leave it null for new charts so auto sparse selection runs from the space budget:
| Space for (max labels) | Aim for |
|---|---|
| 1–5 | ~2 labels |
| 6–13 | ~3 |
| 14–20 | ~4 |
| 21+ | ~5 |
Nice candidates are values like 1, 2, 2.5, 5, 10 × powers of 10.
Do not hand-author customTickInterval. The engine writes that field when resolving ticks. Authors set preferredTickInterval (or leave null).
Percentage charts
For stackedBar100, stackedArea100, and mekko value axes, allowed intervals are filtered to divisors of 100 (1, 2, 2.5, 4, 5, 10, 20, 25, 50, 100). Prefer 20 / 25 / 50 for clean decks. Defaults already seed postfix: '%'.
See Percent axis sample.
Bounds
js
axes: {
left: {
labels: {
customMin: 0,
customMax: 200,
},
},
}null/ omit – auto from data (+ nice rounding in interval mode)- Set one or both – bounds mode
Zero rules
| Chart family | Guidance |
|---|---|
| Clustered / stacked bar, stacked area, waterfall | Usually keep 0 in range. Cutting off zero exaggerates differences. |
| Line, scatter | Zooming with customMin / customMax around the data is often right – zero is not required. |
| 100% / mekko value | Pin 0–100 (engine and defaults already bias this way). |
If customMin sits above the lowest data point (or customMax below the highest), bars/lines clip. Fix the bound or widen it.
Recipe: zoomed line
js
{
chartType: 'line',
isDataTransposed: true,
seriesData: [/* … */],
axes: {
left: {
labels: {
customMin: 80,
customMax: 120,
preferredTickInterval: 10,
},
},
},
}Recipe: currency ticks
js
axes: {
left: {
labels: {
preferredTickInterval: 50,
numberFormat: {
mode: 'custom',
customFormat: {
prefix: '$',
postfix: '',
thousandSeparator: ',',
decimalSeparator: '.',
decimalPlaces: 0,
forceDecimals: false,
signDisplay: 'auto',
scaleDown: 0,
},
},
},
axisTitle: {
visible: true,
text: 'USD millions',
},
},
}Live: Currency ticks sample.
Horizontal charts
After orientation: 'horizontal', the primary range is on bottom. Put formats, preferred intervals, bounds, and value gridlines there – not on left (that side is domain / categories).
js
{
orientation: 'horizontal',
axes: {
bottom: {
labels: {
preferredTickInterval: 20,
numberFormat: {
mode: 'custom',
customFormat: {
prefix: '',
postfix: '%',
decimalPlaces: 0,
forceDecimals: false,
thousandSeparator: ',',
decimalSeparator: '.',
signDisplay: 'auto',
scaleDown: 0,
},
},
},
gridlines: { visible: true },
},
},
}Gridlines
Default for new charts: gridlines visible: false. Turn them on on the value axis side and pair overrides with a fixed preferredTickInterval so tick keys stay stable – Gridlines.
Pitfalls
- Authoring
customTickIntervalinstead ofpreferredTickInterval - Formatting
leftafter flipping to horizontal (range moved tobottom) - Pinning bounds that clip data
- Using dual custom min/max and an incompatible preferred interval
- Expecting
chartDatanumber format alone to change PNG/slide look – formats are on the axis labels (and linked surfaces)
Next: Domain axis · Secondary · By chart type