Stacked Line Chart in Angular Charts
28 Aug 202624 minutes to read
Stacked Line
A stacked line chart displays multiple line series stacked on top of each other to show the cumulative total at each point.
Configure a stacked line series as follows:
-
Set the series type: Set the series
typetoStackingLine. UseStackingLine100to render a 100% stacked line chart. -
Register the service: Register
StackingLineSeriesService(and any required axis services) in the moduleprovidersarray, or inApplicationConfig.providersfor standalone applications. Confirm thatChartModuleis imported. -
Bind the data: Add at least two
<e-series>entries that share the sametype. Bind each entry to the data viadataSource, and assign a differentxName/yNamepair so each series contributes a separate value to the stack.
import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { CategoryService, StackingLineSeriesService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { chartData } from './datasource';
@Component({
imports: [
ChartModule
],
providers: [CategoryService, StackingLineSeriesService],
standalone: true,
selector: 'app-container',
template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [primaryYAxis]='primaryYAxis'>
<e-series-collection>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y' name='John' [marker]='marker'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y1' name='Peter' [marker]='marker'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y2' name='Steve' [marker]='marker'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y3' name='Charle' [marker]='marker'></e-series>
</e-series-collection>
</ejs-chart>`
})
export class AppComponent implements OnInit {
public primaryXAxis?: Object;
public primaryYAxis?: Object;
public marker?: Object;
public chartData?: Object[];
ngOnInit(): void {
this.primaryXAxis = {
interval: 1,
valueType: 'Category'
};
this.primaryYAxis = {
title: 'Expense',
interval: 100,
labelFormat: '${value}'
};
this.chartData = chartData;
this.marker = { visible: true };
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));export let chartData: Object[] = [
{ x: 'Food', y: 90, y1: 40, y2: 70, y3: 120 },
{ x: 'Transport', y: 80, y1: 90, y2: 110, y3: 70 },
{ x: 'Medical', y: 50, y1: 80, y2: 120, y3: 50 },
{ x: 'Clothes', y: 70, y1: 30, y2: 60, y3: 180 },
{ x: 'Personal Care', y: 30, y1: 80, y2: 80, y3: 30 },
{ x: 'Books', y: 10, y1: 40, y2: 30, y3: 270 },
{ x: 'Fitness', y: 100, y1: 30, y2: 70, y3: 40 },
{ x: 'Electricity', y: 55, y1: 95, y2: 55, y3: 75 },
{ x: 'Tax', y: 20, y1: 50, y2: 40, y3: 65 },
{ x: 'Pet Care', y: 40, y1: 20, y2: 80, y3: 95 },
{ x: 'Education', y: 45, y1: 15, y2: 45, y3: 195 },
{ x: 'Entertainment', y: 75, y1: 45, y2: 65, y3: 115 }
];Series customization
Customize a stacked line series using the following properties.
Solid color
Use the fill property to set a single solid stroke color. Accepted values are CSS color names (for example, blue), hexadecimal strings (for example, #1A75FF), and rgba(...) strings. To color several series independently, set a different fill per <e-series> element.
import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { CategoryService, StackingLineSeriesService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { chartData } from './datasource';
@Component({
imports: [
ChartModule
],
providers: [CategoryService, StackingLineSeriesService],
standalone: true,
selector: 'app-container',
template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [primaryYAxis]='primaryYAxis'>
<e-series-collection>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y' name='John' [marker]='marker' fill='red'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y1' name='Peter' [marker]='marker' fill='yellow'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y2' name='Steve' [marker]='marker' fill='black'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y3' name='Charle' [marker]='marker' fill='blue'></e-series>
</e-series-collection>
</ejs-chart>`
})
export class AppComponent implements OnInit {
public primaryXAxis?: Object;
public primaryYAxis?: Object;
public marker?: Object;
public chartData?: Object[];
ngOnInit(): void {
this.primaryXAxis = {
interval: 1,
valueType: 'Category'
};
this.primaryYAxis = {
title: 'Expense',
interval: 100,
labelFormat: '${value}'
};
this.chartData = chartData;
this.marker = { visible: true };
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));export let chartData: Object[] = [
{ x: 'Food', y: 90, y1: 40, y2: 70, y3: 120 },
{ x: 'Transport', y: 80, y1: 90, y2: 110, y3: 70 },
{ x: 'Medical', y: 50, y1: 80, y2: 120, y3: 50 },
{ x: 'Clothes', y: 70, y1: 30, y2: 60, y3: 180 },
{ x: 'Personal Care', y: 30, y1: 80, y2: 80, y3: 30 },
{ x: 'Books', y: 10, y1: 40, y2: 30, y3: 270 },
{ x: 'Fitness', y: 100, y1: 30, y2: 70, y3: 40 },
{ x: 'Electricity', y: 55, y1: 95, y2: 55, y3: 75 },
{ x: 'Tax', y: 20, y1: 50, y2: 40, y3: 65 },
{ x: 'Pet Care', y: 40, y1: 20, y2: 80, y3: 95 },
{ x: 'Education', y: 45, y1: 15, y2: 45, y3: 195 },
{ x: 'Entertainment', y: 75, y1: 45, y2: 65, y3: 115 }
];Gradient color
The fill property can reference an SVG gradient. Define each gradient in an SVG <defs> element and assign it in the url(#gradientId) format.
import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { CategoryService, StackingLineSeriesService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { chartData } from './datasource';
@Component({
imports: [
ChartModule
],
providers: [CategoryService, StackingLineSeriesService],
standalone: true,
selector: 'app-container',
template: `
<svg style="width:1px; height:1px">
<defs>
<linearGradient id="gradient1">
<stop offset="0%" style="stop-color:coral;stop-opacity:5" />
<stop offset="50%" style="stop-color:mediumseagreen;stop-opacity:5" />
</linearGradient>
</defs>
</svg>
<svg style="width:1px; height:1px">
<defs>
<linearGradient id="gradient2">
<stop offset="0%" style="stop-color:darkred;stop-opacity:5" />
<stop offset="50%" style="stop-color:darkorange;stop-opacity:5" />
</linearGradient>
</defs>
</svg>
<svg style="width:1px; height:1px">
<defs>
<linearGradient id="gradient3">
<stop offset="0%" style="stop-color:darkmagenta;stop-opacity:5" />
<stop offset="50%" style="stop-color:darkcyan;stop-opacity:5" />
</linearGradient>
</defs>
</svg>
<svg style="width:1px; height:1px">
<defs>
<linearGradient id="gradient4">
<stop offset="0%" style="stop-color:darkviolet;stop-opacity:5" />
<stop offset="50%" style="stop-color:darkgoldenrod;stop-opacity:5" />
</linearGradient>
</defs>
</svg>
<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis'[primaryYAxis]='primaryYAxis'>
<e-series-collection>
<e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y' name='John' [marker]='marker' [fill]="'url(#gradient1)'"> </e-series>
<e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y1' name='Peter' [marker]='marker' [fill]="'url(#gradient2)'"> </e-series>
<e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y2' name='Steve' [marker]='marker' [fill]="'url(#gradient3)'"> </e-series>
<e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y3' name='Charle' [marker]='marker' [fill]="'url(#gradient4)'"> </e-series>
</e-series-collection>
</ejs-chart>`
})
export class AppComponent implements OnInit {
public primaryXAxis?: Object;
public primaryYAxis?: Object;
public marker?: Object;
public chartData?: Object[];
ngOnInit(): void {
this.primaryXAxis = {
interval: 1,
valueType: 'Category'
};
this.primaryYAxis = {
title: 'Expense',
interval: 100,
labelFormat: '${value}'
};
this.chartData = chartData;
this.marker = { visible: true };
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));export let chartData: Object[] = [
{ x: 'Food', y: 90, y1: 40, y2: 70, y3: 120 },
{ x: 'Transport', y: 80, y1: 90, y2: 110, y3: 70 },
{ x: 'Medical', y: 50, y1: 80, y2: 120, y3: 50 },
{ x: 'Clothes', y: 70, y1: 30, y2: 60, y3: 180 },
{ x: 'Personal Care', y: 30, y1: 80, y2: 80, y3: 30 },
{ x: 'Books', y: 10, y1: 40, y2: 30, y3: 270 },
{ x: 'Fitness', y: 100, y1: 30, y2: 70, y3: 40 },
{ x: 'Electricity', y: 55, y1: 95, y2: 55, y3: 75 },
{ x: 'Tax', y: 20, y1: 50, y2: 40, y3: 65 },
{ x: 'Pet Care', y: 40, y1: 20, y2: 80, y3: 95 },
{ x: 'Education', y: 45, y1: 15, y2: 45, y3: 195 },
{ x: 'Entertainment', y: 75, y1: 45, y2: 65, y3: 115 }
];Opacity
Use the opacity property to control line transparency. Set a value from 0 to 1.
import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { CategoryService, StackingLineSeriesService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { chartData } from './datasource';
@Component({
imports: [
ChartModule
],
providers: [CategoryService, StackingLineSeriesService],
standalone: true,
selector: 'app-container',
template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [primaryYAxis]='primaryYAxis'>
<e-series-collection>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y' name='John' [marker]='marker' [opacity]='0.5'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y1' name='Peter' [marker]='marker' [opacity]='0.5'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y2' name='Steve' [marker]='marker' [opacity]='0.5'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y3' name='Charle' [marker]='marker' [opacity]='0.5'></e-series>
</e-series-collection>
</ejs-chart>`
})
export class AppComponent implements OnInit {
public primaryXAxis?: Object;
public primaryYAxis?: Object;
public marker?: Object;
public chartData?: Object[];
ngOnInit(): void {
this.primaryXAxis = {
interval: 1,
valueType: 'Category'
};
this.primaryYAxis = {
title: 'Expense',
interval: 100,
labelFormat: '${value}'
};
this.chartData = chartData;
this.marker = { visible: true };
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));export let chartData: Object[] = [
{ x: 'Food', y: 90, y1: 40, y2: 70, y3: 120 },
{ x: 'Transport', y: 80, y1: 90, y2: 110, y3: 70 },
{ x: 'Medical', y: 50, y1: 80, y2: 120, y3: 50 },
{ x: 'Clothes', y: 70, y1: 30, y2: 60, y3: 180 },
{ x: 'Personal Care', y: 30, y1: 80, y2: 80, y3: 30 },
{ x: 'Books', y: 10, y1: 40, y2: 30, y3: 270 },
{ x: 'Fitness', y: 100, y1: 30, y2: 70, y3: 40 },
{ x: 'Electricity', y: 55, y1: 95, y2: 55, y3: 75 },
{ x: 'Tax', y: 20, y1: 50, y2: 40, y3: 65 },
{ x: 'Pet Care', y: 40, y1: 20, y2: 80, y3: 95 },
{ x: 'Education', y: 45, y1: 15, y2: 45, y3: 195 },
{ x: 'Entertainment', y: 75, y1: 45, y2: 65, y3: 115 }
];Dash array
Use the dashArray property to define the line stroke’s dash pattern. Provide a comma or whitespace-separated list of stroke-gap sizes in pixels, for example "5,5", "2,2,10,2", or "4 4".
import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { CategoryService, StackingLineSeriesService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { chartData } from './datasource';
@Component({
imports: [
ChartModule
],
providers: [CategoryService, StackingLineSeriesService],
standalone: true,
selector: 'app-container',
template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [primaryYAxis]='primaryYAxis'>
<e-series-collection>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y' name='John' [marker]='marker' dashArray='5,5'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y1' name='Peter' [marker]='marker' dashArray='5,5'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y2' name='Steve' [marker]='marker' dashArray='5,5'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y3' name='Charle' [marker]='marker' dashArray='5,5'></e-series>
</e-series-collection>
</ejs-chart>`
})
export class AppComponent implements OnInit {
public primaryXAxis?: Object;
public primaryYAxis?: Object;
public marker?: Object;
public chartData?: Object[];
ngOnInit(): void {
this.primaryXAxis = {
interval: 1,
valueType: 'Category'
};
this.primaryYAxis = {
title: 'Expense',
interval: 100,
labelFormat: '${value}'
};
this.chartData = chartData;
this.marker = { visible: true };
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));export let chartData: Object[] = [
{ x: 'Food', y: 90, y1: 40, y2: 70, y3: 120 },
{ x: 'Transport', y: 80, y1: 90, y2: 110, y3: 70 },
{ x: 'Medical', y: 50, y1: 80, y2: 120, y3: 50 },
{ x: 'Clothes', y: 70, y1: 30, y2: 60, y3: 180 },
{ x: 'Personal Care', y: 30, y1: 80, y2: 80, y3: 30 },
{ x: 'Books', y: 10, y1: 40, y2: 30, y3: 270 },
{ x: 'Fitness', y: 100, y1: 30, y2: 70, y3: 40 },
{ x: 'Electricity', y: 55, y1: 95, y2: 55, y3: 75 },
{ x: 'Tax', y: 20, y1: 50, y2: 40, y3: 65 },
{ x: 'Pet Care', y: 40, y1: 20, y2: 80, y3: 95 },
{ x: 'Education', y: 45, y1: 15, y2: 45, y3: 195 },
{ x: 'Entertainment', y: 75, y1: 45, y2: 65, y3: 115 }
];Width
Use the width property to set the line stroke width in pixels.
import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { CategoryService, StackingLineSeriesService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { chartData } from './datasource';
@Component({
imports: [
ChartModule
],
providers: [CategoryService, StackingLineSeriesService],
standalone: true,
selector: 'app-container',
template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [primaryYAxis]='primaryYAxis'>
<e-series-collection>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y' name='John' width='5' [marker]='marker'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y1' name='Peter' width='5' [marker]='marker'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y2' name='Steve' width='5' [marker]='marker'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y3' name='Charle' width='5' [marker]='marker'></e-series>
</e-series-collection>
</ejs-chart>`
})
export class AppComponent implements OnInit {
public primaryXAxis?: Object;
public primaryYAxis?: Object;
public marker?: Object;
public chartData?: Object[];
ngOnInit(): void {
this.primaryXAxis = {
interval: 1,
valueType: 'Category'
};
this.primaryYAxis = {
title: 'Expense',
interval: 100,
labelFormat: '${value}'
};
this.chartData = chartData;
this.marker = { visible: true };
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));export let chartData: Object[] = [
{ x: 'Food', y: 90, y1: 40, y2: 70, y3: 120 },
{ x: 'Transport', y: 80, y1: 90, y2: 110, y3: 70 },
{ x: 'Medical', y: 50, y1: 80, y2: 120, y3: 50 },
{ x: 'Clothes', y: 70, y1: 30, y2: 60, y3: 180 },
{ x: 'Personal Care', y: 30, y1: 80, y2: 80, y3: 30 },
{ x: 'Books', y: 10, y1: 40, y2: 30, y3: 270 },
{ x: 'Fitness', y: 100, y1: 30, y2: 70, y3: 40 },
{ x: 'Electricity', y: 55, y1: 95, y2: 55, y3: 75 },
{ x: 'Tax', y: 20, y1: 50, y2: 40, y3: 65 },
{ x: 'Pet Care', y: 40, y1: 20, y2: 80, y3: 95 },
{ x: 'Education', y: 45, y1: 15, y2: 45, y3: 195 },
{ x: 'Entertainment', y: 75, y1: 45, y2: 65, y3: 115 }
];Empty points
A data point whose mapped value is null or undefined is empty. Configure its behavior with emptyPointSettings.mode.
Mode
Use mode to control empty-point rendering. The default is Gap.
| Mode | Visual behavior |
|---|---|
Gap |
Leave a gap at the empty position and continue the stack through the next available point. |
Zero |
Treat the empty point as 0 and connect it. |
Drop |
Drop the line segment; subsequent points are still rendered. |
Average |
Replace the empty value with the average of the surrounding points. |
import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { CategoryService, StackingLineSeriesService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { chartData } from './datasource';
@Component({
imports: [
ChartModule
],
providers: [CategoryService, StackingLineSeriesService],
standalone: true,
selector: 'app-container',
template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [primaryYAxis]='primaryYAxis'>
<e-series-collection>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y' name='John' [marker]='marker' [emptyPointSettings]='emptyPointSettings'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y1' name='Peter' [marker]='marker'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y2' name='Steve' [marker]='marker' [emptyPointSettings]='emptyPointSettings1'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y3' name='Charle' [marker]='marker'></e-series>
</e-series-collection>
</ejs-chart>`
})
export class AppComponent implements OnInit {
public primaryXAxis?: Object;
public primaryYAxis?: Object;
public marker?: Object;
public chartData?: Object[];
public emptyPointSettings?: Object;
public emptyPointSettings1?: Object;
ngOnInit(): void {
this.primaryXAxis = {
interval: 1,
valueType: 'Category'
};
this.primaryYAxis = {
title: 'Expense',
interval: 100,
labelFormat: '${value}'
};
this.chartData = chartData;
this.marker = { visible: true };
this.emptyPointSettings = { mode: 'Average' };
this.emptyPointSettings1 = { mode: 'Gap' };
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));export let chartData: Object[] = [
{ x: 'Food', y: 90, y1: 40, y2: 70, y3: 120 },
{ x: 'Transport', y: 80, y1: 90, y2: 110, y3: 70 },
{ x: 'Medical', y: 50, y1: 80, y2: 120, y3: 50 },
{ x: 'Clothes', y: null, y1: 30, y2: 60, y3: 180 },
{ x: 'Personal Care', y: 30, y1: 80, y2: 80, y3: 30 },
{ x: 'Books', y: 10, y1: 40, y2: 30, y3: 270 },
{ x: 'Fitness', y: 100, y1: 30, y2: 70, y3: 40 },
{ x: 'Electricity', y: 55, y1: 95, y2: undefined, y3: 75 },
{ x: 'Tax', y: 20, y1: 50, y2: 40, y3: 65 },
{ x: 'Pet Care', y: 40, y1: 20, y2: 80, y3: 95 },
{ x: 'Education', y: 45, y1: 15, y2: 45, y3: 195 },
{ x: 'Entertainment', y: 75, y1: 45, y2: 65, y3: 115 }
];Empty-point fill
Use the emptyPointSettings.fill property to customize the fill color of empty points.
import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { CategoryService, StackingLineSeriesService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { chartData } from './datasource';
@Component({
imports: [
ChartModule
],
providers: [CategoryService, StackingLineSeriesService],
standalone: true,
selector: 'app-container',
template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [primaryYAxis]='primaryYAxis'>
<e-series-collection>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y' name='John' [marker]='marker' [emptyPointSettings]='emptyPointSettings'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y1' name='Peter' [marker]='marker'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y2' name='Steve' [marker]='marker' [emptyPointSettings]='emptyPointSettings1'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y3' name='Charle' [marker]='marker'></e-series>
</e-series-collection>
</ejs-chart>`
})
export class AppComponent implements OnInit {
public primaryXAxis?: Object;
public primaryYAxis?: Object;
public marker?: Object;
public chartData?: Object[];
public emptyPointSettings?: Object;
public emptyPointSettings1?: Object;
ngOnInit(): void {
this.primaryXAxis = {
interval: 1,
valueType: 'Category'
};
this.primaryYAxis = {
title: 'Expense',
interval: 100,
labelFormat: '${value}'
};
this.chartData = chartData;
this.marker = { visible: true };
this.emptyPointSettings = { mode: 'Average', fill: 'red' };
this.emptyPointSettings1 = { mode: 'Gap' };
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));export let chartData: Object[] = [
{ x: 'Food', y: 90, y1: 40, y2: 70, y3: 120 },
{ x: 'Transport', y: 80, y1: 90, y2: 110, y3: 70 },
{ x: 'Medical', y: 50, y1: 80, y2: 120, y3: 50 },
{ x: 'Clothes', y: null, y1: 30, y2: 60, y3: 180 },
{ x: 'Personal Care', y: 30, y1: 80, y2: 80, y3: 30 },
{ x: 'Books', y: 10, y1: 40, y2: 30, y3: 270 },
{ x: 'Fitness', y: 100, y1: 30, y2: 70, y3: 40 },
{ x: 'Electricity', y: 55, y1: 95, y2: undefined, y3: 75 },
{ x: 'Tax', y: 20, y1: 50, y2: 40, y3: 65 },
{ x: 'Pet Care', y: 40, y1: 20, y2: 80, y3: 95 },
{ x: 'Education', y: 45, y1: 15, y2: 45, y3: 195 },
{ x: 'Entertainment', y: 75, y1: 45, y2: 65, y3: 115 }
];Empty-point border
Use the emptyPointSettings.border property to customize the width and color of a rendered empty point’s border.
import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { CategoryService, StackingLineSeriesService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { chartData } from './datasource';
@Component({
imports: [
ChartModule
],
providers: [CategoryService, StackingLineSeriesService],
standalone: true,
selector: 'app-container',
template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [primaryYAxis]='primaryYAxis'>
<e-series-collection>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y' name='John' [marker]='marker' [emptyPointSettings]='emptyPointSettings'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y1' name='Peter' [marker]='marker'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y2' name='Steve' [marker]='marker' [emptyPointSettings]='emptyPointSettings1'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y3' name='Charle' [marker]='marker'></e-series>
</e-series-collection>
</ejs-chart>`
})
export class AppComponent implements OnInit {
public primaryXAxis?: Object;
public primaryYAxis?: Object;
public marker?: Object;
public chartData?: Object[];
public emptyPointSettings?: Object;
public emptyPointSettings1?: Object;
ngOnInit(): void {
this.primaryXAxis = {
interval: 1,
valueType: 'Category'
};
this.primaryYAxis = {
title: 'Expense',
interval: 100,
labelFormat: '${value}'
};
this.chartData = chartData;
this.marker = { visible: true };
this.emptyPointSettings = { mode: 'Average', fill: 'red', border: { width: 1.5, color: 'green' } };
this.emptyPointSettings1 = { mode: 'Gap' };
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));export let chartData: Object[] = [
{ x: 'Food', y: 90, y1: 40, y2: 70, y3: 120 },
{ x: 'Transport', y: 80, y1: 90, y2: 110, y3: 70 },
{ x: 'Medical', y: 50, y1: 80, y2: 120, y3: 50 },
{ x: 'Clothes', y: null, y1: 30, y2: 60, y3: 180 },
{ x: 'Personal Care', y: 30, y1: 80, y2: 80, y3: 30 },
{ x: 'Books', y: 10, y1: 40, y2: 30, y3: 270 },
{ x: 'Fitness', y: 100, y1: 30, y2: 70, y3: 40 },
{ x: 'Electricity', y: 55, y1: 95, y2: undefined, y3: 75 },
{ x: 'Tax', y: 20, y1: 50, y2: 40, y3: 65 },
{ x: 'Pet Care', y: 40, y1: 20, y2: 80, y3: 95 },
{ x: 'Education', y: 45, y1: 15, y2: 45, y3: 195 },
{ x: 'Entertainment', y: 75, y1: 45, y2: 65, y3: 115 }
];Stack labels
Stacked charts can display cumulative totals directly on the chart using stackLabels. When a stacked point has negative values, the stack labels render below the point.
import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { CategoryService, DataLabelService, StackingLineSeriesService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { chartData } from './datasource';
@Component({
imports: [
ChartModule
],
providers: [CategoryService, DataLabelService, StackingLineSeriesService],
standalone: true,
selector: 'app-container',
template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [primaryYAxis]='primaryYAxis' [stackLabels]='stackLabels'>
<e-series-collection>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y' name='John' [marker]='marker'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y1' name='Peter' [marker]='marker'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y2' name='Steve' [marker]='marker'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y3' name='Charle' [marker]='marker'></e-series>
</e-series-collection>
</ejs-chart>`
})
export class AppComponent implements OnInit {
public primaryXAxis?: Object;
public primaryYAxis?: Object;
public marker?: Object;
public chartData?: Object[];
public stackLabels?: Object;
ngOnInit(): void {
this.primaryXAxis = {
interval: 1,
valueType: 'Category'
};
this.primaryYAxis = {
title: 'Expense',
interval: 100,
labelFormat: '${value}'
};
this.marker = { dataLabel: { visible: true } };
this.stackLabels = { visible: true };
this.chartData = chartData;
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));export let chartData: Object[] = [
{ x: 'Food', y: 90, y1: 40, y2: 70, y3: 120 },
{ x: 'Transport', y: 80, y1: 90, y2: 110, y3: 70 },
{ x: 'Medical', y: 50, y1: 80, y2: 120, y3: 50 },
{ x: 'Clothes', y: 70, y1: 30, y2: 60, y3: 180 },
{ x: 'Personal Care', y: 30, y1: 80, y2: 80, y3: 30 },
{ x: 'Books', y: 10, y1: 40, y2: 30, y3: 270 },
{ x: 'Fitness', y: 100, y1: 30, y2: 70, y3: 40 },
{ x: 'Electricity', y: 55, y1: 95, y2: 55, y3: 75 },
{ x: 'Tax', y: 20, y1: 50, y2: 40, y3: 65 },
{ x: 'Pet Care', y: 40, y1: 20, y2: 80, y3: 95 },
{ x: 'Education', y: 45, y1: 15, y2: 45, y3: 195 },
{ x: 'Entertainment', y: 75, y1: 45, y2: 65, y3: 115 }
];Stack labels customization
Stack labels have the following stackLabelSettings properties for customization:
| Property | Behavior | Default |
|---|---|---|
visible |
Specifies whether stack labels are visible. Setting to true will display the labels. |
false |
fill |
Defines the background color of the stack labels. Accepts valid CSS color strings (hex, RGBA, etc.). | transparent |
format |
Formats the text displayed in the stack labels. Supports placeholders such as {value}. |
null |
angle |
Specifies the rotation angle for stack labels in degrees. | 0 |
rx |
Defines the rounded corner radius along the X-axis (horizontal direction) for the stack label background. | 5 |
ry |
Defines the rounded corner radius along the Y-axis (vertical direction) for the stack label background. | 5 |
margin |
Configures the margin around the stack label (left, right, top, and bottom). |
— |
border |
Configures the appearance of the stack label’s border. | — |
font |
Customizes the stack label text, including font size, color, style, weight, and family. | — |
import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { CategoryService, DataLabelService, StackingLineSeriesService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { chartData } from './datasource';
@Component({
imports: [
ChartModule
],
providers: [CategoryService, DataLabelService, StackingLineSeriesService],
standalone: true,
selector: 'app-container',
template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [primaryYAxis]='primaryYAxis' [stackLabels]='stackLabels'>
<e-series-collection>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y' name='John' [marker]='marker'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y1' name='Peter' [marker]='marker'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y2' name='Steve' [marker]='marker'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y3' name='Charle' [marker]='marker'></e-series>
</e-series-collection>
</ejs-chart>`
})
export class AppComponent implements OnInit {
public primaryXAxis?: Object;
public primaryYAxis?: Object;
public marker?: Object;
public chartData?: Object[];
public stackLabels?: Object;
ngOnInit(): void {
this.primaryXAxis = {
interval: 1,
valueType: 'Category'
};
this.primaryYAxis = {
title: 'Expense',
interval: 100,
labelFormat: '${value}'
};
this.marker = { dataLabel: { visible: true } };
this.stackLabels = {
visible: true,
fill: 'rgba(0, 123, 255, 0.5)',
format: '{value}',
angle: 45,
rx: 10,
ry: 10,
margin: { left: 10, right: 10, top: 10, bottom: 10 },
border: { width: 2, color: '#000' },
font: { size: '14px', color: '#fff', weight: 'bold', family: 'Arial', textAlignment: 'Left' }
};
this.chartData = chartData;
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));export let chartData: Object[] = [
{ x: 'Food', y: 90, y1: 40, y2: 70, y3: 120 },
{ x: 'Transport', y: 80, y1: 90, y2: 110, y3: 70 },
{ x: 'Medical', y: 50, y1: 80, y2: 120, y3: 50 },
{ x: 'Clothes', y: 70, y1: 30, y2: 60, y3: 180 },
{ x: 'Personal Care', y: 30, y1: 80, y2: 80, y3: 30 },
{ x: 'Books', y: 10, y1: 40, y2: 30, y3: 270 },
{ x: 'Fitness', y: 100, y1: 30, y2: 70, y3: 40 },
{ x: 'Electricity', y: 55, y1: 95, y2: 55, y3: 75 },
{ x: 'Tax', y: 20, y1: 50, y2: 40, y3: 65 },
{ x: 'Pet Care', y: 40, y1: 20, y2: 80, y3: 95 },
{ x: 'Education', y: 45, y1: 15, y2: 45, y3: 195 },
{ x: 'Entertainment', y: 75, y1: 45, y2: 65, y3: 115 }
];Events
Series render
The seriesRender event allows you to customize series properties, such as data, fill, and name, before they are rendered on the chart. The callback receives an ISeriesRenderEventArgs argument that exposes mutable series and data properties.
<ejs-chart (seriesRender)="onSeriesRender($event)"></ejs-chart>import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { CategoryService, StackingLineSeriesService } from '@syncfusion/ej2-angular-charts';
import { ISeriesRenderEventArgs } from '@syncfusion/ej2-charts';
import { Component, OnInit } from '@angular/core';
import { chartData } from './datasource';
@Component({
imports: [
ChartModule
],
providers: [CategoryService, StackingLineSeriesService],
standalone: true,
selector: 'app-container',
template: `<ejs-chart id="chart-container" (seriesRender)='seriesRender($event)' [primaryXAxis]='primaryXAxis' [primaryYAxis]='primaryYAxis'>
<e-series-collection>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y' name='John' [marker]='marker'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y1' name='Peter' [marker]='marker'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y2' name='Steve' [marker]='marker'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y3' name='Charle' [marker]='marker'></e-series>
</e-series-collection>
</ejs-chart>`
})
export class AppComponent implements OnInit {
public primaryXAxis?: Object;
public primaryYAxis?: Object;
public marker?: Object;
public chartData?: Object[];
ngOnInit(): void {
this.primaryXAxis = {
interval: 1,
valueType: 'Category'
};
this.primaryYAxis = {
title: 'Expense',
interval: 100,
labelFormat: '${value}'
};
this.chartData = chartData;
this.marker = { visible: true };
}
public seriesRender(args: ISeriesRenderEventArgs): void {
const palette = ['#ff4251', '#4C4C4C', '#794F1B', '#1a9a6f'];
if (args.series.index >= 0 && args.series.index < palette.length) {
args.fill = palette[args.series.index];
}
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));export let chartData: Object[] = [
{ x: 'Food', y: 90, y1: 40, y2: 70, y3: 120 },
{ x: 'Transport', y: 80, y1: 90, y2: 110, y3: 70 },
{ x: 'Medical', y: 50, y1: 80, y2: 120, y3: 50 },
{ x: 'Clothes', y: 70, y1: 30, y2: 60, y3: 180 },
{ x: 'Personal Care', y: 30, y1: 80, y2: 80, y3: 30 },
{ x: 'Books', y: 10, y1: 40, y2: 30, y3: 270 },
{ x: 'Fitness', y: 100, y1: 30, y2: 70, y3: 40 },
{ x: 'Electricity', y: 55, y1: 95, y2: 55, y3: 75 },
{ x: 'Tax', y: 20, y1: 50, y2: 40, y3: 65 },
{ x: 'Pet Care', y: 40, y1: 20, y2: 80, y3: 95 },
{ x: 'Education', y: 45, y1: 15, y2: 45, y3: 195 },
{ x: 'Entertainment', y: 75, y1: 45, y2: 65, y3: 115 }
];Point render
The pointRender event allows you to customize each data point before it is rendered on the chart. The callback receives an IPointRenderEventArgs argument that exposes the current point, series, fill, and border, plus a cancel flag.
<ejs-chart (pointRender)="onPointRender($event)"></ejs-chart>import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { CategoryService, StackingLineSeriesService } from '@syncfusion/ej2-angular-charts';
import { IPointRenderEventArgs } from '@syncfusion/ej2-charts';
import { Component, OnInit } from '@angular/core';
import { chartData } from './datasource';
@Component({
imports: [
ChartModule
],
providers: [CategoryService, StackingLineSeriesService],
standalone: true,
selector: 'app-container',
template: `<ejs-chart id="chart-container" (pointRender)='pointRender($event)' [primaryXAxis]='primaryXAxis' [primaryYAxis]='primaryYAxis'>
<e-series-collection>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y' name='John' [marker]='marker'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y1' name='Peter' [marker]='marker'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y2' name='Steve' [marker]='marker'></e-series>
<e-series [dataSource]='chartData' type='StackingLine' xName='x' yName='y3' name='Charle' [marker]='marker'></e-series>
</e-series-collection>
</ejs-chart>`
})
export class AppComponent implements OnInit {
public primaryXAxis?: Object;
public primaryYAxis?: Object;
public marker?: Object;
public chartData?: Object[];
ngOnInit(): void {
this.primaryXAxis = {
interval: 1,
valueType: 'Category'
};
this.primaryYAxis = {
title: 'Expense',
interval: 100,
labelFormat: '${value}'
};
this.chartData = chartData;
this.marker = { visible: true };
}
public pointRender(args: IPointRenderEventArgs): void {
args.fill = '#009cb8';
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));export let chartData: Object[] = [
{ x: 'Food', y: 90, y1: 40, y2: 70, y3: 120 },
{ x: 'Transport', y: 80, y1: 90, y2: 110, y3: 70 },
{ x: 'Medical', y: 50, y1: 80, y2: 120, y3: 50 },
{ x: 'Clothes', y: 70, y1: 30, y2: 60, y3: 180 },
{ x: 'Personal Care', y: 30, y1: 80, y2: 80, y3: 30 },
{ x: 'Books', y: 10, y1: 40, y2: 30, y3: 270 },
{ x: 'Fitness', y: 100, y1: 30, y2: 70, y3: 40 },
{ x: 'Electricity', y: 55, y1: 95, y2: 55, y3: 75 },
{ x: 'Tax', y: 20, y1: 50, y2: 40, y3: 65 },
{ x: 'Pet Care', y: 40, y1: 20, y2: 80, y3: 95 },
{ x: 'Education', y: 45, y1: 15, y2: 45, y3: 195 },
{ x: 'Entertainment', y: 75, y1: 45, y2: 65, y3: 115 }
];Troubleshooting
-
The stack does not appear: Confirm that
StackingLineSeriesServiceis registered, every series usestypeStackingLine(orStackingLine100), and thatxName/yNamemap to valid fields. -
Stack labels do not appear: Confirm that
DataLabelServiceis registered and thatstackLabels.visibleis set totrue. -
An empty point is missing: Review
emptyPointSettings.modeand verify that the mapped value isnullorundefined(not0or''). -
The
widthproperty has no effect: Confirm that you are settingwidthon the<e-series>directive and not onborder.width.