Chart annotations in Vue Chart component

13 Jun 202424 minutes to read

Annotations are used to mark the specific area of interest in the chart area with texts, shapes or images.

You can add annotations to the chart by using the annotations option. By using the content option of annotation object, you can specify
the id of the element that needs to be displayed in the chart area.

<template>
  <div id="app">
    <ejs-chart id="container" :title='title' :primaryXAxis='primaryXAxis' :primaryYAxis='primaryYAxis'
      :annotations='annotations'>
      <e-series-collection>
        <e-series :dataSource='seriesData' type='Column' xName='country' yName='gold' name='Gold'> </e-series>
      </e-series-collection>
    </ejs-chart>
  </div>
</template>
<script setup>
import { provide } from "vue";
import { ChartComponent as EjsChart, SeriesCollectionDirective as ESeriesCollection, SeriesDirective as ESeries, ColumnSeries, Category, ChartAnnotation } from "@syncfusion/ej2-vue-charts";



const seriesData = [
  { 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 }
];
const annotations = [{
  content: '70 Gold Medals',
  coordinateUnits: 'Point',
  x: 'France',
  y: 50
}];
const primaryXAxis = {
  valueType: 'Category',
  title: 'Countries'
};
const primaryYAxis =
{
  minimum: 0, maximum: 80,
  interval: 20, title: 'Medals'
};
const title = "Olympic Medals";

provide('chart', [ColumnSeries, Category, ChartAnnotation]);

</script>
<style>
#container {
  height: 350px;
}
</style>
<template>
  <div id="app">
    <ejs-chart id="container" :title='title' :primaryXAxis='primaryXAxis' :primaryYAxis='primaryYAxis'
      :annotations='annotations'>
      <e-series-collection>
        <e-series :dataSource='seriesData' type='Column' xName='country' yName='gold' name='Gold'> </e-series>
      </e-series-collection>
    </ejs-chart>
  </div>
</template>
<script>

import { ChartComponent, SeriesCollectionDirective, SeriesDirective, ColumnSeries, Category, ChartAnnotation } from "@syncfusion/ej2-vue-charts";



export default {
  name: "App",
  components: {
    'ejs-chart': ChartComponent,
    'e-series-collection': SeriesCollectionDirective,
    'e-series': SeriesDirective
  },
  data() {
    return {
      seriesData: [
        { 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 }
      ],
      annotations: [{
        content: '70 Gold Medals',
        coordinateUnits: 'Point',
        x: 'France',
        y: 50
      }],
      primaryXAxis: {
        valueType: 'Category',
        title: 'Countries'
      },
      primaryYAxis:
      {
        minimum: 0, maximum: 80,
        interval: 20, title: 'Medals'
      },
      title: "Olympic Medals"
    };
  },
  provide: {
    chart: [ColumnSeries, Category, ChartAnnotation]
  },
};
</script>
<style>
#container {
  height: 350px;
}
</style>

Note: To use annotation feature in chart, we need to inject ChartAnnotation into the provide.

Region

Annotations can be placed either with respect to Series or Chart. by default, it will placed with respect
to Chart.

<template>
  <div id="app">
    <ejs-chart id="container" :title='title' :primaryXAxis='primaryXAxis' :primaryYAxis='primaryYAxis'
      :annotations='annotations'>
      <e-series-collection>
        <e-series :dataSource='seriesData' type='Column' xName='country' yName='gold' name='Gold'> </e-series>
      </e-series-collection>
    </ejs-chart>
  </div>
</template>
<script setup>
import { provide, createApp } from "vue";
import { ChartComponent as EjsChart, SeriesCollectionDirective as ESeriesCollection, SeriesDirective as ESeries, ColumnSeries, Category, ChartAnnotation } from "@syncfusion/ej2-vue-charts";

const app = createApp();
let contentVue = app.component("contentTemplate", {
  template: '<div>Highest Medal Count</div>',
  data() {
    return {
      data: {}
    };
  }
});
let contentTemplate = function () {
  return { template: contentVue };
};


