Chart Annotations in React Chart
27 Aug 202624 minutes to read
Chart annotations let you highlight specific areas of the chart by overlaying text, shapes, images, or custom HTML elements directly inside the chart area. Use annotations to emphasize trends, mark thresholds, call out key data points, or display additional context such as watermarks and footers.
Note: To use the annotation feature, inject the
ChartAnnotationmodule into the chartservices.
Getting started
Annotations are added through the annotations option, which accepts an array of AnnotationDirective items wrapped in AnnotationsDirective. Use the content property to specify what is rendered—either a string (rendered as text) or a function/element (rendered as custom HTML).
In addition to content, the following properties control placement:
| Property | Type | Default | Description |
|---|---|---|---|
x |
string | number
|
0 |
Horizontal position. A string matches a category value; a number is interpreted in pixels (default) or data values (when coordinateUnits is Point). |
y |
number |
0 |
Vertical position. Interpreted in pixels or data values based on coordinateUnits. |
region |
'Chart' | 'Series'
|
'Chart' |
Reference space for the x and y values. |
coordinateUnits |
'Pixel' | 'Point'
|
'Pixel' |
Unit used to interpret x and y. |
The following example adds a simple text annotation over a column series.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { ChartComponent, SeriesCollectionDirective, SeriesDirective, Inject, ChartAnnotation, AnnotationsDirective, AnnotationDirective, Legend, Category, Tooltip, DataLabel, ColumnSeries } from '@syncfusion/ej2-react-charts';
import { columnData } from './datasource';
function App() {
const primaryxAxis = { valueType: 'Category', title: 'Countries' };
const primaryyAxis = { minimum: 0, maximum: 80, interval: 20, title: 'Medals' };
const border = { width: 2, color: 'grey' };
const animation = { enable: true, duration: 1200, delay: 100 };
return <ChartComponent id='charts' primaryXAxis={primaryxAxis} primaryYAxis={primaryyAxis} title='Olympic Medals'>
<Inject services={[ColumnSeries, Legend, Tooltip, DataLabel, Category, ChartAnnotation]}/>
<AnnotationsDirective>
<AnnotationDirective content='70 Gold Medals' region='Series' coordinateUnits='Point' x='Japan' y={75}>
</AnnotationDirective>
</AnnotationsDirective>
<SeriesCollectionDirective>
<SeriesDirective dataSource={columnData} xName='country' yName='gold' name='Gold' border={border} animation={animation} type='Column'>
</SeriesDirective>
</SeriesCollectionDirective>
</ChartComponent>;
}
;
export default App;
ReactDOM.render(<App />, document.getElementById("charts"));import * as React from "react";
import * as ReactDOM from "react-dom";
import { AxisModel, ChartComponent, SeriesCollectionDirective, SeriesDirective, Inject, ChartAnnotation, AnnotationsDirective, AnnotationDirective, Legend, Category, Tooltip, DataLabel, ColumnSeries}from'@syncfusion/ej2-react-charts';
import { columnData } from './datasource';
function App() {
const primaryxAxis: AxisModel = { valueType: 'Category', title: 'Countries' };
const primaryyAxis: AxisModel = { minimum: 0, maximum: 80, interval: 20, title: 'Medals' };
const border = { width: 2, color: 'grey' };
const animation = { enable: true, duration: 1200, delay: 100 };
return <ChartComponent id='charts'
primaryXAxis={primaryxAxis}
primaryYAxis={primaryyAxis}
title='Olympic Medals'>
<Inject services={[ColumnSeries, Legend, Tooltip, DataLabel, Category, ChartAnnotation]} />
<AnnotationsDirective>
<AnnotationDirective content='70 Gold Medals' region='Series' coordinateUnits='Point' x='Japan' y={75}>
</AnnotationDirective>
</AnnotationsDirective>
<SeriesCollectionDirective>
<SeriesDirective dataSource={columnData} xName='country' yName='gold' name='Gold'
border={border}
animation={animation} type='Column'>
</SeriesDirective>
</SeriesCollectionDirective>
</ChartComponent>
};
export default App;
ReactDOM.render(<App />, document.getElementById("charts"));export let columnData = [
{ country: "USA", gold: 50 },
{ country: "China", gold: 40 },
{ country: "Japan", gold: 70 },
{ country: "Australia", gold: 60 },
{ country: "France", gold: 50 },
{ country: "Germany", gold: 40 },
{ country: "Italy", gold: 40 },
{ country: "Sweden", gold: 30 }
];export let columnData: Object[] = [
{ country: "USA", gold: 50 },
{ country: "China", gold: 40 },
{ country: "Japan", gold: 70 },
{ country: "Australia", gold: 60 },
{ country: "France", gold: 50 },
{ country: "Germany", gold: 40 },
{ country: "Italy", gold: 40 },
{ country: "Sweden", gold: 30 }
];Region
Use the region property to choose the reference space for the annotation’s x and y values:
-
Chart(default) –xandyare positioned relative to the overall chart area. The annotation stays fixed as the data changes. -
Series–xandyare positioned relative to a specific series. WhencoordinateUnitsisPoint,xis matched to a data point on the series.
The following example uses region: 'Series' with coordinateUnits: 'Point' to anchor the annotation to the Japan data point of the column series.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { ChartComponent, SeriesCollectionDirective, SeriesDirective, Inject, ChartAnnotation, AnnotationsDirective, AnnotationDirective, Legend, Category, Tooltip, DataLabel, ColumnSeries } from '@syncfusion/ej2-react-charts';
import { columnData } from './datasource';
function App() {
const primaryxAxis = { valueType: 'Category', title: 'Countries' };
const primaryyAxis = { minimum: 0, maximum: 80, interval: 20, title: 'Medals' };
const border = { width: 2, color: 'grey' };
const animation = { enable: true, duration: 1200, delay: 100 };
const template = chartTemplate;
function chartTemplate() {
return (<div className='template'>
<div>Highest Medal Count</div>
</div>);
}
return <ChartComponent id='charts' primaryXAxis={primaryxAxis} primaryYAxis={primaryyAxis} title='Olympic Medals'>
<Inject services={[ColumnSeries, Legend, Tooltip, DataLabel, Category, ChartAnnotation]}/>
<AnnotationsDirective>
<AnnotationDirective content={template} region='Series' coordinateUnits='Point' x='Japan' y={75}>
</AnnotationDirective>
</AnnotationsDirective>
<SeriesCollectionDirective>
<SeriesDirective dataSource={columnData} xName='country' yName='gold' name='Gold' border={border} animation={animation} type='Column'>
</SeriesDirective>
</SeriesCollectionDirective>
</ChartComponent>;
}
;
export default App;
ReactDOM.render(<App />, document.getElementById("charts"));import * as React from "react";
import * as ReactDOM from "react-dom";
import { AxisModel, ChartComponent, SeriesCollectionDirective, SeriesDirective, Inject, ChartAnnotation, AnnotationsDirective, AnnotationDirective, Legend, Category, Tooltip, DataLabel, ColumnSeries} from'@syncfusion/ej2-react-charts';
import { columnData } from './datasource';
function App() {
const primaryxAxis: AxisModel = { valueType: 'Category', title: 'Countries' };
const primaryyAxis: AxisModel = { minimum: 0, maximum: 80, interval: 20, title: 'Medals' };
const border = { width: 2, color: 'grey' };
const animation = { enable: true, duration: 1200, delay: 100 };
const template: any = chartTemplate;
function chartTemplate(): any {
return (<div className='template'>
<div>Highest Medal Count</div>
</div>);
}
return <ChartComponent id='charts'
primaryXAxis={primaryxAxis}
primaryYAxis={primaryyAxis}
title='Olympic Medals'>
<Inject services={[ColumnSeries, Legend, Tooltip, DataLabel, Category, ChartAnnotation]} />
<AnnotationsDirective>
<AnnotationDirective content={template} region='Series' coordinateUnits='Point' x='Japan' y={75}>
</AnnotationDirective>
</AnnotationsDirective>
<SeriesCollectionDirective>
<SeriesDirective dataSource={columnData} xName='country' yName='gold' name='Gold'
border={border}
animation={animation} type='Column'>
</SeriesDirective>
</SeriesCollectionDirective>
</ChartComponent>
};
export default App;
ReactDOM.render(<App />, document.getElementById("charts"));export let columnData = [
{ country: "USA", gold: 50 },
{ country: "China", gold: 40 },
{ country: "Japan", gold: 70 },
{ country: "Australia", gold: 60 },
{ country: "France", gold: 50 },
{ country: "Germany", gold: 40 },
{ country: "Italy", gold: 40 },
{ country: "Sweden", gold: 30 }
];export let columnData: Object[] = [
{ country: "USA", gold: 50 },
{ country: "China", gold: 40 },
{ country: "Japan", gold: 70 },
{ country: "Australia", gold: 60 },
{ country: "France", gold: 50 },
{ country: "Germany", gold: 40 },
{ country: "Italy", gold: 40 },
{ country: "Sweden", gold: 30 }
];Coordinate Units
Use the coordinateUnits property to choose how the annotation’s x and y values are interpreted:
-
Pixel(default) –xandyare treated as fixed pixel offsets from the top-left corner of the chart area. The annotation does not move with the data. -
Point–xandyare treated as data values on the chart axes.xmatches an axis value (a category name for category axes, a numeric value for numeric/datetime axes) andymatches a series value. The annotation moves with the data.
The following example renders a custom HTML annotation at a fixed pixel location on the chart.
import * as React from "react";
import * as ReactDOM from "react-dom";
import { ChartComponent, SeriesCollectionDirective, SeriesDirective, Inject, ChartAnnotation, AnnotationsDirective, AnnotationDirective, Legend, Category, Tooltip, DataLabel, ColumnSeries } from '@syncfusion/ej2-react-charts';
import { columnData } from './datasource';
function App() {
const primaryxAxis = { valueType: 'Category', title: 'Countries' };
const primaryyAxis = { minimum: 0, maximum: 80, interval: 20, title: 'Medals' };
const border = { width: 2, color: 'grey' };
const animation = { enable: true, duration: 1200, delay: 100 };
const template = chartTemplate;
function chartTemplate() {
return (<div className='charttemplate'>
<div> Annotation In Pixel </div>
</div>);
}
return <ChartComponent id='charts' primaryXAxis={primaryxAxis} primaryYAxis={primaryyAxis} title='Olympic Medals'>
<Inject services={[ColumnSeries, Legend, Tooltip, DataLabel, Category, ChartAnnotation]}/>
<AnnotationsDirective>
<AnnotationDirective content={template} coordinateUnits='Pixel' x={150} y={50}>
</AnnotationDirective>
</AnnotationsDirective>
<SeriesCollectionDirective>
<SeriesDirective dataSource={columnData} xName='country' yName='gold' name='Gold' border={border} animation={animation} type='Column'>
</SeriesDirective>
</SeriesCollectionDirective>
</ChartComponent>;
}
;
export default App;
ReactDOM.render(<App />, document.getElementById("charts"));import * as React from "react";
import * as ReactDOM from "react-dom";
import { AxisModel,ChartComponent, SeriesCollectionDirective, SeriesDirective, Inject, ChartAnnotation, AnnotationsDirective, AnnotationDirective, Legend, Category, Tooltip, DataLabel, ColumnSeries}from'@syncfusion/ej2-react-charts';
import { columnData } from './datasource';
function App() {
const primaryxAxis: AxisModel = { valueType: 'Category', title: 'Countries' };
const primaryyAxis: AxisModel = { minimum: 0, maximum: 80, interval: 20, title: 'Medals' };
const border = { width: 2, color: 'grey' };
const animation = { enable: true, duration: 1200, delay: 100 };
const template: any = chartTemplate;
function chartTemplate(): any {
return (<div className='charttemplate'>
<div> Annotation In Pixel </div>
</div>);
}
return <ChartComponent id='charts'
primaryXAxis={primaryxAxis}
primaryYAxis={primaryyAxis}
title='Olympic Medals'>
<Inject services={[ColumnSeries, Legend, Tooltip, DataLabel, Category, ChartAnnotation]} />
<AnnotationsDirective>
<AnnotationDirective content={template}
coordinateUnits='Pixel' x={150} y={50}>
</AnnotationDirective>
</AnnotationsDirective>
<SeriesCollectionDirective>
<SeriesDirective dataSource={columnData} xName='country' yName='gold' name='Gold'
border={border}
animation={animation} type='Column'>
</SeriesDirective>
</SeriesCollectionDirective>
</ChartComponent>
};
export default App;
ReactDOM.render(<App />, document.getElementById("charts"));export let columnData = [
{ country: "USA", gold: 50 },
{ country: "China", gold: 40 },
{ country: "Japan", gold: 70 },
{ country: "Australia", gold: 60 },
{ country: "France", gold: 50 },
{ country: "Germany", gold: 40 },
{ country: "Italy", gold: 40 },
{ country: "Sweden", gold: 30 }
];export let columnData: Object[] = [
{ country: "USA", gold: 50 },
{ country: "China", gold: 40 },
{ country: "Japan", gold: 70 },
{ country: "Australia", gold: 60 },
{ country: "France", gold: 50 },
{ country: "Germany", gold: 40 },
{ country: "Italy", gold: 40 },
{ country: "Sweden", gold: 30 }
];Customization
The ChartAnnotationSettingsModel exposes additional properties to align and style annotations. The commonly used ones are:
-
horizontalAlignment–'Near','Center', or'Far'. Aligns the annotation horizontally relative to its anchor point. -
verticalAlignment–'Top','Middle', or'Bottom'. Aligns the annotation vertically relative to its anchor point. -
offset–{ x: number, y: number }. Shifts the annotation from its anchor point in pixels. -
opacity–numberbetween0and1. Sets the opacity of the annotation.
The following snippet customizes an annotation with alignment, offset, and opacity:
<AnnotationDirective
content='Target'
coordinateUnits='Point'
x='Japan'
y={75}
horizontalAlignment='Center'
verticalAlignment='Middle'
offset={{ x: 0, y: -10 }}
opacity={0.85}>
</AnnotationDirective>
See the ChartAnnotationSettingsModel API reference for the full list of properties.
Multiple annotations
Add multiple annotations to the same chart by including more than one AnnotationDirective inside AnnotationsDirective. Each annotation can use its own x, y, region, content, and styling.
<AnnotationsDirective>
<AnnotationDirective
content='70 Gold Medals'
region='Series'
coordinateUnits='Point'
x='Japan'
y={75}>
</AnnotationDirective>
<AnnotationDirective
content='Watermark'
region='Chart'
coordinateUnits='Pixel'
x={20}
y={20}
opacity={0.4}>
</AnnotationDirective>
</AnnotationsDirective>