---
title: "Events"
framework: react
version: "14.1.0"
---

# Events

This section explains how to listen and respond to various chart and series events.

## Chart Events

These events are raised by interactions across the entire chart.

### click and doubleClick

These are fired on click or double-click on any empty part of the chart. When a user double-clicks, the `click` event will be fired on the first click, then both the `click` and `doubleClick` will be fired on the second click.

These events may be prevented by other clickable parts of the chart, such as series nodes and legend items which have their own events.

#### Chart Single & Double Click Events

```tsx
import React, { useState } from "react";
import { createRoot } from "react-dom/client";
import { AgCharts } from "ag-charts-react";
import {
  AgChartClickEvent,
  AgChartDoubleClickEvent,
  AgChartOptions,
  BarSeriesModule,
  CategoryAxisModule,
  LegendModule,
  ModuleRegistry,
  NumberAxisModule,
} from "ag-charts-community";

ModuleRegistry.registerModules([
  BarSeriesModule,
  CategoryAxisModule,
  LegendModule,
  NumberAxisModule,
]);

const ChartExample = () => {
  const [options, setOptions] = useState<AgChartOptions>({
    title: {
      text: "Number of Cars Sold",
    },
    subtitle: {
      text: "(single or double click empty space outside bars)",
    },
    data: [
      { month: "March", units: 25, brands: { BMW: 10, Toyota: 15 } },
      { month: "April", units: 27, brands: { Ford: 17, BMW: 10 } },
      { month: "May", units: 42, brands: { Nissan: 20, Toyota: 22 } },
    ],
    series: [
      {
        type: "bar",
        xKey: "month",
        yKey: "units",
      },
    ],
    listeners: {
      click: (_event: AgChartClickEvent) => {
        console.log("[click]");
      },
      doubleClick: (_event: AgChartDoubleClickEvent) => {
        console.log("[double click]");
      },
    },
  });

  return <AgCharts options={options} />;
};

const root = createRoot(document.getElementById("root")!);
root.render(<ChartExample />);
```