const seriesData = [
  { 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 }
];
const annotations = [{
  content: contentTemplate,
  region: 'Series',
  coordinateUnits: 'Point',
  x: 'France',
  y: 50
}];
const primaryXAxis = {
  valueType: 'Category',
  title: 'Countries'
};
const primaryYAxis =
{
  minimum: 0, maximum: 80,
  interval: 20, title: 'Medals'
};
const title = "Olympic Medals";

provide('chart', [ColumnSeries, Category, ChartAnnotation]);

</script>
<style>
#container {
  height: 350px;
}
</style>
<template>
  <div id="app">
    <ejs-chart id="container" :title='title' :primaryXAxis='primaryXAxis' :primaryYAxis='primaryYAxis'
      :annotations='annotations'>
      <e-series-collection>
        <e-series :dataSource='seriesData' type='Column' xName='country' yName='gold' name='Gold'> </e-series>
      </e-series-collection>
    </ejs-chart>
  </div>
</template>
<script>

import { ChartComponent, SeriesCollectionDirective, SeriesDirective, ColumnSeries, Category, ChartAnnotation } from "@syncfusion/ej2-vue-charts";
import { createApp } from "vue";

const app = createApp();
let contentVue = app.component("contentTemplate", {
  template: '<div>Highest Medal Count</div>',
  data() {
    return {
      data: {}
    };
  }
});
let contentTemplate = function () {
  return { template: contentVue };
};


export default {
  name: "App",
  components: {
    'ejs-chart': ChartComponent,
    'e-series-collection': SeriesCollectionDirective,
    'e-series': SeriesDirective
  },
  data() {
    return {
      seriesData: [
        { 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 }
      ],
      annotations: [{
        content: contentTemplate,
        region: 'Series',
        coordinateUnits: 'Point',
        x: 'France',
        y: 50
      }],
      primaryXAxis: {
        valueType: 'Category',
        title: 'Countries'
      },
      primaryYAxis:
      {
        minimum: 0, maximum: 80,
        interval: 20, title: 'Medals'
      },
      title: "Olympic Medals"
    };
  },
  provide: {
    chart: [ColumnSeries, Category, ChartAnnotation]
  },
};
</script>
<style>
#container {
  height: 350px;
}
</style>

Co-ordinate Units

Specified the coordinates units of the annotation either Pixel or Point.

<template>
  <div id="app">
    <ejs-chart id="container" :title='title' :primaryXAxis='primaryXAxis' :primaryYAxis='primaryYAxis'
      :annotations='annotations'>
      <e-series-collection>
        <e-series :dataSource='seriesData' type='Column' xName='country' yName='gold' name='Gold'> </e-series>
      </e-series-collection>
    </ejs-chart>
  </div>
</template>
<script setup>
import { provide, createApp } from "vue";
import { ChartComponent as EjsChart, SeriesCollectionDirective as ESeriesCollection, SeriesDirective as ESeries, ColumnSeries, Category, ChartAnnotation } from "@syncfusion/ej2-vue-charts";

const app = createApp()
let contentVue = app.component("contentTemplate", {
  template: '<div style="border: 1px solid black; padding: 5px 5px 5px 5px, backgrund:#f5f5f5">Annotation in Pixel</div>',
  data() {
    return {
      data: {}
    };
  }
});
let contentTemplate = function () {
  return { template: contentVue };
};


const seriesData = [
  { 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 }
];
const annotations = [{
  content: contentTemplate,
  coordinateUnits: 'Pixel',
  x: 150,
  y: 50
}];
const primaryXAxis = {
  valueType: 'Category',
  title: 'Countries'
};
const primaryYAxis =
{
  minimum: 0, maximum: 80,
  interval: 20, title: 'Medals'
};
const title = "Olympic Medals";

provide('chart', [ColumnSeries, Category, ChartAnnotation]);

</script>
<style>
#container {
  height: 350px;
}
</style>
<template>
  <div id="app">
    <ejs-chart id="container" :title='title' :primaryXAxis='primaryXAxis' :primaryYAxis='primaryYAxis'
      :annotations='annotations'>
      <e-series-collection>
        <e-series :dataSource='seriesData' type='Column' xName='country' yName='gold' name='Gold'> </e-series>
      </e-series-collection>
    </ejs-chart>
  </div>
</template>
<script>

