Skip to content

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 modeBounds mode
TriggerLeave min/max null; optionally set preferredTickIntervalSet customMin and/or customMax
BoundsAuto-round to multiples of the chosen intervalFixed to your min/max
IntervalPrefers your preferredTickInterval when allowedAuto-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 familyGuidance
Clustered / stacked bar, stacked area, waterfallUsually keep 0 in range. Cutting off zero exaggerates differences.
Line, scatterSetting the range with customMin / customMax around the data is often right – zero is not required.
100% / mekko valuePin 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 customTickInterval instead of preferredTickInterval
  • Formatting left after flipping to horizontal (range moved to bottom)
  • Pinning bounds that clip data
  • Using dual custom min/max and an incompatible preferred interval
  • Expecting chartData number format alone to change PNG/slide look – formats are on the axis labels (and linked surfaces)

Next: Domain axis · Secondary · By chart type

Developer documentation for Chartbuddy Embed · Not the end-user Help Center · Help Center