[Live example: Chart Single & Double Click Events](https://www.ag-grid.com/charts/reactFunctionalTs/events/examples/chart-click-event)

In this example:

- When a blank area on a chart is clicked, a message is shown in the console.
- When a blank area on a chart is double-clicked, a different message is shown.

### seriesNodeClick and seriesNodeDoubleClick

These are fired on click or double-click of any series node in the chart.

The contents of the event object passed to the listener will depend on the type of series the clicked node belongs to.

#### Node Click Event

```tsx
import React, { useState } from "react";
import { createRoot } from "react-dom/client";
import { AgCharts } from "ag-charts-react";
import {
  AgChartOptions,
  BarSeriesModule,
  CategoryAxisModule,
  LegendModule,
  LineSeriesModule,
  ModuleRegistry,
  NumberAxisModule,
} from "ag-charts-community";
import { DataType, getData } from "./data";

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

const ChartExample = () => {
  const [options, setOptions] = useState<AgChartOptions<DataType>>({
    title: {
      text: "Average low/high temperatures in London",
    },
    subtitle: {
      text: "(click a data point for details)",
    },
    data: getData(),
    series: [
      {
        type: "line",
        xKey: "month",
        yKey: "high",
      },
      {
        type: "bar",
        xKey: "month",
        yKey: "low",
      },
    ],
    legend: {
      enabled: false,
    },
    listeners: {
      seriesNodeClick: ({ datum, yKey, seriesId }) => {
        console.log(
          `[click]\nTemperature in ${datum.month}: ${String(datum[yKey!])}°C\nSeries: ${seriesId}`,
        );
      },
      seriesNodeDoubleClick: ({ datum, yKey, seriesId }) => {
        const celsius = Number(datum[yKey!]);
        const fahrenheit = (celsius * 9) / 5 + 32;
        console.log(
          `[double click]\nTemperature in ${datum.month}: ${fahrenheit.toFixed(2)}°F\nSeries: ${seriesId}`,
        );
      },
    },
  });

  return <AgCharts options={options} />;
};

const root = createRoot(document.getElementById("root")!);
root.render(<ChartExample />);
```

[Live example: Node Click Event](https://www.ag-grid.com/charts/reactFunctionalTs/events/examples/series-node-click-event)

In this example:

- Whenever a column or line marker is clicked, information about that series node is shown in the console.
- Whenever a column or line marker is double-clicked, the information is shown with temperatures in Fahrenheit.
- The ID of the series that contains the clicked node is also logged.

### seriesVisibilityChange

This is fired when the visibility of a series or data item is toggled. This is usually triggered by user interaction with a legend item.

This event contains:

- The `seriesId` of the series.
- The [`itemId`](#item-identifiers), `legendItemName` or other identifiers of the changed item.
- `visible` - the new visibility state of the series or item.

#### Series Visibility Changed

```tsx
import React, { useState, Fragment } from "react";
import { createRoot } from "react-dom/client";
import { AgCharts } from "ag-charts-react";
import {
  AgChartLegendClickEvent,
  AgPolarChartOptions,
  AgSeriesVisibilityChange,
  LegendModule,
  ModuleRegistry,
  PieSeriesModule,
} from "ag-charts-community";

let counter = 1;
ModuleRegistry.registerModules([LegendModule, PieSeriesModule]);

const ChartExample = () => {
  const [options, setOptions] = useState<AgPolarChartOptions>({
    title: { text: "Business Expense Distribution" },
    data: [
      { expense: "Salaries", percentage: 40 },
      { expense: "Office Rent", percentage: 20 },
      { expense: "Marketing", percentage: 15 },
      { expense: "Research & Development", percentage: 10 },
      { expense: "Utilities & Miscellaneous", percentage: 10 },
      { expense: "Travel", percentage: 5 },
    ],
    series: [{ type: "pie", angleKey: "percentage", legendItemKey: "expense" }],
    legend: {
      listeners: {
        legendItemClick: (event: AgChartLegendClickEvent) => {
          counter = (counter + 1) % 2;
          document.getElementById("myCounter")!.textContent = `${counter}`;
          if (counter !== 1) {
            event.preventDefault();
          }
        },
      },
    },
    listeners: {
      seriesVisibilityChange: ({
        seriesId,
        itemId,
        legendItemName,
        visible,
      }: AgSeriesVisibilityChange) => {
        console.log(
          `seriesId: ${seriesId}, itemId: ${itemId}, legendItemName: ${legendItemName}, visible: ${visible}`,
        );
      },
    },
  });

  return (
    <Fragment>
      <div className="example-controls">
        <div className="controls-row center">
          Counter: <span id="myCounter">1</span>
        </div>
      </div>
      <AgCharts options={options} />
    </Fragment>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(<ChartExample />);
```

[Live example: Series Visibility Changed](https://www.ag-grid.com/charts/reactFunctionalTs/events/examples/series-visibility-change)

```js
{
    listeners: {
        seriesVisibilityChange: ({ seriesId, visible }) => {
            console.log(`seriesId: ${seriesId}, visible: ${visible}`);
        },
    },
}
```

In this example:

- When a legend item is clicked, the visibility change is prevented and a counter decreases. This is done by using `preventDefault` on the [legendItemClick](#legenditemclick-and-legenditemdoubleclick) event.
- When the counter hits zero, the series toggle is allowed to occur.
- The series visibility change is fired, with the relevant information shown in the console.

### activeChange

This event is fired when the [active](https://www.ag-grid.com/charts/react/api-state/#active) state is changed. This occurs when a user interaction (mouse, touch, keyboard) on a series node or legend causes a highlight or tooltip change.

The event contains:

- `activeItem` - the item that is now active, or `undefined` if no item is active.
- The `activeItem` contains:
  - `type` - the type of the active item, either `'series-node'` or `'legend'`.
  - `seriesId` and [`itemId`](#item-identifiers) identifying the active item.
- `datum` - the data from the chart data array for the active item.
- `source` - the source of the event, either `'user-interaction'` or `'state-change'`.

#### Active Change Event

```tsx
import React, { useState } from "react";
import { createRoot } from "react-dom/client";
import { AgCharts } from "ag-charts-react";
import {
  AgActiveChangeEvent,
  AgChartOptions,
  BarSeriesModule,
  CategoryAxisModule,
  LegendModule,
  ModuleRegistry,
  NumberAxisModule,
} from "ag-charts-community";
import { getData } from "./data";

ModuleRegistry.registerModules([
  BarSeriesModule,
  LegendModule,
  CategoryAxisModule,
  NumberAxisModule,
]);

const ChartExample = () => {
  const [options, setOptions] = useState<AgChartOptions>({
    title: {
      text: "Energy Production by Source & Country",
    },
    subtitle: {
      text: "Energy Production (TWh)",
    },
    data: getData(),
    series: [
      {
        type: "bar",
        direction: "horizontal",
        xKey: "year",
        yKey: "USACoal",
        yName: "Coal - USA",
        legendItemName: "Coal",
        stackGroup: "usa",
        fill: "#5b5b5b",
      },
      {
        type: "bar",
        direction: "horizontal",
        xKey: "year",
        yKey: "USAGas",
        yName: "Natural Gas - USA",
        legendItemName: "Natural Gas",
        stackGroup: "usa",
        fill: "#f2a541",
      },
      {
        type: "bar",
        direction: "horizontal",
        xKey: "year",
        yKey: "USARenewables",
        yName: "Renewables - USA",
        legendItemName: "Renewables",
        stackGroup: "usa",
        fill: "#4caf50",
      },
      {
        type: "bar",
        direction: "horizontal",
        xKey: "year",
        yKey: "USANuclear",
        yName: "Nuclear - USA",
        legendItemName: "Nuclear",
        stackGroup: "usa",
        fill: "#6f7bd9",
      },
      {
        type: "bar",
        direction: "horizontal",
        xKey: "year",
        yKey: "GermanyCoal",
        yName: "Coal - Germany",
        legendItemName: "Coal",
        stackGroup: "germany",
        showInLegend: false,
        fill: "#5b5b5b",
      },
      {
        type: "bar",
        direction: "horizontal",
        xKey: "year",
        yKey: "GermanyGas",
        yName: "Natural Gas - Germany",
        legendItemName: "Natural Gas",
        stackGroup: "germany",
        showInLegend: false,
        fill: "#f2a541",
      },
      {
        type: "bar",
        direction: "horizontal",
        xKey: "year",
        yKey: "GermanyRenewables",
        yName: "Renewables - Germany",
        legendItemName: "Renewables",
        stackGroup: "germany",
        showInLegend: false,
        fill: "#4caf50",
      },
      {
        type: "bar",
        direction: "horizontal",
        xKey: "year",
        yKey: "GermanyNuclear",
        yName: "Nuclear - Germany",
        legendItemName: "Nuclear",
        stackGroup: "germany",
        showInLegend: false,
        fill: "#6f7bd9",
      },
      {
        type: "bar",
        direction: "horizontal",
        xKey: "year",
        yKey: "ChinaCoal",
        yName: "Coal - China",
        legendItemName: "Coal",
        stackGroup: "china",
        showInLegend: false,
        fill: "#5b5b5b",
      },
      {
        type: "bar",
        direction: "horizontal",
        xKey: "year",
        yKey: "ChinaGas",
        yName: "Natural Gas - China",
        legendItemName: "Natural Gas",
        stackGroup: "china",
        showInLegend: false,
        fill: "#f2a541",
      },
      {
        type: "bar",
        direction: "horizontal",
        xKey: "year",
        yKey: "ChinaRenewables",
        yName: "Renewables - China",
        legendItemName: "Renewables",
        stackGroup: "china",
        showInLegend: false,
        fill: "#4caf50",
      },
      {
        type: "bar",
        direction: "horizontal",
        xKey: "year",
        yKey: "ChinaNuclear",
        yName: "Nuclear - China",
        legendItemName: "Nuclear",
        stackGroup: "china",
        showInLegend: false,
        fill: "#6f7bd9",
      },
    ],
    listeners: {
      activeChange: (ev: AgActiveChangeEvent<unknown, unknown>) => {
        if (ev.activeItem === undefined) {
          console.log(`[inactive], event:`, ev);
        } else {
          const { type: t, seriesId: s, itemId: i } = ev.activeItem;
          console.log(`[${t}], seriesId: ${s}, itemId: ${i}, event:`, ev);
        }
      },
    },
  });

  return <AgCharts options={options} />;
};

const root = createRoot(document.getElementById("root")!);
root.render(<ChartExample />);
```

[Live example: Active Change Event](https://www.ag-grid.com/charts/reactFunctionalTs/events/examples/active-change-event)

```js
{
    listeners: {
        activeChange: (ev) => {
            if (ev.activeItem === undefined) {
                console.log(`[inactive], event:`, ev);
            } else {
                const { type: t, seriesId: s, itemId: i } = ev.activeItem;
                console.log(`[${t}], seriesId: ${s}, itemId: ${i}, event:`, ev);
            }
        },
    },
}
```

In this example:

- Whenever a user interaction (mouse, touch, keyboard) on the series-area or legend changes the highlight state, a message is shown in the console.

### selectionChange

This is fired when the [Data Selection](https://www.ag-grid.com/charts/react/selection/) is updated by either user interaction or an API call. See [Selection Change Event](https://www.ag-grid.com/charts/react/selection/#selection-change-event) for full details.

### collapsedChange

This is fired when an item in an [Org Chart](https://www.ag-grid.com/charts/react/org-chart/) is expanded or collapsed, by either user interaction or an API call.

The event contains:

- `collapsed` - array of the items newly collapsed by this change, each with `itemId` and `datum`:
  - `itemId` - the unique identifier of the datum.
  - `datum` - the data from the chart data array for the collapsed item.
- `expanded` - array of the items newly expanded by this change, each with `itemId` and `datum`:
  - `itemId` - the unique identifier of the datum.
  - `datum` - the data from the chart data array for the expanded item.
- `source` - the source of the event, either `'user-interaction'` or `'api-call'`.

> **Note**
>
> `collapsed` and `expanded` contain only the items changed by this event, not the full set of collapsed or expanded items. Use `chart.getState()` to get the current state of all items.

#### Collapsed Change Event

```tsx
import React, { useState } from "react";
import { createRoot } from "react-dom/client";
import { AgCharts } from "ag-charts-react";
import {
  AgChartOptions,
  ContextMenuModule,
  ModuleRegistry,
  OrganizationSeriesModule,
} from "ag-charts-enterprise";
import { getData } from "./data";

ModuleRegistry.registerModules([OrganizationSeriesModule, ContextMenuModule]);

const ChartExample = () => {
  const [options, setOptions] = useState<AgChartOptions>({
    title: {
      text: "Company Organisation",
    },
    data: getData(),
    listeners: {
      collapsedChange: (event) => {
        console.log(
          `source: ${event.source},`,
          "just collapsed:",
          event.collapsed.map(({ itemId }) => itemId),
          "just expanded:",
          event.expanded.map(({ itemId }) => itemId),
        );
      },
    },
    initialState: {
      collapsed: [
        "Mr. Jeffrey Brown",
        "Nicole Jones",
        "Justin Contreras",
        "Lawrence Martinez",
        "Eric Jensen",
      ],
    },
    series: [
      {
        type: "organization",
        idKey: "id",
        parentIdKey: "parentId",
        node: {
          image: {
            key: "avatar",
            height: 50,
            width: 50,
            position: "left",
          },
          title: { key: "name" },
          subtitle: { key: "job" },
          labels: [{ key: "location" }],
        },
      },
    ],
  });

  return <AgCharts options={options} />;
};

const root = createRoot(document.getElementById("root")!);
root.render(<ChartExample />);
```

[Live example: Collapsed Change Event](https://www.ag-grid.com/charts/reactFunctionalTs/events/examples/collapsed-change-event)

In this example:

- Whenever a node is collapsed or expanded, a message is shown in the console.

### annotations

This is fired when the [annotations](https://www.ag-grid.com/charts/react/annotations/) are changed, added or removed in either cartesian charts or with the [financial charts toolbar](https://www.ag-grid.com/charts/react/financial-charts-toolbar/).

#### Annotations

```tsx
import React, { useState } from "react";
import { createRoot } from "react-dom/client";
import { AgCharts } from "ag-charts-react";
import {
  AgChartOptions,
  AnimationModule,
  AnnotationsModule,
  CategoryAxisModule,
  ChartToolbarModule,
  ContextMenuModule,
  CrosshairModule,
  LegendModule,
  LineSeriesModule,
  ModuleRegistry,
  NumberAxisModule,
} from "ag-charts-enterprise";
import { getData } from "./data";

ModuleRegistry.registerModules([
  AnimationModule,
  AnnotationsModule,
  CategoryAxisModule,
  ChartToolbarModule,
  CrosshairModule,
  LegendModule,
  LineSeriesModule,
  NumberAxisModule,
  ContextMenuModule,
]);

const ChartExample = () => {
  const [options, setOptions] = useState<AgChartOptions>({
    data: getData(),
    title: {
      text: "Monthly Sales Revenue",
    },
    footnote: {
      text: "2024, values in $1000s",
    },
    series: [
      {
        type: "line",
        xKey: "month",
        yKey: "revenue",
        interpolation: { type: "smooth" },
        marker: {
          enabled: false,
        },
      },
    ],
    listeners: {
      annotations: (event) => {
        console.log(event);
      },
    },
    annotations: {
      enabled: true,
      toolbar: {
        buttons: [
          {
            icon: "delete",
            value: "clear",
          },
          {
            icon: "text-annotation",
            value: "text-menu",
          },
        ],
      },
    },
    initialState: {
      annotations: [
        {
          type: "comment",
          x: { value: "Feb", groupPercentage: -0.2 },
          y: 46,
          text: "$45,000",
          fontSize: 12,
        },
        {
          type: "text",
          x: { value: "Jun", groupPercentage: -0.2 },
          y: 81,
          text: "$80,000",
          fontSize: 12,
        },
        {
          type: "note",
          x: "Sep",
          y: 75,
          text: "End of summer dip recovered",
          fontSize: 12,
        },
        {
          type: "callout",
          start: { x: { value: "Dec", groupPercentage: -0.1 }, y: 107 },
          end: { x: "Oct", y: 110 },
          text: "$95,000",
          fontSize: 12,
        },
      ],
    },
  });

  return <AgCharts options={options} />;
};

const root = createRoot(document.getElementById("root")!);
root.render(<ChartExample />);
```

[Live example: Annotations](https://www.ag-grid.com/charts/reactFunctionalTs/events/examples/annotations-event)

This event contains:

- The array of `annotations`.

In this example:

- When an annotation is changed, added or removed, the event is output to the console.

### zoom

This is fired when the zoom level or position changes. This is triggered when [zooming in or out of the chart](https://www.ag-grid.com/charts/react/zoom/), [panning](https://www.ag-grid.com/charts/react/zoom/#panning) or using the [Navigator](https://www.ag-grid.com/charts/react/navigator/).

#### Zoom

```tsx
import React, { useState } from "react";
import { createRoot } from "react-dom/client";
import { AgCharts } from "ag-charts-react";
import {
  AgCartesianChartOptions,
  AnimationModule,
  CategoryAxisModule,
  ContextMenuModule,
  CrosshairModule,
  LegendModule,
  LineSeriesModule,
  ModuleRegistry,
  NumberAxisModule,
  ZoomModule,
} from "ag-charts-enterprise";
import { getData } from "./data";

ModuleRegistry.registerModules([
  AnimationModule,
  CategoryAxisModule,
  CrosshairModule,
  LegendModule,
  LineSeriesModule,
  NumberAxisModule,
  ZoomModule,
  ContextMenuModule,
]);

const ChartExample = () => {
  const [options, setOptions] = useState<AgCartesianChartOptions>({
    title: {
      text: "2023 Average Temperatures",
    },
    subtitle: {
      text: "Oxford, UK",
    },
    zoom: {
      enabled: true,
      anchorPointX: "pointer",
    },
    listeners: {
      zoom: (event) => {
        console.log(event);
      },
    },
    data: getData(),
    series: [
      {
        type: "line",
        xKey: "month",
        xName: "Month",
        yKey: "min",
        yName: "Min Temperature",
        interpolation: { type: "smooth" },
      },
      {
        type: "line",
        xKey: "month",
        xName: "Month",
        yKey: "max",
        yName: "Max Temperature",
        interpolation: { type: "smooth" },
      },
    ],
  });

  return <AgCharts options={options} />;
};

const root = createRoot(document.getElementById("root")!);
root.render(<ChartExample />);
```

[Live example: Zoom](https://www.ag-grid.com/charts/reactFunctionalTs/events/examples/zoom-event)

This event contains:

- A `ratioX` and `ratioY` with `start` and `end` properties with values between `0` and `1`. These represent a proportion of the width or height of the chart.
- Any non-category axes also include `rangeX` or `rangeY` properties. These contain values that match the [axis type](https://www.ag-grid.com/charts/react/axes-types/), e.g. a date for an [Ordinal Time Axis](https://www.ag-grid.com/charts/react/axes-types/#time).

In this example:

- When the zoom level is changed or the chart is panned, the event is output to the console.

## Series Events

These are fired on click or double-click of the series node. Depending on the type of series, a node can mean a bar or a pie sector, or a marker, such as a Line or an Area series marker.

These events contain:

- The `series` the node belongs to.
- The piece of chart data or `datum`.
- The specific keys in that `datum` that were used to fetch the values represented by the clicked node.

### seriesNodeClick and seriesNodeDoubleClick

#### Node Click Event

```tsx
import React, { useState } from "react";
import { createRoot } from "react-dom/client";
import { AgCharts } from "ag-charts-react";
import {
  AgChartOptions,
  BarSeriesModule,
  CategoryAxisModule,
  LegendModule,
  ModuleRegistry,
  NumberAxisModule,
} from "ag-charts-community";
import { DataType, getData } from "./data";

function makeMessage(header: string, datum: DataType) {
  const { brands, month, units } = datum;
  const buffer: string[] = [
    header,
    "\nCars sold in ",
    month,
    ": ",
    String(units),
    "\n",
  ];
  for (const key in brands) {
    buffer.push(key, ": ", String(brands[key]), "\n");
  }
  return buffer.join("");
}
ModuleRegistry.registerModules([
  BarSeriesModule,
  CategoryAxisModule,
  LegendModule,
  NumberAxisModule,
]);

const ChartExample = () => {
  const [options, setOptions] = useState<AgChartOptions<DataType>>({
    title: {
      text: "Number of Cars Sold",
    },
    subtitle: {
      text: "(click a column for details)",
    },
    data: getData(),
    series: [
      {
        type: "bar",
        xKey: "month",
        yKey: "units",
        listeners: {
          seriesNodeClick: (event) =>
            console.log(makeMessage("[click]", event.datum)),
          seriesNodeDoubleClick: (event) =>
            console.log(makeMessage("[double click]", event.datum)),
        },
      },
    ],
  });

  return <AgCharts options={options} />;
};

const root = createRoot(document.getElementById("root")!);
root.render(<ChartExample />);
```

[Live example: Node Click Event](https://www.ag-grid.com/charts/reactFunctionalTs/events/examples/node-click-event)

In this example:

- Whenever a bar is clicked or double-clicked, information about that bar is shown in the console.
- The event listener pulls extra information from the datum containing the bar's value and shows it in the console as well. In this case the breakdown of sales numbers by brand name.

## Legend Events

### legendItemClick and legendItemDoubleClick

These are fired on click or double-click of a legend item.

These events contain:

- The `seriesId` of the series associated with the legend item.
- The [`itemId`](#item-identifiers), usually the `yKey` value for cartesian series.

#### Legend Item Click Event

```tsx
import React, { useState } from "react";
import { createRoot } from "react-dom/client";
import { AgCharts } from "ag-charts-react";
import {
  AgCartesianChartOptions,
  AgChartLegendClickEvent,
  AgChartLegendDoubleClickEvent,
  CategoryAxisModule,
  LegendModule,
  LineSeriesModule,
  ModuleRegistry,
  NumberAxisModule,
} from "ag-charts-community";

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

const ChartExample = () => {
  const [options, setOptions] = useState<AgCartesianChartOptions>({
    data: [
      {
        quarter: "Q1",
        petrol: 200,
        diesel: 100,
      },
      {
        quarter: "Q2",
        petrol: 300,
        diesel: 130,
      },
      {
        quarter: "Q3",
        petrol: 350,
        diesel: 160,
      },
      {
        quarter: "Q4",
        petrol: 400,
        diesel: 200,
      },
    ],
    series: [
      {
        type: "line",
        xKey: "quarter",
        yKey: "petrol",
      },
      {
        type: "line",
        xKey: "quarter",
        yKey: "diesel",
      },
    ],
    legend: {
      listeners: {
        legendItemClick: ({ seriesId, itemId }: AgChartLegendClickEvent) => {
          console.log(`Click - seriesId: ${seriesId}, itemId: ${itemId}`);
        },
        legendItemDoubleClick: ({
          seriesId,
          itemId,
        }: AgChartLegendDoubleClickEvent) => {
          console.log(
            `Double Click - seriesId: ${seriesId}, itemId: ${itemId}`,
          );
        },
      },
    },
  });

  return <AgCharts options={options} />;
};

const root = createRoot(document.getElementById("root")!);
root.render(<ChartExample />);
```

[Live example: Legend Item Click Event](https://www.ag-grid.com/charts/reactFunctionalTs/events/examples/legend-item-click-event)

```js
{
    legend: {
        listeners: {
            legendItemClick: ({ seriesId, itemId }) => {
                console.log(`seriesId: ${seriesId}, itemId: ${itemId}`);
            },
        },
    },
}
```

In this example:

- When a legend item is clicked, a message is logged to the console with the `legendItemClick` event contents.
- When a legend item is double clicked, a message is logged to the console with the `legendItemDoubleClick` event contents.

### Series Visibility Toggling

Although clicking a legend item will usually toggle the series visibility, this is not included in the legend events. Use the chart [seriesVisibilityChange](#seriesvisibilitychange) event to listen for this.

The legend item click events include a `preventDefault` function that can be called to stop the default series visibility toggling. See the [seriesVisibilityChange](#seriesvisibilitychange) event documentation for an example of this.

## Interaction Ranges

By default, the `seriesNodeClick` event is only triggered when the user clicks exactly on a node. You can use the `nodeClickRange` option to instead define a range at which the event is triggered. This can be set to one of three values: `'nearest'`, `'exact'` or a number as a distance in pixels.

#### Interaction Ranges

```tsx
import React, { useState, Fragment } from "react";
import { createRoot } from "react-dom/client";
import { AgCharts } from "ag-charts-react";
import {
  AgCartesianChartOptions,
  CategoryAxisModule,
  LegendModule,
  LineSeriesModule,
  ModuleRegistry,
  NumberAxisModule,
} from "ag-charts-community";
import { DataType, getData } from "./data";
import clone from "clone";

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

const ChartExample = () => {
  const [options, setOptions] = useState<AgCartesianChartOptions<DataType>>({
    data: getData(),
    series: [
      {
        type: "line",
        xKey: "quarter",
        yKey: "petrol",
        nodeClickRange: "exact",
        listeners: {
          seriesNodeClick: ({ datum }) =>
            console.log(`petrol - ${datum.petrol}`),
        },
      },
      {
        type: "line",
        xKey: "quarter",
        yKey: "diesel",
        nodeClickRange: "exact",
        listeners: {
          seriesNodeClick: ({ datum }) =>
            console.log(`diesel - ${datum.diesel}`),
        },
      },
    ],
  });

  const exact = () => {
    const nextOptions = clone(options);

    nextOptions.series = nextOptions.series!.map((series) => ({
      ...series,
      nodeClickRange: "exact",
    }));

    setOptions(nextOptions);
  };

  const nearest = () => {
    const nextOptions = clone(options);

    nextOptions.series = nextOptions.series!.map((series) => ({
      ...series,
      nodeClickRange: "nearest",
    }));

    setOptions(nextOptions);
  };

  const distance = () => {
    const nextOptions = clone(options);

    nextOptions.series = nextOptions.series!.map((series) => ({
      ...series,
      nodeClickRange: 10,
    }));

    setOptions(nextOptions);
  };

  return (
    <Fragment>
      <div className="example-controls">
        <div className="controls-row">
          <button onClick={exact}>Exact (Default)</button>
          <button onClick={nearest}>Nearest</button>
          <button onClick={distance}>Distance (10 Pixels)</button>
        </div>
      </div>
      <AgCharts options={options} />
    </Fragment>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(<ChartExample />);
```

[Live example: Interaction Ranges](https://www.ag-grid.com/charts/reactFunctionalTs/events/examples/interaction-ranges)

In this example:

- `'exact'` (default) will trigger the event if the user clicks exactly on a node.
- `'nearest'` will trigger the event for whichever node is nearest to the click.
- Given a number it will trigger the event when the click is made within that many pixels of a node.

## Item Identifiers

Many events expose an `itemId` to identify the item within its series. How it is derived depends on the item type:

- **Series nodes** use a node identifier.
  - Automatically generated from the data, and may change when the data updates.
  - Set `dataIdKey` to use a `datum` field as a stable identifier across data updates (see [Identifying Items by Key](https://www.ag-grid.com/charts/react/transactions/#identifying-items-by-key)).
  - Series whose nodes don't map directly to a datum - such as [Histogram](https://www.ag-grid.com/charts/react/histogram-series/) bins and [Sankey](https://www.ag-grid.com/charts/react/sankey-series/) or [Chord](https://www.ag-grid.com/charts/react/chord-series/) nodes - expose a `getItemId` callback instead.
  - [Waterfall](https://www.ag-grid.com/charts/react/waterfall-series/) `total` and `subtotal` bars use their `totals.itemId` if set, otherwise their `totals.axisLabel`.
- **Legend items** use the legend item's identifier. Typically the `yKey` value for most series, or the legend item's position for series with one legend item per datum, such as `pie` and `donut`.

## API Reference

#### Series Events

All series event options have similar interface contracts. See the series-specific documentation for variations.

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| seriesNodeClick | Listener |  | The listener to call when a node (marker, column, bar, tile or a pie sector) in the series is clicked. |
| seriesNodeDoubleClick | Listener |  | The listener to call when a node (marker, column, bar, tile or a pie sector) in the series is double-clicked. |

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| nodeClickRange | PixelSize \| 'exact' \| 'nearest' \| 'area' |  | Range from a node that a click triggers the listener. |

#### Legend Events

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| legendItemClick | Function |  | The listener to call when a legend item is clicked. |
| legendItemDoubleClick | Function |  | The listener to call when a legend item is double-clicked. |

#### Chart Events

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| seriesNodeClick | Listener |  | The listener to call when a node (marker, column, bar, tile or a pie sector) in any series is clicked. Useful for a chart containing multiple series. |
| seriesNodeDoubleClick | Listener |  | The listener to call when a node (marker, column, bar, tile or a pie sector) in any series is double-clicked. Useful for a chart containing multiple series. |
| seriesVisibilityChange | Listener |  | The listener to call when a series visibility is changed. |
| activeChange | Listener |  | The listener to call when the active state (highlight/tooltip) is changed. |
| selectionChange | Listener |  | The listener to call when data selection is changed |
| collapsedChange | Listener |  | The listener to call when collapsed items are changed. |
| click | Listener |  | The listener to call when the chart is clicked. |
| doubleClick | Listener |  | The listener to call when the chart is double-clicked. |
| annotations | Listener |  | The listener to call when the annotations are changed. |
| zoom | Listener |  | The listener to call when the zoom is changed. |
