How can I help you?
Dynamic data update in Angular Chart component
3 Feb 202624 minutes to read
Adding a new data point
Use the addPoint method to dynamically append a new data point to a series. This is useful for real-time data streams, user interactions, or incremental data loading. The method accepts the following parameters:
- Data point (required): The new data object to append to the series (must match the datasource structure)
- Animation duration (optional): Duration in milliseconds for the entry animation
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { ChartComponent, SplineSeriesService, CategoryService, LegendService, DataLabelService } from '@syncfusion/ej2-angular-charts';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { Component, OnInit, ViewChild } from '@angular/core';
@Component({
imports: [
ChartModule, ButtonModule
],
providers: [ SplineSeriesService, CategoryService, LegendService, DataLabelService ],
standalone: true,
selector: 'app-container',
template: `<ejs-chart #chart id="chart-container" [primaryXAxis]='primaryXAxis'[primaryYAxis]='primaryYAxis' [title]='title' [legendSettings]='legendSettings' [chartArea]='chartArea'>
<e-series-collection>
<e-series [dataSource]='chartData' type='Spline' xName='x' yName='y' name='Users' width=2 [marker]='marker'></e-series>
</e-series-collection>
</ejs-chart>
<button ej-button id='add' (click)='click()'>Add Point</button>`
})
export class AppComponent implements OnInit {
@ViewChild('chart')
public chart?: ChartComponent;
public primaryXAxis?: Object;
public primaryYAxis?: Object;
public chartData?: Object[] = [
{ x: "Germany", y: 72 },
{ x: "Russia", y: 103.1 },
{ x: "Brazil", y: 139.1 },
{ x: "India", y: 462.1 },
{ x: "China", y: 721.4 },
{ x: "USA", y: 286.9 },
{ x: "Great Britain", y: 115.1 },
{ x: "Nigeria", y: 97.2 }
];
public title?: string;
public marker?: Object;
public legendSettings?: Object;
public chartArea?: Object;
ngOnInit(): void {
this.primaryXAxis = {
valueType: 'Category',
enableTrim: false,
majorTickLines: { width: 0 },
majorGridLines: { width: 0 }
};
this.primaryYAxis = {
minimum: 0,
maximum: 800,
labelFormat: '{value}M',
edgeLabelPlacement: 'Shift'
};
this.title = 'Internet Users - 2016';
this.marker = {
visible: true,
dataLabel: {
visible: true,
position: 'Top',
font: { fontWeight: '600' }
}
};
this.legendSettings = { visible: false };
this.chartArea = {
border: { width: 1 }
};
}
click() {
if (this.chart?.series?.length) {
if (typeof this.chart.series[0].addPoint === 'function') {
this.chart?.series[0].addPoint({ x: 'Japan', y: 118.2 });
}
}
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Removing an existing data point
Use the removePoint method to dynamically delete a data point from a series by its index. This is useful for filtering data, removing outliers, or responding to user actions. The method accepts the following parameters:
- Point index (required): The zero-based index of the data point to remove
- Animation duration (optional): Duration in milliseconds for the exit animation
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { ChartComponent, SplineSeriesService, CategoryService, LegendService, DataLabelService } from '@syncfusion/ej2-angular-charts';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { Component, OnInit, ViewChild } from '@angular/core';
@Component({
imports: [
ChartModule, ButtonModule
],
providers: [ SplineSeriesService, CategoryService, LegendService, DataLabelService ],
standalone: true,
selector: 'app-container',
template: `<ejs-chart #chart id="chart-container" [primaryXAxis]='primaryXAxis'[primaryYAxis]='primaryYAxis' [title]='title' [legendSettings]='legendSettings' [chartArea]='chartArea'>
<e-series-collection>
<e-series [dataSource]='chartData' type='Spline' xName='x' yName='y' name='Users' width=2 [marker]='marker'></e-series>
</e-series-collection>
</ejs-chart>
<button ej-button id='remove' (click)='click()'>Remove Point</button>`
})
export class AppComponent implements OnInit {
@ViewChild('chart')
public chart?: ChartComponent;
public primaryXAxis?: Object;
public primaryYAxis?: Object;
public chartData?: Object[] = [
{ x: "Germany", y: 72 },
{ x: "Russia", y: 103.1 },
{ x: "Brazil", y: 139.1 },
{ x: "India", y: 462.1 },
{ x: "China", y: 721.4 },
{ x: "USA", y: 286.9 },
{ x: "Great Britain", y: 115.1 },
{ x: "Nigeria", y: 97.2 }
];
public title?: string;
public marker?: Object;
public legendSettings?: Object;
public chartArea?: Object;
ngOnInit(): void {
this.primaryXAxis = {
valueType: 'Category',
enableTrim: false,
majorTickLines: { width: 0 },
majorGridLines: { width: 0 }
};
this.primaryYAxis = {
minimum: 0,
maximum: 800,
labelFormat: '{value}M',
edgeLabelPlacement: 'Shift'
};
this.title = 'Internet Users - 2016';
this.marker = {
visible: true,
dataLabel: {
visible: true,
position: 'Top',
font: { fontWeight: '600' }
}
};
this.legendSettings = { visible: false };
this.chartArea = {
border: { width: 1 }
};
}
click() {
if (this.chart?.series?.length) {
if (typeof this.chart.series[0].removePoint === 'function') {
this.chart?.series[0].removePoint(0);
}
}
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Replacing entire data points
Use the setData method to replace all data points in a series with a new dataset. This is useful for category switching, time range changes, or complete data refreshes. The method accepts the following parameters:
- New data source (required): The complete new dataset array to display
- Animation duration (optional): Duration in milliseconds for the transition animation
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { ChartComponent, ColumnSeriesService, CategoryService, IAxisRangeCalculatedEventArgs } from '@syncfusion/ej2-angular-charts';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { Component, OnInit, ViewChild } from '@angular/core';
@Component({
imports: [
ChartModule, ButtonModule
],
providers: [ ColumnSeriesService, CategoryService ],
standalone: true,
selector: 'app-container',
template: `<ejs-chart #chart id="chart-container" [primaryXAxis]='primaryXAxis'[primaryYAxis]='primaryYAxis' [title]='title' [chartArea]='chartArea' (axisRangeCalculated)="axisRangeCalculated($event)">
<e-series-collection>
<e-series [dataSource]='chartData' type='Column' xName='x' yName='y' columnWidth=0.5 [cornerRadius]='cornerRadius'></e-series>
</e-series-collection>
</ejs-chart>
<button ej-button id='update' (click)='click()'>Update Data</button>`
})
export class AppComponent implements OnInit {
@ViewChild('chart')
public chart?: ChartComponent;
public primaryXAxis?: Object;
public primaryYAxis?: Object;
public chartData?: Object[] = [
{ x: 'Jewellery', y: 75 },
{ x: 'Shoes', y: 45 },
{ x: 'Footwear', y: 73 },
{ x: 'Pet Services', y: 53 },
{ x: 'Business Clothing', y: 85 },
{ x: 'Office Supplies', y: 68 },
{ x: 'Food', y: 45 }
];
public title?: string;
public cornerRadius?: Object;
public chartArea?: Object;
public getRandomInt(min: number, max: number) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
ngOnInit(): void {
this.primaryXAxis = {
valueType: 'Category',
majorGridLines: { width: 0 },
labelStyle: { size: '12px' },
labelIntersectAction: 'Rotate90'
};
this.primaryYAxis = {
title: 'Sales (in percentage)',
labelFormat: '{value}%',
lineStyle: { width: 0 },
majorTickLines: { width: 0 },
interval: 5,
minimum: 0,
maximum: 100
};
this.title = 'Sales by product';
this.cornerRadius = { topLeft: 15, topRight: 15 };
this.chartArea = {
border: { width: 0 }
};
}
click() {
if (this.chart && this.chart.series && this.chart.series.length > 0 && this.chart.series[0].dataSource) {
const newData = (
this.chart.series[0].dataSource as { x: string; y: number }[]
).map((item) => {
const value: number = this.getRandomInt(10, 90);
return { x: item.x, y: value };
});
if (typeof this.chart.series[0].setData === 'function') {
this.chart.series[0].setData(newData, 500);
}
}
}
public axisRangeCalculated (args: IAxisRangeCalculatedEventArgs): void {
if (args.axis.name === 'primaryYAxis') {
args.maximum = args.maximum as number > 100 ? 100 : args.maximum;
if (args.maximum > 80) {
args.interval = 20;
} else if(args.maximum > 40){
args.interval = 10;
}
}
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Click to add or remove a data point
Enable users to add or remove data points by clicking on the chart. Listen to the chartMouseClick event to capture click coordinates and point information. When a user clicks within the chart area, extract the x and y axis values from the event arguments. If the location is empty, use addPoint to add a new data point at those coordinates. If a user clicks on an existing data point, identify its index and use removePoint to delete it. This creates an intuitive interface for data exploration and editing.
To remove a data point from the existing data source, simply click on the desired data point. To achieve this, first, verify whether the clicked data point obtained from chartMouseClick already exists in the data source. If it does, remove it by utilizing the removePoint method based on its index.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { ChartComponent, LineSeriesService, CategoryService, TooltipService, DataLabelService, IAxisRangeCalculatedEventArgs, Series, IMouseEventArgs } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit, ViewChild } from '@angular/core';
@Component({
imports: [
ChartModule
],
providers: [ LineSeriesService, CategoryService, TooltipService, DataLabelService ],
standalone: true,
selector: 'app-container',
template: `<ejs-chart #chart id="chart-container" [primaryXAxis]='primaryXAxis'[primaryYAxis]='primaryYAxis' [title]='title' [chartArea]='chartArea' [tooltip]='tooltip' (chartMouseClick)='chartMouseClick($event)' (axisRangeCalculated)="axisRangeCalculated($event)">
<e-series-collection>
<e-series [dataSource]='chartData' type='Line' xName='x' yName='y' width=3 [marker]='marker'></e-series>
</e-series-collection>
</ejs-chart>
`
})
export class AppComponent implements OnInit {
@ViewChild('chart')
public chart?: ChartComponent;
public primaryXAxis?: Object;
public primaryYAxis?: Object;
public chartData?: Object[] = [
{ x: 20, y: 20 },
{ x: 80, y: 80 }
];
public title?: string;
public marker?: Object;
public chartArea?: Object;
public tooltip?: Object;
ngOnInit(): void {
this.primaryXAxis = {
edgeLabelPlacement: 'Shift',
rangePadding: 'Additional',
majorGridLines: { width: 0 }
};
this.primaryYAxis = {
title: 'Value',
interval: 20,
lineStyle: { width: 0 },
majorTickLines: { width: 0 }
};
this.title = 'User supplied data';
this.marker = {
visible: true,
isFilled: true,
border: {
width: 2,
color: 'White'
},
width: 13,
height: 13
};
this.chartArea = {
border: { width: 0 }
};
this.tooltip = { enable: true };
}
public chartMouseClick(args: IMouseEventArgs): void {
let isRemoved: boolean = false;
if (args.axisData && this.chart?.series) {
for (let i: number = 0; i < (this.chart.series[0] as Series).points.length; i++) {
let markerWidth: number = (this.chart.series[0] as Series).marker?.width ?? 0 / 2;
let roundedX: number = Math.round(args.axisData['primaryXAxis']) + markerWidth;
let roundedY: number = Math.round(args.axisData['primaryYAxis']) + markerWidth;
let pointX: number = Math.round((this.chart.series[0] as Series).points[i].x as number) + markerWidth;
let pointY: number = Math.round((this.chart.series[0] as Series).points[i].y as number) + markerWidth;
if ((roundedX === pointX || roundedX + 1 === pointX || roundedX - 1 === pointX) &&
(roundedY === pointY || roundedY + 1 === pointY || roundedY - 1 === pointY)) {
if ((this.chart.series[0] as Series).points.length > 1) {
const points = (this.chart.series[0] as Series).points;
const duration: number = i === 0 || i === points[points.length - 1].index ? 500 : 0;
if (this.chart?.series?.length) {
if (typeof this.chart.series[0].removePoint === 'function') {
this.chart.series[0].removePoint(i, duration);
}
}
}
isRemoved = true;
}
}
if (!isRemoved) {
if (this.chart?.series?.length) {
if (typeof this.chart.series[0].addPoint === 'function') {
this.chart.series[0].addPoint({
x: Math.round(args.axisData['primaryXAxis']),
y: Math.round(args.axisData['primaryYAxis'])
});
}
}
}
}
};
public axisRangeCalculated(args: IAxisRangeCalculatedEventArgs): void {
if (args.axis.name === 'primaryXAxis') {
if (args.interval < 10) {
args.maximum = args.maximum + 10;
args.minimum = args.minimum - 10;
args.interval = 10;
}
}
if (args.axis.name === 'primaryYAxis') {
if (args.maximum <= 60) {
args.interval = 10;
}
}
};
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));