import { ChartComponent, SeriesCollectionDirective, SeriesDirective, ColumnSeries, Category, ChartAnnotation } from "@syncfusion/ej2-vue-charts";
import { createApp } from 'vue';

const app = createApp();
let contentVue = app.component("contentTemplate", {
  template: '<div style="border: 1px solid black; padding: 5px 5px 5px 5px, backgrund:#f5f5f5">Annotation in Pixel</div>',
  data() {
    return {
      data: {}
    };
  }
});
let contentTemplate = function () {
  return { template: contentVue };
};


export default {
  name: "App",
  components: {
    'ejs-chart': ChartComponent,
    'e-series-collection': SeriesCollectionDirective,
    'e-series': SeriesDirective
  },
  data() {
    return {
      seriesData: [
        { 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 }
      ],
      annotations: [{
        content: contentTemplate,
        coordinateUnits: 'Pixel',
        x: 150,
        y: 50
      }],
      primaryXAxis: {
        valueType: 'Category',
        title: 'Countries'
      },
      primaryYAxis:
      {
        minimum: 0, maximum: 80,
        interval: 20, title: 'Medals'
      },
      title: "Olympic Medals"
    };
  },
  provide: {
    chart: [ColumnSeries, Category, ChartAnnotation]
  },
};
</script>
<style>
#container {
  height: 350px;
}
</style>

Alignment

Annotation provides verticalAlignment and horizontalAlignment. The verticalAlignment can be customized
via Top, Bottom or Middle and the horizontalAlignment can be customized via Near, Far or Center.

<template>
  <div id="app">
    <ejs-chart id="container" :title='title' :primaryXAxis='primaryXAxis' :primaryYAxis='primaryYAxis'
      :annotations='annotations'>
      <e-series-collection>
        <e-series :dataSource='seriesData' type='Column' xName='country' yName='gold' name='Gold'> </e-series>
      </e-series-collection>
    </ejs-chart>
  </div>
</template>
<script setup>
import { provide, createApp } from "vue";
import { ChartComponent as EjsChart, SeriesCollectionDirective as ESeriesCollection, SeriesDirective as ESeries, ColumnSeries, Category, ChartAnnotation } from "@syncfusion/ej2-vue-charts";


const app = createApp();
let contentVue = app.component("contentTemplate", {
  template: '<div style="border: 1px solid black; padidng: 5px 5px 5px 5px, backgrund:#f5f5f5">Highest Medal Count</div>',
  data() {
    return {
      data: {}
    };
  }
});
let contentTemplate = function () {
  return { template: contentVue };
};



const seriesData = [
  { 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 }
];
const annotations = [{
  content: contentTemplate,
  x: 'France',
  y: 50,
  verticalAlignment: 'Top',
  horizontalAlignment: 'Near'
}];
const primaryXAxis = {
  valueType: 'Category',
  title: 'Countries'
};
const primaryYAxis =
{
  minimum: 0, maximum: 80,
  interval: 20, title: 'Medals'
};
const title = "Olympic Medals";

provide('chart', [ColumnSeries, Category, ChartAnnotation]);

</script>
<style>
#container {
  height: 350px;
}
</style>
<template>
  <div id="app">
    <ejs-chart id="container" :title='title' :primaryXAxis='primaryXAxis' :primaryYAxis='primaryYAxis'
      :annotations='annotations'>
      <e-series-collection>
        <e-series :dataSource='seriesData' type='Column' xName='country' yName='gold' name='Gold'> </e-series>
      </e-series-collection>
    </ejs-chart>
  </div>
</template>
<script>

import { ChartComponent, SeriesCollectionDirective, SeriesDirective, ColumnSeries, Category, ChartAnnotation } from "@syncfusion/ej2-vue-charts";
import { createApp } from 'vue';

const app = createApp();
let contentVue = app.component("contentTemplate", {
  template: '<div style="border: 1px solid black; padidng: 5px 5px 5px 5px, backgrund:#f5f5f5">Highest Medal Count</div>',
  data() {
    return {
      data: {}
    };
  }
});
let contentTemplate = function () {
  return { template: contentVue };
};


