---
title: "Formatters"
framework: javascript
version: "14.1.0"
---

# Formatters

Formatters make it easy to customise the text shown for data across all chart elements, such as series labels, tooltips, and axes.

## Global Formatter

The chart level `formatter` is a callback called by all textual elements displaying data-based text. It should return a `string` to display, or `undefined` to fallback to [the next available option](#inheritance-and-precedence).

The parameters provided to the callback differ based on whether the text is coming from a [Number](#reference-NumberFormatterParams), [Date](#reference-DateFormatterParams) or [Category](#reference-CategoryFormatterParams) domain.

These properties provide enough context and information to tailor the formatting to your specific needs across different chart elements and scenarios.

These include:

- `type` - whether the value is coming from a category, number, or date domain.
- `value` - the raw value to be formatted.
- `source` - the chart element, such as `axis-label` or `tooltip`.
- `property` - the data visualisation property, such as `x`, `y`, `size`. These mirror the `_Key` properties.
- `context` - the user provided [Context Object](https://www.ag-grid.com/charts/javascript/context/).
- Properties to tie the value to the series and data used, such as `seriesId`, `boundSeries`, `domain`, `datum`.
- Date domains also include properties such as `unit`, `step`, `epoch`.

See the [API Reference](#api-reference) for a full list.

## Property Formatters

For ease of use, the formatter can also be an object keyed by property, providing a separate callback for each data visualisation property. This allows specifying a format for every place this property is used.

#### Formatter

```ts
import {
  AgCartesianChartOptions,
  AgCharts,
  AnimationModule,
  BubbleSeriesModule,
  ContextMenuModule,
  CrosshairModule,
  LegendModule,
  ModuleRegistry,
  NumberAxisModule,
  TimeAxisModule,
} from "ag-charts-enterprise";
import { getData } from "./data";

const magnitudeFormatter = new Intl.NumberFormat("en-US", {
  style: "decimal",
  maximumFractionDigits: 1,
  minimumFractionDigits: 1,
});
const deathsFormatter = new Intl.NumberFormat("en-US", {
  style: "decimal",
  maximumFractionDigits: 0,
  minimumFractionDigits: 0,
});
const dateFormatter = new Intl.DateTimeFormat("en-US", {
  year: "numeric",
  month: "long",
  day: "numeric",
  weekday: "long",
});
const yearFormatter = new Intl.DateTimeFormat("en-US", {
  year: "numeric",
});
ModuleRegistry.registerModules([
  AnimationModule,
  BubbleSeriesModule,
  CrosshairModule,
  LegendModule,
  NumberAxisModule,
  TimeAxisModule,
  ContextMenuModule,
]);

const options: AgCartesianChartOptions = {
  data: getData(),
  title: {
    text: "Earthquakes in the 21st Century",
  },
  series: [
    {
      type: "bubble",
      title: "Earthquakes",
      xKey: "date",
      xName: "Date",
      yKey: "magnitude",
      yName: "Magnitude",
      sizeKey: "deaths",
      sizeName: "Deaths",
      labelKey: "location",
      labelName: "Location",
      minSize: 5,
      maxSize: 100,
      label: {
        enabled: true,
        placement: "right",
      },
    },
  ],
  axes: {
    x: {
      type: "time",
      title: {
        text: "Date",
      },
    },
    y: {
      type: "number",
      title: {
        text: "Magnitude",
      },
    },
  },
  formatter: {
    x: (params) => {
      if (params.type !== "date") return;
      const formatter = params.unit === "year" ? yearFormatter : dateFormatter;
      return formatter.format(params.value);
    },
    y: (params) => {
      if (params.type !== "number") return;
      return `${magnitudeFormatter.format(params.value)} Mw`;
    },
    size: (params) => {
      if (params.type !== "number") return;
      return deathsFormatter.format(params.value);
    },
    label: (params) => {
      if (params.source === "series-label") return params.datum.flag;
    },
  },
};

options.container = document.getElementById("myChart");

const chart = AgCharts.create(options);
```

[Live example: Formatter](https://www.ag-grid.com/charts/typescript/formatters/examples/formatter)

```js
{
    formatter: {
        x: (params) => {
            const formatter = params.unit === 'year' ? yearFormatter : dateFormatter;
            return formatter.format(params.value);
        },
        y: (params) => {
            return `${magnitudeFormatter.format(params.value)} Mw`;
        },
        size: (params) => {
            return deathsFormatter.format(params.value);
        },
        label: (params) => {
            if (params.source === 'series-label') return params.datum.flag;
        },
    },
}
```

In this configuration:

- `x` formats the `xKey` values as a either a full date for the tooltip and crosshair, or year for the axis labels. It does this based on the `unit` value.
- `y` formats the `yKey` values as values on the Richter scale, with one decimal place of precision.
- `size` formats the `sizeKey` values as a decimal number with no fractional digits.
- `label` formats the label values removing additional information when it is a series label, otherwise returns the value as-is for the tooltip. It does this based on the `source` value.

The available properties are `x`, `y`, `angle`, `radius`, `size`, `color`, `label`, `secondaryLabel`, `calloutLabel`, and `sectorLabel`. These mirror the `_Key` properties.

> **Note**
>
> Each key formats its corresponding `_Key` data, not the visual element.  
> For example, `label` formats `labelKey` values on series that use it. Series labels on Line and Bar come from `yKey`, and so use the `y` key, optionally combined with `source === 'series-label'`.

## Inheritance and Precedence

Each chart element has a `formatter` callback within its options, and these take precedence over the chart level `formatter`.

For example an axis label will be formatted as follows:

1. `axes[].label.formatter` - if provided and not returning `undefined`.
2. Chart `formatter` - if provided and not returning `undefined`.
3. AG Chart defaults.

Additionally, if only an `axes[].label.formatter` is provided in the chart, the tooltip and crosshair formats will inherit based on this.

## Format Strings

A formatter can also be specified as a format string, which is a static string that represents a time or number format. This has less flexibility than the formatter function, but can be serialised.

#### Format String

```ts
import {
  AgChartOptions,
  AgCharts,
  LegendModule,
  LineSeriesModule,
  ModuleRegistry,
  NumberAxisModule,
  UnitTimeAxisModule,
} from "ag-charts-community";
import { getData } from "./data";

ModuleRegistry.registerModules([
  LegendModule,
  LineSeriesModule,
  NumberAxisModule,
  UnitTimeAxisModule,
]);

const options: AgChartOptions = {
  data: getData(),
  series: [
    {
      type: "line",
      xKey: "date",
      yKey: "temp",
    },
  ],
  axes: {
    x: {
      type: "unit-time",
      interval: { step: "month" },
    },
  },
  formatter: {
    x: "%b %Y",
    y: "$#{0>6.2f}",
  },
};

options.container = document.getElementById("myChart");

const chart = AgCharts.create(options);
```

[Live example: Format String](https://www.ag-grid.com/charts/typescript/formatters/examples/format-string)

```js
{
    formatter: {
        x: '%b %Y',
        y: '$#{0>6.2f}',
    },
}
```

#### Time Formats

The format string for `time` axis labels may contain the following directives, which reflect [Python's strftime specification](https://strftime.org/).

- `%a` - Abbreviated weekday name.*
- `%A` - Full weekday name.*
- `%b` - Abbreviated month name.*
- `%B` - Full month name.*
- `%c` - Locale's date and time, such as `%x`, `%X`.*
- `%d` - Zero-padded day of the month as a decimal number `[01,31]`.
- `%e` - Space-padded day of the month as a decimal number `[ 1,31]`; equivalent to `%_d`.
- `%f` - Microseconds as a decimal number `[000000,999999]`.
- `%H` - Hour (24-hour clock) as a decimal number `[00,23]`.
- `%I` - Hour (12-hour clock) as a decimal number `[01,12]`.
- `%j` - Day of the year as a decimal number `[001,366]`.
- `%m` - Month as a decimal number `[01,12]`.
- `%M` - Minute as a decimal number `[00,59]`.
- `%L` - Milliseconds as a decimal number `[000,999]`.
- `%p` - AM or PM.*
- `%Q` - Milliseconds since UNIX epoch.
- `%s` - Seconds since UNIX epoch.
- `%S` - Second as a decimal number `[00,61]`.
- `%u` - Monday-based (ISO) weekday as a decimal number `[1,7]`.
- `%U` - Sunday-based week of the year as a decimal number `[00,53]`. Days preceding the first Sunday in the year in week 0
- `%V` - ISO 8601 week number of the year as a decimal number `[01, 53]`. Week 1 is the first week where four or more days fall within the new year.
- `%w` - Sunday-based weekday as a decimal number `[0,6]`.
- `%W` - Monday-based week of the year as a decimal number `[00,53]`. Days preceding the first Monday in the year are in week 0.
- `%x` - Locale's date, such as `%-m/%-d/%Y`.*
- `%X` - Locale's time, such as `%-I:%M:%S %p`.*
- `%y` - Two-digit year as a decimal number `[00,99]`.
- `%Y` - Full year as a decimal number.
- `%Z` - Time zone offset, such as `-0700`, `-07:00`, `-07`, or `Z`.
- `%%` - A literal percent sign (%).

Directives marked with an asterisk (*) may be affected by the locale definition.

The `%` sign indicating a directive may be immediately followed by a padding modifier, otherwise no padding will be applied.

- `0` - zero-padding.
- `_` - space-padding.

#### Number Formats

The format string for `number` and `log` axis labels contain the following directives, which reflect [Python's format specification](https://docs.python.org/3/library/string.html#formatspec/).

`[[fill]align][sign][#][0][width][grouping_option][.precision][type]`

Where:

- `fill` - Can be any character.
- `align`:
  - `>` - Forces the field to be right-aligned within the available space (default).
  - `<` - Forces the field to be left-aligned within the available space.
  - `^` - Forces the field to be centred within the available space.
  - `=` - Like >, but with any sign and symbol to the left of any padding.
- `sign`:
  - `-` - Nothing for zero or positive, and a minus sign for negative (default).
  - `+` - A plus sign for zero or positive and a minus sign for negative.
  - `(` - Nothing for zero or positive and parentheses for negative.
  - ` ` - A space for zero or positive and a minus sign for negative.
- `symbol`:
  - `$` - The `$` currency symbol.
  - `#` - For binary, octal, or hexadecimal notation, prefix by `0b`, `0o`, or `0x`, respectively.
- `zero` - The `0` option enables zero-padding. Implicitly sets `fill` to `0` and `align` to `=`.
- `width` - The minimum field width. If not specified, this will be determined by the content.
- `comma` - The group separator, such as a comma for thousands.
- `precision` - For types `f` and `%` determines the number of digits after the decimal point, otherwise determines the number of significant digits. Defaults to 6 for all types, or 12 if no type is supplied. Ignored for integer types.
- `~` - Trims insignificant trailing zeros across all format types.
- `type` - Determines how the data should be presented:
  - `%` - Multiply by 100, and display in decimal notation with a percent sign.
  - `b` - Binary notation, rounded to integer.
  - `c` - Display the integer as the corresponding unicode character.
  - `d` - Decimal notation, rounded to integer.
  - `e` - Exponent notation.
  - `f` - Fixed point notation.
  - `g` - Either decimal or exponent notation, rounded to significant digits.
  - `o` - Octal notation, rounded to integer.
  - `p` - Multiply by 100, round to significant digits, and then decimal notation with a percent sign.
  - `r` - Decimal notation, rounded to significant digits.
  - `s` - Decimal notation with a SI prefix, rounded to significant digits.
  - `x` - Hexadecimal notation, using lower-case letters, rounded to integer.
  - `X` - Hexadecimal notation, using upper-case letters, rounded to integer.

> **Note**
>
> Formats should be wrapped with `#{}` if included within a string so that it's clear where the number format begins and ends. For example: `I'm #{0>2.0f} years old`.

## API Reference

#### Number Formatter Parameters

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| type | 'number' |  | Configuration for a number-formatted value. |
| fractionDigits | number \| undefined |  | The recommended precision to format the value. |
| visibleDomain | [AgNumericValue, AgNumericValue] \| undefined |  | The currently visible domain. [min, max] |
| value | number \| bigint |  | The current value being formatted. |
| datum | TDatum \| undefined |  | The datum associated with the value, if available. |
| legendItemName | string \| undefined |  | The legendItemName of the series that the value belongs to, if available. |
| seriesId | string \| undefined |  | The ID of the series that the value belongs to, if available. |
| key | ResolvedDatumKey \| undefined |  | The key of the property associated with the datum, if available. |
| source | SeriesFormatterSource \| ChartFormatterSource |  | The source of the formatter, indicating the element where it is being used. |
| property | FormatterPropertyType |  | The property being formatted, such as 'x', 'y', 'angle', etc. |
| domain | any[] |  | The data domain of the series that the value belongs to, if available.. |
| boundSeries | FormatterBoundSeries[] |  | A description of the key and name properties of the series associated with the element being formatted. |
| boundSeries.seriesId | string |  | ID used by the series for values. |
| boundSeries.key | string |  | Key used by the series for values. |
| boundSeries.name | string |  | Optional name used by the series for values. |
| context | TContext |  | Context for this callback. |

#### Date Formatter Parameters

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| type | 'date' |  | Configuration for a date-formatted value. |
| unit | 'millisecond' \| 'second' \| 'minute' \| 'hour' \| 'day' \| 'month' \| 'year' |  | The interval used for the formatted element. I.e. if given the unit `day`, you may format your day as '1 January 2020'. |
| step | number |  | The frequency of `unit`. I.e. a unit of `day` and a step of `7` indicates a weekly interval. |
| epoch | Date \| undefined |  | The date from which the time interval is relative to. For example, if you had weekly data, and your epoch was a Sunday, you would format every Sunday. |
| style | 'long' \| 'component' |  | Date formatting style. Either `long` for the full date, such as '25 December 2020'; or `component` for just the unit component of the date, such as '25'. |
| value | Date |  | The current value being formatted. |
| datum | TDatum \| undefined |  | The datum associated with the value, if available. |
| legendItemName | string \| undefined |  | The legendItemName of the series that the value belongs to, if available. |
| seriesId | string \| undefined |  | The ID of the series that the value belongs to, if available. |
| key | ResolvedDatumKey \| undefined |  | The key of the property associated with the datum, if available. |
| source | SeriesFormatterSource \| ChartFormatterSource |  | The source of the formatter, indicating the element where it is being used. |
| property | FormatterPropertyType |  | The property being formatted, such as 'x', 'y', 'angle', etc. |
| domain | any[] |  | The data domain of the series that the value belongs to, if available.. |
| boundSeries | FormatterBoundSeries[] |  | A description of the key and name properties of the series associated with the element being formatted. |
| boundSeries.seriesId | string |  | ID used by the series for values. |
| boundSeries.key | string |  | Key used by the series for values. |
| boundSeries.name | string |  | Optional name used by the series for values. |
| context | TContext |  | Context for this callback. |

#### Category Formatter Parameters

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| type | 'category' |  | Configuration for a category-formatted value. |
| value | string \| number \| Date \| string[] |  | The current value being formatted. |
| datum | TDatum \| undefined |  | The datum associated with the value, if available. |
| legendItemName | string \| undefined |  | The legendItemName of the series that the value belongs to, if available. |
| seriesId | string \| undefined |  | The ID of the series that the value belongs to, if available. |
| key | ResolvedDatumKey \| undefined |  | The key of the property associated with the datum, if available. |
| source | SeriesFormatterSource \| ChartFormatterSource |  | The source of the formatter, indicating the element where it is being used. |
| property | FormatterPropertyType |  | The property being formatted, such as 'x', 'y', 'angle', etc. |
| domain | any[] |  | The data domain of the series that the value belongs to, if available.. |
| boundSeries | FormatterBoundSeries[] |  | A description of the key and name properties of the series associated with the element being formatted. |
| boundSeries.seriesId | string |  | ID used by the series for values. |
| boundSeries.key | string |  | Key used by the series for values. |
| boundSeries.name | string |  | Optional name used by the series for values. |
| context | TContext |  | Context for this callback. |
