---
title: "Flash On Update"
enterprise: true
framework: react
version: "14.1.0"
---

# Flash On Update

Flash on Update signals that chart data has changed by briefly overlaying a flash animation, drawing the user's attention to the chart whenever data is updated, added or removed.

## Enabling Flash On Update

Flash on Update is disabled by default. To enable it, set `flashOnUpdate.enabled` to `true`.

#### Flash On Update

```tsx
import React, { useState, Fragment } from "react";
import { createRoot } from "react-dom/client";
import { AgCharts } from "ag-charts-react";
import {
  AgCartesianChartOptions,
  CandlestickSeriesModule,
  ContextMenuModule,
  CrosshairModule,
  FlashOnUpdateModule,
  LegendModule,
  ModuleRegistry,
  NumberAxisModule,
  OrdinalTimeAxisModule,
} from "ag-charts-enterprise";
import { applyLiveUpdate, getInitialData } from "./data";
import clone from "clone";

ModuleRegistry.registerModules([
  CandlestickSeriesModule,
  ContextMenuModule,
  CrosshairModule,
  FlashOnUpdateModule,
  LegendModule,
  NumberAxisModule,
  OrdinalTimeAxisModule,
]);

const ChartExample = () => {
  const [options, setOptions] = useState<AgCartesianChartOptions>({
    data: getInitialData(),
    title: {
      text: "AAPL Stock Price",
    },
    series: [
      {
        type: "candlestick",
        xKey: "date",
        xName: "Date",
        openKey: "open",
        highKey: "high",
        lowKey: "low",
        closeKey: "close",
      },
    ],
    axes: {
      y: {
        type: "number",
        label: {
          formatter: ({ value }) => `$${Number(value).toFixed(0)}`,
        },
      },
    },
    flashOnUpdate: {
      enabled: true,
    },
  });

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

    nextOptions.data = applyLiveUpdate(nextOptions.data!);

    setOptions(nextOptions);
  };

  return (
    <Fragment>
      <div className="example-controls">
        <div className="controls-row">
          <button onClick={update}>Update</button>
        </div>
      </div>
      <AgCharts options={options} />
    </Fragment>
  );
};

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

[Live example: Flash On Update](https://www.ag-grid.com/charts/reactFunctionalTs/flash-on-update/examples/flash-on-update)

```js
{
    flashOnUpdate: {
        enabled: true,
    },
}
```

## Category Flash

Flashing just the category band makes it easier to identify which categories have changed. Set `item` to `'category'` to enable this.

#### Category Flash

```tsx
import React, { useState, Fragment } from "react";
import { createRoot } from "react-dom/client";
import { AgCharts } from "ag-charts-react";
import {
  BarSeriesModule,
  CategoryAxisModule,
  LegendModule,
  ModuleRegistry,
  NumberAxisModule,
} from "ag-charts-community";
import {
  AgCartesianChartOptions,
  ContextMenuModule,
  CrosshairModule,
  FlashOnUpdateModule,
} from "ag-charts-enterprise";
import { DataType, applyRandomUpdate, getInitialData } from "./data";
import clone from "clone";

let data: DataType[] = getInitialData();
let isRunning = false;
let updateInterval: ReturnType<typeof setInterval> | undefined;
ModuleRegistry.registerModules([
  BarSeriesModule,
  CategoryAxisModule,
  ContextMenuModule,
  CrosshairModule,
  FlashOnUpdateModule,
  LegendModule,
  NumberAxisModule,
]);

const ChartExample = () => {
  const [options, setOptions] = useState<AgCartesianChartOptions<DataType>>({
    data,
    title: {
      text: "Stock Trading Volume",
    },
    series: [
      {
        type: "bar",
        xKey: "ticker",
        yKey: "buyVolume",
        yName: "Buy Volume (M)",
        stacked: true,
      },
      {
        type: "bar",
        xKey: "ticker",
        yKey: "sellVolume",
        yName: "Sell Volume (M)",
        stacked: true,
      },
    ],
    axes: {
      x: {
        type: "category",
        label: {
          autoRotate: false,
        },
      },
    },
    flashOnUpdate: {
      enabled: true,
      item: "category",
    },
  });

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

    data = applyRandomUpdate(data);
    nextOptions.data = data;

    setOptions(nextOptions);
  };

  const startUpdates = () => {
    if (isRunning) return;
    isRunning = true;
    updateButton();
    update();
    updateInterval = setInterval(update, 2000);
  };

  const stopUpdates = () => {
    if (!isRunning) return;
    isRunning = false;
    updateButton();
    if (updateInterval) {
      clearInterval(updateInterval);
      updateInterval = undefined;
    }
  };

  const updateButton = () => {
    const button = document.getElementById("toggleBtn");
    if (button) {
      button.textContent = isRunning ? "Stop Updates" : "Start Updates";
    }
  };

  const toggleUpdates = () => {
    if (isRunning) {
      stopUpdates();
    } else {
      startUpdates();
    }
  };

  return (
    <Fragment>
      <div className="example-controls">
        <div className="controls-row">
          <button id="toggleBtn" onClick={toggleUpdates}>
            Start Updates
          </button>
        </div>
      </div>
      <AgCharts options={options} />
    </Fragment>
  );
};

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