export default {
  name: "App",
  components: {
    'ejs-chart': ChartComponent,
    'e-series-collection': SeriesCollectionDirective,
    'e-series': SeriesDirective
  },
  data() {
    return {
      seriesData: [
        { 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 }
      ],
      annotations: [{
        content: contentTemplate,
        x: 'France',
        y: 50,
        verticalAlignment: 'Top',
        horizontalAlignment: 'Near'
      }],
      primaryXAxis: {
        valueType: 'Category',
        title: 'Countries'
      },
      primaryYAxis:
      {
        minimum: 0, maximum: 80,
        interval: 20, title: 'Medals'
      },
      title: "Olympic Medals"
    };
  },
  provide: {
    chart: [ColumnSeries, Category, ChartAnnotation]
  },
};
</script>
<style>
#container {
  height: 350px;
}
</style>

Adding y-axis sub title through on annotation

By setting text div in the content option of annotation object you can add sub title to chart y-axis. Specified the coordinate value as pixel and customize x and y location of the text.

<template>
  <div id="app">
    <ejs-chart id="container" :title='title' :primaryXAxis='primaryXAxis' :primaryYAxis='primaryYAxis'
      :annotations='annotations'>
      <e-series-collection>
        <e-series :dataSource='seriesData' type='Column' xName='country' yName='gold' name='Gold'> </e-series>
      </e-series-collection>
    </ejs-chart>
  </div>
</template>
<script setup>
import { provide, createApp } from "vue";
import { ChartComponent as EjsChart, SeriesCollectionDirective as ESeriesCollection, SeriesDirective as ESeries, ColumnSeries, Category, ChartAnnotation } from "@syncfusion/ej2-vue-charts";


const app = createApp();
let contentVue = app.component("contentTemplate", {
  template: '<div id="text" style="transform: rotate(-90deg);">Speed Rate</div>',
  data() {
    return {
      data: {}
    };
  }
});
let contentTemplate = function () {
  return { template: contentVue };
};


const seriesData = [
  { 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 }
];
const annotations = [{
  content: contentTemplate,
  coordinateUnits: 'Pixel',
  x: 13,
  y: 180,
  region: 'Chart'
}];
const primaryXAxis = {
  valueType: 'Category',
  title: 'Countries'
};
const primaryYAxis =
{
  minimum: 0, maximum: 80,
  interval: 20, title: '(m2/min)'
};
const title = "Olympic Medals";

provide('chart', [ColumnSeries, Category, ChartAnnotation]);

</script>
<style>
#container {
  height: 350px;
}
</style>
<template>
  <div id="app">
    <ejs-chart id="container" :title='title' :primaryXAxis='primaryXAxis' :primaryYAxis='primaryYAxis'
      :annotations='annotations'>
      <e-series-collection>
        <e-series :dataSource='seriesData' type='Column' xName='country' yName='gold' name='Gold'> </e-series>
      </e-series-collection>
    </ejs-chart>
  </div>
</template>
<script>

import { ChartComponent, SeriesCollectionDirective, SeriesDirective, ColumnSeries, Category, ChartAnnotation } from "@syncfusion/ej2-vue-charts";
import { createApp } from 'vue';

const app = createApp();
let contentVue = app.component("contentTemplate", {
  template: '<div id="text" style="transform: rotate(-90deg);">Speed Rate</div>',
  data() {
    return {
      data: {}
    };
  }
});
let contentTemplate = function () {
  return { template: contentVue };
};


export default {
  name: "App",
  components: {
    'ejs-chart': ChartComponent,
    'e-series-collection': SeriesCollectionDirective,
    'e-series': SeriesDirective
  },
  data() {
    return {
      seriesData: [
        { 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 }
      ],
      annotations: [{
        content: contentTemplate,
        coordinateUnits: 'Pixel',
        x: 13,
        y: 180,
        region: 'Chart'
      }],
      primaryXAxis: {
        valueType: 'Category',
        title: 'Countries'
      },
      primaryYAxis:
      {
        minimum: 0, maximum: 80,
        interval: 20, title: '(m2/min)'
      },
      title: "Olympic Medals"
    };
  },
  provide: {
    chart: [ColumnSeries, Category, ChartAnnotation]
  },
};
</script>
<style>
#container {
  height: 350px;
}
</style>