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

# Overlays

There are some options to display custom HTML over a chart.

## Missing Data Overlay

Sometimes end-users can be confused if a chart doesn't have any content. To help them understand that no data has been supplied, a message is displayed over the chart area.

#### Overlay for Missing Data

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

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

const ChartExample = () => {
  const [options, setOptions] = useState<AgChartOptions>({
    title: {
      text: "A chart with missing data",
    },
    data: [],
    series: [
      {
        type: "line",
        xKey: "year",
        yKey: "spending",
      },
    ],
    axes: {
      y: { type: "number", title: { text: "Year" } },
      x: { type: "number", title: { text: "Spending" } },
    },
    overlays: {
      noData: {
        text: "No data to display",
      },
    },
  });

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

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

[Live example: Overlay for Missing Data](https://www.ag-grid.com/charts/reactFunctionalTs/overlays/examples/no-data-plain)

## No Visible Series Overlay

A message is also displayed when all series are hidden:

#### No Visible Series

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

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

const ChartExample = () => {
  const [options, setOptions] = useState<AgChartOptions>({
    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", visible: false },
      { type: "line", xKey: "quarter", yKey: "diesel", visible: false },
    ],
  });

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

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

[Live example: No Visible Series](https://www.ag-grid.com/charts/reactFunctionalTs/overlays/examples/no-visible-series)

## Loading Data Overlay

When using [Asynchronous Data](https://www.ag-grid.com/charts/react/async-data/), a loading data animation is shown while waiting for a response. The overlay can also be shown or hidden manually using the `loading` option. See [Asynchronous Data — Manual Control](https://www.ag-grid.com/charts/react/async-data/#manual-control) for details.

#### Loading Data

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

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

const ChartExample = () => {
  const [options, setOptions] = useState<AgChartOptions>({
    dataSource: {
      getData: () =>
        new Promise(() => {
          // Never resolve so the loading spinner remains
        }),
    },
    series: [
      {
        type: "line",
        xKey: "year",
        yKey: "spending",
      },
    ],
    axes: {
      y: { type: "number", title: { text: "Year" } },
      x: { type: "number", title: { text: "Spending" } },
    },
  });

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

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

[Live example: Loading Data](https://www.ag-grid.com/charts/reactFunctionalTs/overlays/examples/loading)

## Unsupported Browser Overlay

When an [unsupported browser](https://www.ag-grid.com/charts/react/supported-browsers/) is detected and the chart may not operate correctly, we display an overlay to make the user aware of this.

## Customisation

### Text

These messages can be customised through `overlays`:

```js
{
    overlays: {
        loading: {
            text: 'Some custom loading message',
        },
        noData: {
            text: 'Some custom noData message',
        },
        noVisibleSeries: {
            text: 'Some custom noVisibleSeries message',
        },
        unsupportedBrowser: {
            text: 'Some custom unsupportedBrowser message',
        },
    },
}
```

### Custom Overlay

If finer grained control is required, a renderer can be provided to allow full customisation:

#### Custom Overlay for Missing Data

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

const noDataOverlay = () => {
  return [
    "<div",
    '    style="',
    "        align-items: center;",
    "        background: hsl(45deg, 100%, 90%);",
    "        border: 2px solid hsl(0deg, 100%, 75%);",
    "        box-sizing: border-box;",
    "        color: black;",
    "        display: flex;",
    "        height: calc(100% - 16px);",
    "        justify-content: center;",
    "        margin: 8px;",
    '    "',
    ">",
    "    <em>Custom message for <strong>missing data</strong></em>",
    "</div>",
  ].join("\n");
};
ModuleRegistry.registerModules([
  LegendModule,
  LineSeriesModule,
  NumberAxisModule,
]);

const ChartExample = () => {
  const [options, setOptions] = useState<AgChartOptions>({
    title: {
      text: "A chart with missing data",
    },
    data: [],
    series: [
      {
        type: "line",
        xKey: "year",
        yKey: "spending",
      },
    ],
    axes: {
      y: { type: "number", title: { text: "Year" } },
      x: { type: "number", title: { text: "Spending" } },
    },
    overlays: {
      noData: {
        renderer: noDataOverlay,
      },
    },
  });

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

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

[Live example: Custom Overlay for Missing Data](https://www.ag-grid.com/charts/reactFunctionalTs/overlays/examples/no-data)

```js
{
    overlays: {
        noData: {
            renderer: () => '<em>Custom message for <strong>missing data</strong></em>',
        },
    },
}
```

### Custom Loading Spinner

#### Custom Overlay for Loading Data

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

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

const ChartExample = () => {
  const [options, setOptions] = useState<AgChartOptions>({
    dataSource: {
      getData: () =>
        new Promise(() => {
          // Never resolve so the loading spinner remains
        }),
    },
    overlays: {
      loading: {
        renderer: () => {
          const container = document.createElement("div");
          container.style.display = "flex";
          container.style.alignItems = "flex-end";
          container.style.justifyContent = "flex-start";
          container.style.flexDirection = "column";
          container.style.height = "100%";
          container.style.boxSizing = "border-box";
          container.style.userSelect = "none";
          container.style.animation = "loading 250ms linear 50ms both";
          const spinner = document.createElement("div");
          spinner.style.width = "20px";
          spinner.style.height = "20px";
          spinner.style.backgroundImage = [
            "linear-gradient(#333, #333)",
            "linear-gradient(#999, #999)",
            "linear-gradient(#ccc, #ccc)",
          ].join(", ");
          spinner.style.backgroundPosition = "0% 0%, 0% 100%, 100% 100%";
          spinner.style.backgroundSize = "50% 50%";
          spinner.style.backgroundRepeat = "no-repeat";
          spinner.style.animation = "loading-spinner 1s infinite";
          const animation = document.createElement("style");
          animation.innerText = [
            "@keyframes loading { from { opacity: 0 } to { opacity: 1 } }",
            "@keyframes loading-spinner {",
            "  0% { background-position: 0% 0%, 0% 100%, 100% 100%; }",
            "  25% { background-position: 100% 0%, 0% 0%, 0% 100%; }",
            "  50% { background-position: 100% 100%, 100% 0%, 0% 0%; }",
            "  75% { background-position: 0% 100%, 100% 100%, 100% 0%; }",
            "  100% { background-position: 0% 0%, 0% 100%, 100% 100%; }",
            "}",
          ].join(" ");
          container.replaceChildren(spinner, animation);
          return container;
        },
      },
    },
    series: [
      {
        type: "line",
        xKey: "year",
        yKey: "spending",
      },
    ],
    axes: {
      y: { type: "number", title: { text: "Year" } },
      x: { type: "number", title: { text: "Spending" } },
    },
  });

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

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

[Live example: Custom Overlay for Loading Data](https://www.ag-grid.com/charts/reactFunctionalTs/overlays/examples/loading-custom)

```js
{
    overlays: {
        loading: {
            renderer: () => {
                const container = document.createElement('div');
                // ... styles

                const spinner = document.createElement('div');
                // ... styles

                const animation = document.createElement('style');
                // ... keyframes

                container.append(spinner, animation);

                return container;
            },
        },
    },
}
```

## API Reference

#### Overlays

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| loading | AgChartOverlayOptions |  | An overlay to be displayed when there is no data. |
| loading.enabled | boolean | true | Enabled or disable use of the overlay. |
| loading.text | TextValue \| ContentSegment[] |  | Text to render in the overlay. Plain text, or an array of segments for rich content. |
| loading.renderer | Renderer |  | A function for generating HTML element or string for overlay content. |
| noData | AgChartOverlayOptions |  | An overlay to be displayed when there is no data. |
| noData.enabled | boolean | true | Enabled or disable use of the overlay. |
| noData.text | TextValue \| ContentSegment[] |  | Text to render in the overlay. Plain text, or an array of segments for rich content. |
| noData.renderer | Renderer |  | A function for generating HTML element or string for overlay content. |
| noVisibleSeries | AgChartOverlayOptions |  | An overlay to be displayed when there are no series visible. |
| noVisibleSeries.enabled | boolean | true | Enabled or disable use of the overlay. |
| noVisibleSeries.text | TextValue \| ContentSegment[] |  | Text to render in the overlay. Plain text, or an array of segments for rich content. |
| noVisibleSeries.renderer | Renderer |  | A function for generating HTML element or string for overlay content. |
| unsupportedBrowser | AgChartOverlayOptions |  | An overlay to be displayed when chart is running in an unsupported browser. |
| unsupportedBrowser.enabled | boolean | true | Enabled or disable use of the overlay. |
| unsupportedBrowser.text | TextValue \| ContentSegment[] |  | Text to render in the overlay. Plain text, or an array of segments for rich content. |
| unsupportedBrowser.renderer | Renderer |  | A function for generating HTML element or string for overlay content. |
