Data Selection allows users click or drag on the chart to mark individual datums as selected. Selected datums receive a distinct visual treatment and can be read back, set, or cleared programmatically.
Selection Copy Link
To enable this feature, set selection.enabled to true.
import {
AgCartesianChartOptions,
AgCharts,
BarSeriesModule,
CategoryAxisModule,
LegendModule,
ModuleRegistry,
NumberAxisModule,
SelectionModule,
} from "ag-charts-enterprise";
import { getData } from "./data";
ModuleRegistry.registerModules([
BarSeriesModule,
CategoryAxisModule,
LegendModule,
NumberAxisModule,
SelectionModule,
]);
const options: AgCartesianChartOptions = {
title: { text: "Quarterly Revenue" },
subtitle: { text: "Click or drag to select" },
selection: {
enabled: true,
enableDrag: true,
},
data: getData(),
series: [
{
type: "bar",
xKey: "quarter",
yKey: "revenue",
yName: "Revenue ($m)",
highlight: { enabled: false },
},
],
axes: {
x: { type: "category" },
y: { type: "number" },
},
listeners: {
selectionChange: () => {
const count = Array.from(chart.getSelection()).length;
document.getElementById("selectionStatus")!.textContent =
count === 0
? "No items selected"
: `${count} item${count === 1 ? "" : "s"} selected`;
},
},
};
options.container = document.getElementById("myChart");
const chart = AgCharts.create(options);
export interface QuarterDatum {
quarter: string;
revenue: number;
}
export function getData(): QuarterDatum[] {
return [
{ quarter: "Q1 2023", revenue: 184 },
{ quarter: "Q2 2023", revenue: 212 },
{ quarter: "Q3 2023", revenue: 198 },
{ quarter: "Q4 2023", revenue: 245 },
{ quarter: "Q1 2024", revenue: 221 },
{ quarter: "Q2 2024", revenue: 268 },
{ quarter: "Q3 2024", revenue: 254 },
{ quarter: "Q4 2024", revenue: 301 },
];
}
{
selection: {
enabled: true,
enableDrag: true,
},
}Selection can also be configured independently on each series via the series.selection options.
Click Selection Copy Link
Click selection is enabled by default. Use enableClick: false to disable.
By default, clicking a datum replaces the current selection, and clicking on a blank space clears the selection. Use clickMode and enableClickAwayToClear to modify this behaviour.
import {
AgCartesianChartOptions,
AgCharts,
AgSelectionClickMode,
BarSeriesModule,
CategoryAxisModule,
LegendModule,
ModuleRegistry,
NumberAxisModule,
SelectionModule,
} from "ag-charts-enterprise";
import { getData } from "./data";
ModuleRegistry.registerModules([
BarSeriesModule,
CategoryAxisModule,
LegendModule,
NumberAxisModule,
SelectionModule,
]);
const options: AgCartesianChartOptions = {
subtitle: { text: "clickMode: 'single', clickAwayToClear: true" },
selection: {
enabled: true,
clickMode: "single",
enableClickAwayToClear: true,
},
data: getData(),
series: [
{
type: "bar",
xKey: "quarter",
yKey: "revenue",
yName: "Revenue ($m)",
highlight: { enabled: false },
},
],
axes: {
x: { type: "category" },
y: { type: "number" },
},
};
options.container = document.getElementById("myChart");
const chart = AgCharts.create(options);
function setClickMode(event: Event) {
const clickMode = (event.target as HTMLInputElement)
.value as AgSelectionClickMode;
options.selection = { ...options.selection, clickMode };
options.subtitle = {
text: `clickMode: '${options.selection!.clickMode}', clickAwayToClear: ${options.selection!.enableClickAwayToClear}`,
};
chart.update(options);
}
function setClickAway(event: Event) {
const enableClickAwayToClear =
(event.target as HTMLInputElement).value === "true";
options.selection = { ...options.selection, enableClickAwayToClear };
options.subtitle = {
text: `clickMode: '${options.selection!.clickMode}', clickAwayToClear: ${options.selection!.enableClickAwayToClear}`,
};
chart.update(options);
}
if (typeof window !== "undefined") {
// Attach external event handlers to window so they can be called from index.html
(<any>window).setClickMode = setClickMode;
(<any>window).setClickAway = setClickAway;
}
export interface QuarterDatum {
quarter: string;
revenue: number;
}
export function getData(): QuarterDatum[] {
return [
{ quarter: "Q1 2023", revenue: 184 },
{ quarter: "Q2 2023", revenue: 212 },
{ quarter: "Q3 2023", revenue: 198 },
{ quarter: "Q4 2023", revenue: 245 },
{ quarter: "Q1 2024", revenue: 221 },
{ quarter: "Q2 2024", revenue: 268 },
{ quarter: "Q3 2024", revenue: 254 },
{ quarter: "Q4 2024", revenue: 301 },
];
}
{
selection: {
enabled: true,
clickMode: 'single',
enableClickAwayToClear: true,
},
}In the above example:
'single'replaces the current selection with the clicked datum.'multiple'toggles the clicked datum in or out of the existing selection. This mode is particularly useful on touch devices.- Holding ^ Ctrl⌘ Command key while clicking will always add or remove the clicked datum from the selection.
- When
enableClickAwayToClearis set tofalse, the selection remains in place when the user clicks an empty area of the chart. - Click range is determined by the
nodeClickRangeproperty on each series type.
Drag-to-Select Copy Link
Set enableDrag to true to allow the user draw a rectangle across the chart and select every datum the rectangle covers. This is only available on cartesian series types.
import {
AgCartesianChartOptions,
AgCharts,
AgSelectionContainment,
BubbleSeriesModule,
ModuleRegistry,
NumberAxisModule,
SelectionModule,
} from "ag-charts-enterprise";
import { getData } from "./data";
ModuleRegistry.registerModules([
BubbleSeriesModule,
NumberAxisModule,
SelectionModule,
]);
const options: AgCartesianChartOptions = {
title: { text: "Drag to select" },
selection: {
enabled: true,
enableDrag: true,
containment: "any",
},
data: getData(),
series: [
{
type: "bubble",
xKey: "height",
xName: "Height",
yKey: "weight",
yName: "Weight",
sizeKey: "age",
sizeName: "Age",
highlight: { enabled: false },
},
],
axes: {
x: { type: "number", title: { text: "Height (cm)" } },
y: { type: "number", title: { text: "Weight (kg)" } },
},
};
options.container = document.getElementById("myChart");
const chart = AgCharts.create(options);
function containmentChange(event: Event) {
const containment = (event.target as HTMLInputElement)
.value as AgSelectionContainment;
options.selection = { ...options.selection, containment };
chart.update(options);
}
if (typeof window !== "undefined") {
// Attach external event handlers to window so they can be called from index.html
(<any>window).containmentChange = containmentChange;
}
export interface PersonDatum {
height: number;
weight: number;
age: number;
}
export function getData(): PersonDatum[] {
return [
{ height: 152, weight: 48, age: 22 },
{ height: 155, weight: 52, age: 28 },
{ height: 158, weight: 50, age: 19 },
{ height: 160, weight: 55, age: 35 },
{ height: 161, weight: 58, age: 42 },
{ height: 162, weight: 53, age: 25 },
{ height: 163, weight: 60, age: 31 },
{ height: 164, weight: 56, age: 27 },
{ height: 165, weight: 62, age: 48 },
{ height: 165, weight: 54, age: 20 },
{ height: 166, weight: 65, age: 55 },
{ height: 167, weight: 59, age: 33 },
{ height: 168, weight: 63, age: 39 },
{ height: 168, weight: 57, age: 24 },
{ height: 169, weight: 68, age: 45 },
{ height: 170, weight: 61, age: 29 },
{ height: 170, weight: 72, age: 52 },
{ height: 171, weight: 66, age: 36 },
{ height: 172, weight: 64, age: 30 },
{ height: 172, weight: 75, age: 58 },
{ height: 173, weight: 70, age: 41 },
{ height: 173, weight: 62, age: 23 },
{ height: 174, weight: 68, age: 34 },
{ height: 174, weight: 78, age: 50 },
{ height: 175, weight: 65, age: 26 },
{ height: 175, weight: 73, age: 44 },
{ height: 175, weight: 82, age: 61 },
{ height: 176, weight: 70, age: 32 },
{ height: 176, weight: 60, age: 21 },
{ height: 177, weight: 76, age: 47 },
{ height: 177, weight: 67, age: 28 },
{ height: 178, weight: 72, age: 37 },
{ height: 178, weight: 80, age: 53 },
{ height: 179, weight: 69, age: 25 },
{ height: 179, weight: 85, age: 59 },
{ height: 180, weight: 74, age: 40 },
{ height: 180, weight: 66, age: 22 },
{ height: 180, weight: 88, age: 63 },
{ height: 181, weight: 78, age: 46 },
{ height: 181, weight: 71, age: 30 },
{ height: 182, weight: 76, age: 38 },
{ height: 182, weight: 83, age: 55 },
{ height: 183, weight: 73, age: 27 },
{ height: 183, weight: 90, age: 60 },
{ height: 184, weight: 80, age: 43 },
{ height: 184, weight: 69, age: 24 },
{ height: 185, weight: 77, age: 35 },
{ height: 185, weight: 86, age: 51 },
{ height: 185, weight: 72, age: 20 },
{ height: 186, weight: 82, age: 48 },
{ height: 186, weight: 74, age: 29 },
{ height: 187, weight: 79, age: 36 },
{ height: 187, weight: 92, age: 62 },
{ height: 188, weight: 84, age: 44 },
{ height: 188, weight: 76, age: 26 },
{ height: 189, weight: 88, age: 54 },
{ height: 189, weight: 78, age: 33 },
{ height: 190, weight: 82, age: 39 },
{ height: 190, weight: 95, age: 65 },
{ height: 190, weight: 75, age: 23 },
{ height: 191, weight: 86, age: 47 },
{ height: 192, weight: 90, age: 56 },
{ height: 192, weight: 80, age: 31 },
{ height: 193, weight: 84, age: 42 },
{ height: 193, weight: 98, age: 64 },
{ height: 194, weight: 88, age: 49 },
{ height: 195, weight: 92, age: 57 },
{ height: 195, weight: 82, age: 28 },
{ height: 196, weight: 96, age: 60 },
{ height: 197, weight: 86, age: 37 },
{ height: 198, weight: 100, age: 66 },
{ height: 155, weight: 70, age: 50 },
{ height: 160, weight: 75, age: 58 },
{ height: 165, weight: 80, age: 62 },
{ height: 170, weight: 58, age: 19 },
{ height: 175, weight: 90, age: 56 },
{ height: 180, weight: 60, age: 18 },
{ height: 185, weight: 95, age: 64 },
{ height: 190, weight: 70, age: 21 },
{ height: 163, weight: 72, age: 46 },
];
}
{
selection: {
enabled: true,
enableDrag: true,
containment: 'any',
},
}In the above example:
- Dragging the mouse across the chart draws a rectangle. When the mouse is released, any datums that overlap the rectangle are selected.
- Holding ^ Ctrl⌘ Command key while completing a drag adds the newly enclosed datums to the existing selection instead of replacing it.
- The
containmentoption controls which datums the drag rectangle picks up.'any'(default) selects a datum if any part of it overlaps the drag rectangle.'all'selects a datum only when it is entirely enclosed by the drag rectangle.
Styling Copy Link
Use the series series.selection.selectedItem and series.selection.unselectedItem options to customise the appearance of selected and unselected datums.
import {
AgCartesianChartOptions,
AgCharts,
BarSeriesModule,
CategoryAxisModule,
LegendModule,
ModuleRegistry,
NumberAxisModule,
SelectionModule,
} from "ag-charts-enterprise";
import { getData } from "./data";
ModuleRegistry.registerModules([
BarSeriesModule,
CategoryAxisModule,
LegendModule,
NumberAxisModule,
SelectionModule,
]);
const options: AgCartesianChartOptions = {
title: { text: "Quarterly Revenue" },
selection: {
enabled: true,
enableDrag: true,
},
data: getData(),
series: [
{
type: "bar",
xKey: "quarter",
yKey: "revenue",
yName: "Revenue ($m)",
highlight: { enabled: false },
selection: {
selectedItem: {
fill: "#c0392b",
stroke: "#922b21",
strokeWidth: 3,
},
unselectedItem: {
fill: "#bdc3c7",
fillOpacity: 0.6,
},
},
},
],
axes: {
x: { type: "category" },
y: { type: "number" },
},
};
options.container = document.getElementById("myChart");
const chart = AgCharts.create(options);
export interface QuarterDatum {
quarter: string;
revenue: number;
}
export function getData(): QuarterDatum[] {
return [
{ quarter: "Q1 2023", revenue: 184 },
{ quarter: "Q2 2023", revenue: 212 },
{ quarter: "Q3 2023", revenue: 198 },
{ quarter: "Q4 2023", revenue: 245 },
{ quarter: "Q1 2024", revenue: 221 },
{ quarter: "Q2 2024", revenue: 268 },
{ quarter: "Q3 2024", revenue: 254 },
{ quarter: "Q4 2024", revenue: 301 },
];
}
{
series: [
{
type: 'bar',
xKey: 'quarter',
yKey: 'revenue',
selection: {
selectedItem: {
fill: '#c0392b',
stroke: '#922b21',
strokeWidth: 3,
},
unselectedItem: {
fill: '#bdc3c7',
fillOpacity: 0.6,
},
},
},
],
}In this example:
selectedItemsets the selected datum to a red fill and border.unselectedItemsets the unselected datums to a grey fill.- For dynamic per-datum styling, use the series item styler, which includes a
selectionStateproperty in the parameters.
Candidacy Copy Link
The candidateState property in Styler callbacks can be used to customise the styling while a drag motion is in progress based on the pending selection state.
import {
AgCartesianChartOptions,
AgCharts,
BarSeriesModule,
CategoryAxisModule,
LegendModule,
ModuleRegistry,
NumberAxisModule,
SelectionModule,
} from "ag-charts-enterprise";
ModuleRegistry.registerModules([
BarSeriesModule,
CategoryAxisModule,
LegendModule,
NumberAxisModule,
SelectionModule,
]);
const options: AgCartesianChartOptions = {
title: { text: "Drag the mouse to view custom candidacy styling" },
selection: {
enabled: true,
enableDrag: true,
},
data: [
{ category: "A", value: 30 },
{ category: "B", value: 25 },
{ category: "C", value: 40 },
{ category: "D", value: 35 },
],
series: [
{
type: "bar",
xKey: "category",
yKey: "value",
itemStyler: (params) => {
const { candidateState, selectionState } = params;
// Is this datum included in a drag motion?
if (
candidateState === "selected-item" &&
(selectionState === "unselected-item" || selectionState == "none")
) {
return { fill: "green" };
}
// Is this datum excluded from a drag motion?
if (
selectionState === "selected-item" &&
(candidateState === "unselected-item" || candidateState === "none")
) {
return { fill: "red" };
}
// No dragging is in progress; Is this datum selected?
if (selectionState === "selected-item") {
return { fill: "skyblue" };
}
// Default: No dragging is in progress; Not selected.
return { fill: "gray" };
},
},
],
axes: {
x: { type: "category" },
y: { type: "number" },
},
};
options.container = document.getElementById("myChart");
const chart = AgCharts.create(options);
In this example:
- When no dragging is in progress:
- Selected bars are rendered in
'skyblue'colour. - Unselected bars are dimmed.
- Selected bars are rendered in
- When dragging is in progress:
- Bars that will be added to the selection are rendered in
'green'colour. - Bars that will be removed from the selection are rendered in
'red'colour.
- Bars that will be added to the selection are rendered in
The candidateState property includes:
undefined- no drag selection is in progress.'selected-item'- the datum will become selected after the drag completes.'unselected-item'- the datum will become unselected after the drag completes.'none'- there will be nothing selected after the drag completes.
Once the drag completes, the candidateState becomes the new selectionState. If the user cancels the drag, the candidateState is cleared and the selectionState remains unchanged.
Selection API Copy Link
import {
AgCartesianChartOptions,
AgCharts,
AgSelectionItemIds,
BarSeriesModule,
CategoryAxisModule,
LegendModule,
ModuleRegistry,
NumberAxisModule,
SelectionModule,
} from "ag-charts-enterprise";
import { getData } from "./data";
let savedSelection: AgSelectionItemIds[] = [];
ModuleRegistry.registerModules([
BarSeriesModule,
CategoryAxisModule,
LegendModule,
NumberAxisModule,
SelectionModule,
]);
const options: AgCartesianChartOptions = {
title: { text: "Click bars, then use the buttons above" },
selection: {
enabled: true,
enableDrag: true,
},
data: getData(),
series: [
{
type: "bar",
xKey: "quarter",
yKey: "revenue",
yName: "Revenue ($m)",
highlight: { enabled: false },
},
],
axes: {
x: { type: "category" },
y: { type: "number" },
},
listeners: {
selectionChange: (event) => {
console.log("selectionChange", {
source: event.source,
added: event.added.map((item) => ({
seriesId: item.seriesId,
itemId: item.itemId,
})),
removed: event.removed.map((item) => ({
seriesId: item.seriesId,
itemId: item.itemId,
})),
});
},
},
};
options.container = document.getElementById("myChart");
const chart = AgCharts.create(options);
function logSelection() {
console.log("selection", Array.from(chart.getSelection()));
}
function saveSelection() {
savedSelection = Array.from(chart.getSelection()).map(
({ seriesId, itemId }) => ({ seriesId, itemId }),
);
console.log("saved", savedSelection.length, "item(s)");
}
function restoreSelection() {
chart.setSelection(savedSelection);
}
function clearSelection() {
chart.clearSelection();
}
if (typeof window !== "undefined") {
// Attach external event handlers to window so they can be called from index.html
(<any>window).logSelection = logSelection;
(<any>window).saveSelection = saveSelection;
(<any>window).restoreSelection = restoreSelection;
(<any>window).clearSelection = clearSelection;
}
export interface QuarterDatum {
quarter: string;
revenue: number;
}
export function getData(): QuarterDatum[] {
return [
{ quarter: "Q1 2023", revenue: 184 },
{ quarter: "Q2 2023", revenue: 212 },
{ quarter: "Q3 2023", revenue: 198 },
{ quarter: "Q4 2023", revenue: 245 },
{ quarter: "Q1 2024", revenue: 221 },
{ quarter: "Q2 2024", revenue: 268 },
{ quarter: "Q3 2024", revenue: 254 },
{ quarter: "Q4 2024", revenue: 301 },
];
}
Saving and Restoring Copy Link
chart.getSelection() returns an Iterable of every currently selected item. Each item contains:
seriesId- the series the datum belongs to.itemId- the unique identifier of the datum, derived fromdataIdKeyif set, otherwise the datum index.datum- the original data object from the chart data array.
chart.setSelection(items) replaces the current selection. Each item requires seriesId and itemId to identify the datum. The existing selection is cleared before the new items are applied.
chart.clearSelection() removes every selected item across all series.
Selection Change Event Copy Link
The selectionChange event fires whenever the selection is updated, whether by user interaction or an API call.
{
listeners: {
selectionChange: (event) => {
console.log(event.source, event.added, event.removed);
},
},
}The event contains:
source-'user-interaction'or'api-call'.added- an array of items added to the selection.removed- an array of items removed from the selection.
Feature Interactions Copy Link
Highlighting Copy Link
When both selection and highlighting are enabled, the chart merges their visual styles. If there is a conflict, the selection style takes priority.
Zoom Copy Link
When both selection drag and zoom drag-to-select (enableSelecting) are enabled, the selection drag takes precedence. Zoom panning uses the panKey modifier instead. See Zoom Panning for details.
API Reference Copy Link
Properties available on the AgChartSelectionOptions interface.
- enabled
booleandefault: false - Set to `true` to enable the data-selection module.
- enableClick
booleandefault: true - Set to `true` to enable click-to-select.
- enableDrag
booleandefault: false - Set to `true` to enable drag-to-select.
- enableClickAwayToClear
booleandefault: true - Set to `true` to clear the selection by clicking an empty space on the chart.
- clickMode
AgSelectionClickModedefault: 'single' - Click-to-select mode. `'single'` replaces the current selection; `'multiple'` toggles each click. Holding Control (or Command) temporarily promotes a single click to `'multiple'`.
- containment
AgSelectionContainmentdefault: 'any' - Drag-to-select containment rule. `'any'` selects a datum when any part overlaps the drag rectangle; `'all'` requires the datum to be fully enclosed.
Properties available on the AgChartSelectionOptions interface.
- enabled
booleandefault: false - Set to `true` to enable the data-selection module.
- enableClick
booleandefault: true - Set to `true` to enable click-to-select.
- enableDrag
booleandefault: false - Set to `true` to enable drag-to-select.
- enableClickAwayToClear
booleandefault: true - Set to `true` to clear the selection by clicking an empty space on the chart.
- clickMode
AgSelectionClickModedefault: 'single' - Click-to-select mode. `'single'` replaces the current selection; `'multiple'` toggles each click. Holding Control (or Command) temporarily promotes a single click to `'multiple'`.
- containment
AgSelectionContainmentdefault: 'any' - Drag-to-select containment rule. `'any'` selects a datum when any part overlaps the drag rectangle; `'all'` requires the datum to be fully enclosed.
Properties available on the AgSelectionOptions interface.
- enabled
boolean - Set to `true` to enable the data-selection on this series.
- containment
AgSelectionContainmentdefault: chart.selection.containment - Override the drag-to-select containment rule for this series.
- selectedItem
AgSelectionStyleOptions - Styling options for selected items.
- unselectedItem
AgSelectionStyleOptions - Styling options for unselected items.
- unselectedSeries
AgSelectionStyleOptions - Styling options for series with no selections when there is at least one other selected series.
Properties available on the AgSelectionOptions interface.
- enabled
boolean - Set to `true` to enable the data-selection on this series.
- containment
AgSelectionContainmentdefault: chart.selection.containment - Override the drag-to-select containment rule for this series.
- selectedItem
AgSelectionStyleOptions - Styling options for selected items.
- unselectedItem
AgSelectionStyleOptions - Styling options for unselected items.
- unselectedSeries
AgSelectionStyleOptions - Styling options for series with no selections when there is at least one other selected series.
Properties available on the AgSelectionChangeEvent interface.
- type required
'selectionChange' - Event type.
- source required
AgSelectionChangeEventSource - An indication of what triggered this event.
- added required
AgSelectionItem[] - Items added to the selection in this change.
- removed required
AgSelectionItem[] - Items removed from the selection in this change.
- defaultPrevented required
boolean - True if the `preventDefault()` method has been called on this event.
- preventDefault required
Function - Prevent the AG Charts built-in default event handlers from running.
- context
TContext - Callback context for this event.
Properties available on the AgSelectionChangeEvent interface.
- type required
'selectionChange' - Event type.
- source required
AgSelectionChangeEventSource - An indication of what triggered this event.
- added required
AgSelectionItem[] - Items added to the selection in this change.
- removed required
AgSelectionItem[] - Items removed from the selection in this change.
- defaultPrevented required
boolean - True if the `preventDefault()` method has been called on this event.
- preventDefault required
Function - Prevent the AG Charts built-in default event handlers from running.
- context
TContext - Callback context for this event.