Range Controls allow the user to easily navigate to specific time periods and ranges along the chart timeline.
Enabling Range Controls Copy Link
Set ranges.enabled to true to display range control buttons.
import {
AgChartOptions,
AgCharts,
LineSeriesModule,
ModuleRegistry,
NavigatorModule,
NumberAxisModule,
RangesModule,
UnitTimeAxisModule,
ZoomModule,
} from "ag-charts-enterprise";
import { getData } from "./data";
ModuleRegistry.registerModules([
LineSeriesModule,
NumberAxisModule,
UnitTimeAxisModule,
RangesModule,
ZoomModule,
NavigatorModule,
]);
const options: AgChartOptions = {
data: getData(),
title: { text: "Daily Readings" },
series: [{ type: "line", xKey: "date", yKey: "value", yName: "Value" }],
axes: {
x: { type: "unit-time" },
y: { type: "number" },
},
zoom: { enabled: true },
navigator: { enabled: true },
ranges: { enabled: true },
};
options.container = document.getElementById("myChart");
const chart = AgCharts.create(options);
export function getData() {
const data: { date: Date; value: number }[] = [];
const start = new Date(2022, 0, 1);
const end = new Date(2025, 3, 30);
let value = 100;
for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
value += random() * 6 - 3;
value = Math.max(10, value);
data.push({ date: new Date(d), value: Math.round(value * 100) / 100 });
}
return data;
}
let seed = 1234567;
function random() {
seed = (seed * 16807) % 2147483647;
return (seed - 1) / 2147483646;
}
{
ranges: { enabled: true },
}In this example:
- Clicking a range button updates the visible range to the corresponding time period.
- Time periods are calculated from the end of the axis domain. For example, '1 M' shows the last month of data.
- Range controls are commonly used alongside Zoom and Navigator for a complete navigation experience.
- Financial Charts also include range controls - see Financial Charts - Range Buttons.
Position Copy Link
Use the position property to change where the range buttons are displayed. The default is 'top-right'.
import {
AgCartesianChartOptions,
AgCharts,
AgRangesPosition,
LineSeriesModule,
ModuleRegistry,
NavigatorModule,
NumberAxisModule,
RangesModule,
UnitTimeAxisModule,
ZoomModule,
} from "ag-charts-enterprise";
import { getData } from "./data";
ModuleRegistry.registerModules([
LineSeriesModule,
NumberAxisModule,
UnitTimeAxisModule,
RangesModule,
ZoomModule,
NavigatorModule,
]);
const options: AgCartesianChartOptions = {
data: getData(),
title: { text: "Daily Readings" },
series: [{ type: "line", xKey: "date", yKey: "value", yName: "Value" }],
axes: {
x: { type: "unit-time" },
y: { type: "number" },
},
zoom: { enabled: true },
navigator: { enabled: true },
ranges: {
enabled: true,
position: "top-right",
},
};
options.container = document.getElementById("myChart");
const chart = AgCharts.create(options);
function changePosition(position: AgRangesPosition) {
options.ranges = {
...options.ranges,
position,
};
chart.update(options);
}
if (typeof window !== "undefined") {
// Attach external event handlers to window so they can be called from index.html
(<any>window).changePosition = changePosition;
}
export function getData() {
const data: { date: Date; value: number }[] = [];
const start = new Date(2022, 0, 1);
const end = new Date(2025, 3, 30);
let value = 100;
for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
value += random() * 6 - 3;
value = Math.max(10, value);
data.push({ date: new Date(d), value: Math.round(value * 100) / 100 });
}
return data;
}
let seed = 1234567;
function random() {
seed = (seed * 16807) % 2147483647;
return (seed - 1) / 2147483646;
}
{
ranges: {
position: 'bottom-left',
},
}In this example:
- Use the dropdown to select different positions for the range buttons.
- Available positions are:
'top-left','top','top-right','bottom-left','bottom','bottom-right'.
Custom Ranges Copy Link
Override the default buttons by providing a buttons array. Each button has a label, and a value that determines the range.
{
ranges: {
buttons: [
{ label: '6 Months', value: 6 * 30 * 24 * 60 * 60 * 1000 },
{ label: '1 Year', value: 365 * 24 * 60 * 60 * 1000 },
{ label: 'H1 2023', value: [new Date(2023, 0, 1), new Date(2023, 6, 1)] },
{ label: 'All Data', value: undefined },
],
},
}The value property accepts:
- Calendar Interval - An
AgTimeIntervalorAgTimeIntervalUnitfor calendar-aware ranges on time axes. - Number - A duration in milliseconds for time axes, or a numeric offset for number axes.
- Pair - A
[Date | number, Date | number]tuple defining an absolute range. - Function - A function that receives the data domain and current visible window, and returns a new range. The function may return
undefinedfor either endpoint to leave that side of the range unchanged. undefined- Resets the zoom to show all data or the initial zoom range.
Calendar Intervals Copy Link
Use AgTimeInterval or AgTimeIntervalUnit values for calendar-aware ranges that handle variable-length months and years correctly.
import {
AgChartOptions,
AgCharts,
LineSeriesModule,
ModuleRegistry,
NavigatorModule,
NumberAxisModule,
RangesModule,
UnitTimeAxisModule,
ZoomModule,
} from "ag-charts-enterprise";
import { getData } from "./data";
ModuleRegistry.registerModules([
LineSeriesModule,
NumberAxisModule,
UnitTimeAxisModule,
RangesModule,
ZoomModule,
NavigatorModule,
]);
const options: AgChartOptions = {
data: getData(),
title: { text: "Daily Readings" },
series: [{ type: "line", xKey: "date", yKey: "value", yName: "Value" }],
axes: {
x: { type: "unit-time" },
y: { type: "number" },
},
zoom: { enabled: true },
navigator: { enabled: true },
ranges: {
buttons: [
{ label: "1 Month", value: "month" },
{ label: "3 Months", value: { unit: "month", step: 3 } },
{ label: "6 Months", value: { unit: "month", step: 6 } },
{ label: "1 Year", value: "year" },
{ label: "All Data", value: undefined },
],
},
};
options.container = document.getElementById("myChart");
const chart = AgCharts.create(options);
export function getData() {
const data: { date: Date; value: number }[] = [];
const start = new Date(2022, 0, 1);
const end = new Date(2025, 2, 31);
let value = 100;
for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
value += random() * 6 - 3;
value = Math.max(10, value);
data.push({ date: new Date(d), value: Math.round(value * 100) / 100 });
}
return data;
}
let seed = 1234567;
function random() {
seed = (seed * 16807) % 2147483647;
return (seed - 1) / 2147483646;
}
{
ranges: {
buttons: [
{ label: '1 Month', value: 'month' },
{ label: '3 Months', value: { unit: 'month', step: 3 } },
{ label: '1 Year', value: 'year' },
{ label: 'All Data', value: undefined },
],
},
}- Calendar intervals account for varying month lengths rather than using a fixed number of milliseconds. For example, '1 Month' from 31 March navigates back to 28 February.
- See Time Intervals for more details.
Window-Relative Functions Copy Link
For full control, provide a function that receives the data domain and current visible window, and returns a new range.
import {
AgChartOptions,
AgCharts,
LineSeriesModule,
ModuleRegistry,
NavigatorModule,
NumberAxisModule,
RangesModule,
UnitTimeAxisModule,
ZoomModule,
} from "ag-charts-enterprise";
import { getData } from "./data";
ModuleRegistry.registerModules([
LineSeriesModule,
NumberAxisModule,
UnitTimeAxisModule,
RangesModule,
ZoomModule,
NavigatorModule,
]);
const options: AgChartOptions = {
data: getData(),
series: [
{
type: "line",
xKey: "date",
yKey: "value",
},
],
axes: {
x: {
type: "unit-time",
label: {
autoRotate: false,
},
},
y: {
type: "number",
},
},
ranges: {
buttons: [
{
label: "Last 1M",
value: ({ windowEnd }) => {
const month = 30 * 24 * 60 * 60 * 1000;
return [Number(windowEnd) - month, windowEnd];
},
},
{
label: "Last 3M",
value: ({ windowEnd }) => {
const months = 3 * 30 * 24 * 60 * 60 * 1000;
return [Number(windowEnd) - months, windowEnd];
},
},
{
label: "1M Centre",
value: ({ windowStart, windowEnd }) => {
const mid = (Number(windowStart) + Number(windowEnd)) / 2;
const halfMonth = (30 * 24 * 60 * 60 * 1000) / 2;
return [mid - halfMonth, mid + halfMonth];
},
},
{
label: "3M Centre",
value: ({ windowStart, windowEnd }) => {
const mid = (Number(windowStart) + Number(windowEnd)) / 2;
const halfRange = (3 * 30 * 24 * 60 * 60 * 1000) / 2;
return [mid - halfRange, mid + halfRange];
},
},
{
label: "< 1M",
value: ({ windowStart, windowEnd }) => {
const month = 30 * 24 * 60 * 60 * 1000;
return [Number(windowStart) - month, Number(windowEnd) - month];
},
},
{
label: "1M >",
value: ({ windowStart, windowEnd }) => {
const month = 30 * 24 * 60 * 60 * 1000;
return [Number(windowStart) + month, Number(windowEnd) + month];
},
},
{ label: "All", value: undefined },
],
},
zoom: { enabled: true },
navigator: { enabled: true },
};
options.container = document.getElementById("myChart");
const chart = AgCharts.create(options);
export function getData() {
const data: { date: Date; value: number }[] = [];
const start = new Date(2023, 0, 1);
const end = new Date(2024, 11, 31);
let value = 100;
for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
value += random() * 6 - 3;
value = Math.max(10, value);
data.push({ date: new Date(d), value: Math.round(value * 100) / 100 });
}
return data;
}
let seed = 1234567;
function random() {
seed = (seed * 16807) % 2147483647;
return (seed - 1) / 2147483646;
}
{
ranges: {
buttons: [
{
label: 'Last 1M',
value: ({ windowEnd }) => {
const month = 30 * 24 * 60 * 60 * 1000;
return [Number(windowEnd) - month, windowEnd];
},
},
{
label: '1M Centre',
value: ({ windowStart, windowEnd }) => {
const mid = (Number(windowStart) + Number(windowEnd)) / 2;
const halfMonth = (30 * 24 * 60 * 60 * 1000) / 2;
return [mid - halfMonth, mid + halfMonth];
},
},
{
label: '< 1M',
value: ({ windowStart, windowEnd }) => {
const month = 30 * 24 * 60 * 60 * 1000;
return [Number(windowStart) - month, Number(windowEnd) - month];
},
},
{ label: 'All', value: undefined },
],
},
}Use the Navigator to zoom into the middle of the data, then try the buttons:
- 'Last 1M' and 'Last 3M' - Shows the last 1 or 3 months from the right edge of the current window.
- '1M Centre' and '3M Centre' - Zooms to 1 or 3 months centred on the midpoint of the current window.
- '< 1M' and '1M >' - Pan the entire window one month backward or forward.
The function receives a single params object which includes the following properties:
startandend- The full data domain bounds.windowStartandwindowEnd- The currently visible range.source- Indicates what triggered the function call. As the function is also called to determine whether the button should be disabled, this allows differentiation.
Appearance Copy Link
Out-of-Range Buttons Copy Link
When buttons specify ranges that exceed the data bounds, they are disabled by default. Set enableOutOfRange to true to keep them enabled.
import {
AgCartesianChartOptions,
AgCharts,
LineSeriesModule,
ModuleRegistry,
NavigatorModule,
NumberAxisModule,
RangesModule,
UnitTimeAxisModule,
ZoomModule,
} from "ag-charts-enterprise";
import { getData } from "./data";
ModuleRegistry.registerModules([
LineSeriesModule,
NumberAxisModule,
UnitTimeAxisModule,
RangesModule,
ZoomModule,
NavigatorModule,
]);
const options: AgCartesianChartOptions = {
data: getData(),
series: [
{
type: "line",
xKey: "date",
yKey: "value",
},
],
axes: {
x: {
type: "unit-time",
label: {
autoRotate: false,
},
},
y: {
type: "number",
},
},
zoom: { enabled: true },
navigator: { enabled: true },
ranges: {
enabled: true,
},
};
options.container = document.getElementById("myChart");
const chart = AgCharts.create(options);
function toggleOutOfRange(event: Event) {
const enableOutOfRange = (event.target as HTMLInputElement).value === "true";
options.ranges = {
...options.ranges,
enableOutOfRange,
};
chart.update(options);
}
if (typeof window !== "undefined") {
// Attach external event handlers to window so they can be called from index.html
(<any>window).toggleOutOfRange = toggleOutOfRange;
}
export function getData() {
const data: { date: Date; value: number }[] = [];
const start = new Date(2024, 9, 1);
const end = new Date(2024, 11, 31);
let value = 50;
for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
value += random() * 6 - 3;
value = Math.max(10, value);
data.push({ date: new Date(d), value: Math.round(value * 100) / 100 });
}
return data;
}
let seed = 9876543;
function random() {
seed = (seed * 16807) % 2147483647;
return (seed - 1) / 2147483646;
}
{
ranges: {
enableOutOfRange: true,
},
}In this example:
- The data only spans 3 months, so the '6M', 'YTD', and '1Y' buttons are disabled by default.
- The 'All' button is always enabled.
- Individual buttons can use the
enabledproperty within their definition to force enable or disable states.
Responsive Dropdown Copy Link
When the chart is too narrow for all buttons, they automatically collapse into a dropdown.
import {
AgCartesianChartOptions,
AgCharts,
LineSeriesModule,
ModuleRegistry,
NavigatorModule,
NumberAxisModule,
RangesModule,
UnitTimeAxisModule,
ZoomModule,
} from "ag-charts-enterprise";
import { getData } from "./data";
ModuleRegistry.registerModules([
LineSeriesModule,
NumberAxisModule,
UnitTimeAxisModule,
RangesModule,
ZoomModule,
NavigatorModule,
]);
const options: AgCartesianChartOptions = {
data: getData(),
series: [
{
type: "line",
xKey: "date",
yKey: "value",
},
],
axes: {
x: {
type: "unit-time",
label: {
autoRotate: false,
},
},
y: {
type: "number",
},
},
ranges: {
enabled: true,
dropdown: { visible: "auto" },
buttons: [
{ label: "1 Month", value: "month" },
{ label: "3 Months", value: { unit: "month", step: 3 } },
{ label: "6 Months", value: { unit: "month", step: 6 } },
{ label: "1 Year", value: "year" },
{ label: "All Data", value: undefined },
],
},
zoom: { enabled: true },
navigator: { enabled: true },
};
options.container = document.getElementById("myChart");
const chart = AgCharts.create(options);
function changeDropdown(visible: "auto" | "always" | "never") {
options.ranges = {
...options.ranges,
dropdown: { visible },
};
chart.update(options);
}
if (typeof window !== "undefined") {
// Attach external event handlers to window so they can be called from index.html
(<any>window).changeDropdown = changeDropdown;
}
.resizable-container {
height: 100%;
padding: 4px;
border-radius: 8px;
background-color: color-mix(in srgb, var(--chart-bg), var(--chart-border) 10%);
border: 1px solid var(--chart-border);
overflow: hidden;
transform: translate3d(0, 0, 0);
}
.resizable {
width: 100%;
max-width: 100%;
max-height: 100%;
overflow: hidden;
resize: both;
}
export function getData() {
const data: { date: Date; value: number }[] = [];
const start = new Date(2022, 0, 1);
const end = new Date(2024, 11, 31);
let value = 100;
for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
value += random() * 6 - 3;
value = Math.max(10, value);
data.push({ date: new Date(d), value: Math.round(value * 100) / 100 });
}
return data;
}
let seed = 1234567;
function random() {
seed = (seed * 16807) % 2147483647;
return (seed - 1) / 2147483646;
}
{
ranges: {
dropdown: { visible: 'auto' },
},
}Control this behaviour with the dropdown.visible property.
In this example:
- Select the different options and use the resize handle to see how the buttons respond when the chart width is reduced.
'auto'(default) - Switches to dropdown when buttons exceed available space.'always'- Always shows a dropdown.'never'- Never collapses to dropdown; buttons may overflow.
Styling Copy Link
Customise the appearance of range buttons using styling properties on the ranges options object.
import {
AgChartOptions,
AgCharts,
LineSeriesModule,
ModuleRegistry,
NavigatorModule,
NumberAxisModule,
RangesModule,
UnitTimeAxisModule,
ZoomModule,
} from "ag-charts-enterprise";
import { getData } from "./data";
ModuleRegistry.registerModules([
LineSeriesModule,
NumberAxisModule,
UnitTimeAxisModule,
RangesModule,
ZoomModule,
NavigatorModule,
]);
const options: AgChartOptions = {
data: getData(),
series: [
{
type: "line",
xKey: "date",
yKey: "value",
},
],
axes: {
x: {
type: "unit-time",
label: {
autoRotate: false,
},
},
y: {
type: "number",
},
},
zoom: { enabled: true },
navigator: { enabled: true },
ranges: {
enabled: true,
fill: "#6366f1",
cornerRadius: 8,
textColor: "#ffffff",
stroke: "#4f46e5",
strokeWidth: 2,
active: {
fill: "#16a34a",
textColor: "#ffffff",
stroke: "#15803d",
},
hover: {
fill: "#ea580c",
textColor: "#ffffff",
stroke: "#c2410c",
},
disabled: {
fill: "#e5e7eb",
textColor: "#9ca3af",
stroke: "#d1d5db",
},
button: {
padding: { top: 6, right: 12, bottom: 6, left: 12 },
},
gap: 4,
},
};
options.container = document.getElementById("myChart");
const chart = AgCharts.create(options);
export function getData() {
const data: { date: Date; value: number }[] = [];
const start = new Date(2024, 6, 1);
const end = new Date(2024, 11, 31);
let value = 100;
for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
value += random() * 6 - 3;
value = Math.max(10, value);
data.push({ date: new Date(d), value: Math.round(value * 100) / 100 });
}
return data;
}
let seed = 1234567;
function random() {
seed = (seed * 16807) % 2147483647;
return (seed - 1) / 2147483646;
}
{
ranges: {
fill: '#6366f1',
cornerRadius: 8,
textColor: '#ffffff',
stroke: '#4f46e5',
active: {
fill: '#16a34a',
textColor: '#ffffff',
stroke: '#15803d',
},
hover: {
fill: '#ea580c',
textColor: '#ffffff',
stroke: '#c2410c',
},
disabled: {
fill: '#e5e7eb',
textColor: '#9ca3af',
stroke: '#d1d5db',
},
},
}In this example:
- Default - Purple fill. The idle state for buttons that are not active, hovered, or disabled.
- Active - Green fill. Click a button to see this state.
- Hover - Orange fill. Hover over a button to see this state.
- Disabled - Light grey fill with muted text. The '1Y' button shows this state as the data only spans 6 months.
- Button and dropdown styling inherit from the top level options, but can be overridden with the
buttonanddropdownobjects.
API Reference Copy Link
Properties available on the AgRangesOptions interface.
- enableOutOfRange
booleandefault: false - Whether out of range buttons should be enabled.
- gap
PixelSizedefault: 0 - The gap between each button.
- position
AgRangesPositiondefault: 'top-right' - The position of the range buttons on the chart.
- spacing
PixelSizedefault: 10 - The spacing between the range buttons and the series area or axis when positioned at the top or bottom, respectively.
- button
AgRangesButtonStyles - dropdown
AgRangesDropdown - buttons
AgRangesButton[] - The buttons to display.
- enabled
boolean - Whether the associated elements and properties should be used in the chart.
- cornerRadius
PixelSize - padding
Padding - The padding inside the range buttons. A number applies uniform padding; an object sets each side.
- textColor
CssColor - active
AgRangesStateStyles - disabled
AgRangesStateStyles - hover
AgRangesStateStyles - fill
CssColor - The colour for filling shapes.
- fillOpacity
Opacity - The opacity of the fill colour.
- fontSize
FontSize - The size of the font in pixels for text elements.
- fontFamily
FontFamily - The font family for text elements.
- fontStyle
FontStyle - The style to use for text elements.
- fontWeight
FontWeight - The font weight to use for text elements.
- stroke
AgCssColorOrRef - The colour for the stroke.
- strokeWidth
PixelSize - The width of the stroke in pixels.
Properties available on the AgRangesOptions interface.
- enableOutOfRange
booleandefault: false - Whether out of range buttons should be enabled.
- gap
PixelSizedefault: 0 - The gap between each button.
- position
AgRangesPositiondefault: 'top-right' - The position of the range buttons on the chart.
- spacing
PixelSizedefault: 10 - The spacing between the range buttons and the series area or axis when positioned at the top or bottom, respectively.
- button
AgRangesButtonStyles - dropdown
AgRangesDropdown - buttons
AgRangesButton[] - The buttons to display.
- enabled
boolean - Whether the associated elements and properties should be used in the chart.
- cornerRadius
PixelSize - padding
Padding - The padding inside the range buttons. A number applies uniform padding; an object sets each side.
- textColor
CssColor - active
AgRangesStateStyles - disabled
AgRangesStateStyles - hover
AgRangesStateStyles - fill
CssColor - The colour for filling shapes.
- fillOpacity
Opacity - The opacity of the fill colour.
- fontSize
FontSize - The size of the font in pixels for text elements.
- fontFamily
FontFamily - The font family for text elements.
- fontStyle
FontStyle - The style to use for text elements.
- fontWeight
FontWeight - The font weight to use for text elements.
- stroke
AgCssColorOrRef - The colour for the stroke.
- strokeWidth
PixelSize - The width of the stroke in pixels.