[Live example: Category Flash](https://www.ag-grid.com/charts/reactFunctionalTs/flash-on-update/examples/flash-on-update-category)

```js
{
    flashOnUpdate: {
        enabled: true,
        item: 'category',
    },
}
```

In this example:

- Click 'Start Updates' to begin a simulated data feed that updates 1–3 bars every 2 seconds.
- Only the changed bars flash.
- Click **Stop Updates** to pause the feed.
- Category Flash is only available on [Category](https://www.ag-grid.com/charts/react/axes-types/#category), [Grouped Category](https://www.ag-grid.com/charts/react/axes-types/#grouped-category), [Unit Time](https://www.ag-grid.com/charts/react/axes-time/#unit-time) and [Ordinal Time](https://www.ag-grid.com/charts/react/axes-time/#ordinal-time) axes.

### Adding and Removing Data

Category flash is also triggered when a category is added to the chart. Removing a category does not trigger a flash.

#### Adding and Removing Data

```tsx
import React, { useState, Fragment } from "react";
import { createRoot } from "react-dom/client";
import { AgCharts } from "ag-charts-react";
import {
  BarSeriesModule,
  CategoryAxisModule,
  LegendModule,
  ModuleRegistry,
  NumberAxisModule,
} from "ag-charts-community";
import {
  AgCartesianChartOptions,
  ContextMenuModule,
  CrosshairModule,
  FlashOnUpdateModule,
} from "ag-charts-enterprise";
import { DataType, applyUpdate, getInitialData, getNextSector } from "./data";
import clone from "clone";

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

const ChartExample = () => {
  const [options, setOptions] = useState<AgCartesianChartOptions<DataType>>({
    data: getInitialData(),
    title: {
      text: "Sector Trading Activity",
    },
    series: [
      {
        type: "bar",
        xKey: "sector",
        yKey: "institutional",
        yName: "Institutional ($M)",
        stacked: true,
      },
      {
        type: "bar",
        xKey: "sector",
        yKey: "retail",
        yName: "Retail ($M)",
        stacked: true,
      },
      {
        type: "bar",
        xKey: "sector",
        yKey: "etfFlows",
        yName: "ETF Flows ($M)",
        stacked: true,
      },
    ],
    axes: {
      x: {
        type: "category",
      },
    },
    flashOnUpdate: {
      enabled: true,
      item: "category",
    },
  });

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

    const next = getNextSector(nextOptions.data!);
    if (!next) return;
    nextOptions.data = [...nextOptions.data!, { ...next }];

    setOptions(nextOptions);
  };

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

    if (nextOptions.data!.length <= 2) return;
    nextOptions.data = nextOptions.data!.slice(0, -1);

    setOptions(nextOptions);
  };

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

    nextOptions.data = applyUpdate(nextOptions.data!);

    setOptions(nextOptions);
  };

  return (
    <Fragment>
      <div className="example-controls">
        <div className="controls-row">
          <button onClick={addSector}>Add Sector</button>
          <button onClick={removeSector}>Remove Sector</button>
          <button onClick={updateSectors}>Update</button>
        </div>
      </div>
      <AgCharts options={options} />
    </Fragment>
  );
};

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

[Live example: Adding and Removing Data](https://www.ag-grid.com/charts/reactFunctionalTs/flash-on-update/examples/flash-on-update-add-remove)

In this example:

- Click 'Add Sector' to add a new sector to the chart — the new category flashes on arrival.
- Click 'Remove Sector' to remove the last sector — no flash occurs on removal.
- Click 'Update' to update values for one or two sectors and observe the category flash.

## Customisation

The appearance and timing of the flash effect can be customised.

#### Customisation

```tsx
import React, { useState, Fragment } from "react";
import { createRoot } from "react-dom/client";
import { AgCharts } from "ag-charts-react";
import {
  AgCartesianChartOptions,
  ContextMenuModule,
  CrosshairModule,
  FlashOnUpdateModule,
  LegendModule,
  ModuleRegistry,
  NumberAxisModule,
  OhlcSeriesModule,
  OrdinalTimeAxisModule,
} from "ag-charts-enterprise";
import { applyLiveUpdate, getInitialData } from "./data";
import clone from "clone";

let data = getInitialData();
let isRunning = false;
let updateInterval: ReturnType<typeof setInterval> | undefined;
ModuleRegistry.registerModules([
  ContextMenuModule,
  CrosshairModule,
  FlashOnUpdateModule,
  LegendModule,
  NumberAxisModule,
  OhlcSeriesModule,
  OrdinalTimeAxisModule,
]);

const ChartExample = () => {
  const [options, setOptions] = useState<AgCartesianChartOptions>({
    data,
    title: {
      text: "MSFT Stock Price",
    },
    series: [
      {
        type: "ohlc",
        xKey: "date",
        xName: "Date",
        openKey: "open",
        highKey: "high",
        lowKey: "low",
        closeKey: "close",
      },
    ],
    axes: {
      y: {
        type: "number",
        label: {
          formatter: ({ value }) => `$${Number(value).toFixed(0)}`,
        },
      },
    },
    flashOnUpdate: {
      enabled: true,
      fill: "#ffd6a5",
      flashDuration: 300,
      fadeOutDuration: 700,
    },
  });

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

    data = applyLiveUpdate(data);
    nextOptions.data = data;

    setOptions(nextOptions);
  };

  const startUpdates = () => {
    if (isRunning) return;
    isRunning = true;
    updateButton();
    update();
    updateInterval = setInterval(update, 2000);
  };

  const stopUpdates = () => {
    if (!isRunning) return;
    isRunning = false;
    updateButton();
    if (updateInterval) {
      clearInterval(updateInterval);
      updateInterval = undefined;
    }
  };

  const updateButton = () => {
    const button = document.getElementById("toggleBtn");
    if (button) {
      button.textContent = isRunning ? "Stop Updates" : "Start Updates";
    }
  };

  const toggleUpdates = () => {
    if (isRunning) {
      stopUpdates();
    } else {
      startUpdates();
    }
  };

  const setColor = (value: string) => {
    const nextOptions = clone(options);

    nextOptions.flashOnUpdate!.fill = value;

    setOptions(nextOptions);
  };

  const setFlashDuration = (value: string) => {
    const nextOptions = clone(options);

    nextOptions.flashOnUpdate!.flashDuration = Number(value);

    setOptions(nextOptions);
  };

  const setFadeDuration = (value: string) => {
    const nextOptions = clone(options);

    nextOptions.flashOnUpdate!.fadeOutDuration = Number(value);

    setOptions(nextOptions);
  };

  return (
    <Fragment>
      <div className="example-controls">
        <div className="controls-row">
          <button id="toggleBtn" onClick={toggleUpdates}>
            Start Updates
          </button>
          <label>Fill:</label>
          <select onChange={(event) => setColor(event.target.value)}>
            <option value="#cfeeff">Default (#cfeeff)</option>
            <option value="#ffd6a5">Warm (#ffd6a5)</option>
            <option value="#ffadad">Red (#ffadad)</option>
          </select>
          <label>Flash:</label>
          <select onChange={(event) => setFlashDuration(event.target.value)}>
            <option value="0">0ms</option>
            <option value="100">100ms</option>
            <option value="300">300ms</option>
            <option value="500">500ms</option>
          </select>
          <label>Fade:</label>
          <select onChange={(event) => setFadeDuration(event.target.value)}>
            <option value="200">200ms</option>
            <option value="500">500ms</option>
            <option value="700">700ms</option>
            <option value="1500">1500ms</option>
          </select>
        </div>
      </div>
      <AgCharts options={options} />
    </Fragment>
  );
};

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

[Live example: Customisation](https://www.ag-grid.com/charts/reactFunctionalTs/flash-on-update/examples/flash-on-update-customisation)

```js
{
    flashOnUpdate: {
        enabled: true,
        fill: '#ffd6a5',
        flashDuration: 300,
        fadeOutDuration: 700,
    },
}
```

In this example:

- Use the 'Fill', 'Flash' and 'Fade' controls to adjust the flash appearance.
  - `fill` — the fill colour of the flash overlay.
  - `flashDuration` — how long (in milliseconds) the flash remains at full opacity before fading.
  - `fadeOutDuration` — how long (in milliseconds) the fade-out takes.
- Click 'Start Updates' to begin a simulated live price feed and observe the flash with the current settings.
- Click 'Stop Updates' to pause the feed.

## Animation

Flash on Update disables [Animation](https://www.ag-grid.com/charts/react/animation/) by default, as the two are rarely used together. If you do need both, explicitly set `animation: { enabled: true }`.

When both are enabled, the `flashDuration` and `fadeOutDuration` values are scaled to fit within the data update animation phases, so the actual timing may differ from the configured values. Their ratio still controls how the duration is split between the hold and fade stages.

## API Reference

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| enabled | boolean |  | Whether the flash effect is enabled. |
| item | 'chart' \| 'category' |  | What part of the chart to flash. |
| fill | CssColor |  | The fill colour of the flash effect. |
| fillOpacity | Opacity |  | The fill opacity of the flash effect. |
| flashDuration | DurationMs |  | The flash hold duration in milliseconds before fading begins. Actual timing may vary when animations are enabled. |
| fadeOutDuration | DurationMs |  | The fade-out duration in milliseconds. Actual timing may vary when animations are enabled. |
