Stacked Bar Chart in Angular Charts

28 Aug 202624 minutes to read

Stacked Bar

A stacked bar chart displays horizontal bars divided into segments that represent different series. It helps compare totals while showing the contribution of each series.

Stack bar chart showing data trends over time

Configure a stacked bar chart as follows:

  1. Set the series type: Set the series type to StackingBar.
  2. Register the required services: Import and add StackingBarSeriesService and the required axis services, such as CategoryService, to the component or NgModule providers array.

Use Angular and @syncfusion/ej2-angular-charts versions that satisfy the package peer dependencies. Review the package release notes and peer dependencies before upgrading.

import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { StackingBarSeriesService, CategoryService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { stackedData } from './datasource';
@Component({
imports: [
         ChartModule
    ],

providers: [StackingBarSeriesService, CategoryService],
standalone: true,
    selector: 'app-container',
    template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [title]='title'>
        <e-series-collection>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y' name='Apple'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y1' name='Orange'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y2' name='Wastage'></e-series>
        </e-series-collection>
    </ejs-chart>`
})
export class AppComponent implements OnInit {
    public primaryXAxis?: Object;
    public chartData?: Object[];
    public title?: string;
    ngOnInit(): void {
        this.chartData = stackedData;
        this.primaryXAxis = {
            valueType: 'Category',
            title: 'Months'
        };
        this.title = 'Sales Comparison';
    }

}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
export let stackedData: Object[] = [
        { x: 'Jan', y: 6,  y1: 6,  y2: -1 },
        { x: 'Feb', y: 8 , y1: 8,  y2: -1.5 },
        { x: 'Mar', y: 12, y1: 11, y2: -2 },
        { x: 'Apr', y: 15, y1: 16, y2: -2.5 },
        { x: 'May', y: 20, y1: 21, y2: -3 },
        { x: 'Jun', y: 24, y1: 25, y2: -3.5 },
        { x: 'Jul', y: 28, y1: 27, y2: -4 },
        { x: 'Aug', y: 32, y1: 31, y2: -4.5 },
        { x: 'Sep', y: 33, y1: 34, y2: -5 },
        { x: 'Oct', y: 35, y1: 34, y2: -5.5 },
        { x: 'Nov', y: 40, y1: 41, y2: -6 },
        { x: 'Dec', y: 42, y1: 42, y2: -6.5 }
    ];

Binding data to a series

Bind an array of JSON objects or a DataManager instance to the series with the dataSource property. Map the category field with xName and map a value field for each series with yName.

import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { StackingBarSeriesService, CategoryService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { stackedData } from './datasource';
@Component({
imports: [
         ChartModule
    ],

providers: [StackingBarSeriesService, CategoryService],
standalone: true,
    selector: 'app-container',
    template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [title]='title'>
        <e-series-collection>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y' name='Apple'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y1' name='Orange'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y2' name='Wastage'></e-series>
        </e-series-collection>
    </ejs-chart>`
})
export class AppComponent implements OnInit {
    public primaryXAxis?: Object;
    public chartData?: Object[];
    public title?: string;
    ngOnInit(): void {
        this.chartData = stackedData;
        this.primaryXAxis = {
            valueType: 'Category',
            title: 'Months'
        };
        this.title = 'Sales Comparison';
    }

}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
export let stackedData: Object[] = [
        { x: 'Jan', y: 6,  y1: 6,  y2: -1 },
        { x: 'Feb', y: 8 , y1: 8,  y2: -1.5 },
        { x: 'Mar', y: 12, y1: 11, y2: -2 },
        { x: 'Apr', y: 15, y1: 16, y2: -2.5 },
        { x: 'May', y: 20, y1: 21, y2: -3 },
        { x: 'Jun', y: 24, y1: 25, y2: -3.5 },
        { x: 'Jul', y: 28, y1: 27, y2: -4 },
        { x: 'Aug', y: 32, y1: 31, y2: -4.5 },
        { x: 'Sep', y: 33, y1: 34, y2: -5 },
        { x: 'Oct', y: 35, y1: 34, y2: -5.5 },
        { x: 'Nov', y: 40, y1: 41, y2: -6 },
        { x: 'Dec', y: 42, y1: 42, y2: -6.5 }
    ];

Series customization

Use the following properties to customize the appearance of a stacked bar series.

Solid fill

Use the fill property to set a solid CSS color for a series.

import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { StackingBarSeriesService, CategoryService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { stackedData } from './datasource';
@Component({
imports: [
         ChartModule
    ],

providers: [StackingBarSeriesService, CategoryService],
standalone: true,
    selector: 'app-container',
    template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [title]='title'>
        <e-series-collection>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y' name='Apple' fill='yellow'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y1' name='Orange' fill='green'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y2' name='Wastage' fill='blue'></e-series>
        </e-series-collection>
    </ejs-chart>`
})
export class AppComponent implements OnInit {
    public primaryXAxis?: Object;
    public chartData?: Object[];
    public title?: string;
    ngOnInit(): void {
        this.chartData = stackedData;
        this.primaryXAxis = {
            valueType: 'Category',
            title: 'Months'
        };
        this.title = 'Sales Comparison';
    }

}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
export let stackedData: Object[] = [
        { x: 'Jan', y: 6,  y1: 6,  y2: -1 },
        { x: 'Feb', y: 8 , y1: 8,  y2: -1.5 },
        { x: 'Mar', y: 12, y1: 11, y2: -2 },
        { x: 'Apr', y: 15, y1: 16, y2: -2.5 },
        { x: 'May', y: 20, y1: 21, y2: -3 },
        { x: 'Jun', y: 24, y1: 25, y2: -3.5 },
        { x: 'Jul', y: 28, y1: 27, y2: -4 },
        { x: 'Aug', y: 32, y1: 31, y2: -4.5 },
        { x: 'Sep', y: 33, y1: 34, y2: -5 },
        { x: 'Oct', y: 35, y1: 34, y2: -5.5 },
        { x: 'Nov', y: 40, y1: 41, y2: -6 },
        { x: 'Dec', y: 42, y1: 42, y2: -6.5 }
    ];

Gradient fill

The fill property can apply an SVG gradient to a stacked bar series. Define each gradient in an SVG <defs> element with a unique ID, and assign it to the series in the url(#gradientId) format.

Place the SVG gradient definitions in the application’s index.html file, inside the <body> element and outside the <app-container> element.

<svg>
    <defs>
        <linearGradient id="gradient1">
            <stop offset="0%" style="stop-color:blue;stop-opacity:5" />
            <stop offset="50%" style="stop-color:violet;stop-opacity:5" />
        </linearGradient>
    </defs>
</svg>
<svg>
    <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>
    <defs>
        <linearGradient id="gradient3">
            <stop offset="0%" style="stop-color:darkgreen;stop-opacity:5" />
            <stop offset="50%" style="stop-color:darkslateblue;stop-opacity:5" />
        </linearGradient>
    </defs>
</svg>

Set the series fill values to url(#gradient1), url(#gradient2), and url(#gradient3) respectively.

import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { StackingBarSeriesService, CategoryService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { stackedData } from './datasource';
@Component({
imports: [
         ChartModule
    ],

providers: [StackingBarSeriesService, CategoryService],
standalone: true,
    selector: 'app-container',
    template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [title]='title'>
        <e-series-collection>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y' name='Apple' fill='url(#gradient1)'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y1' name='Orange' fill='url(#gradient2)'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y2' name='Wastage' fill='url(#gradient3)'></e-series>
        </e-series-collection>
    </ejs-chart>`
})
export class AppComponent implements OnInit {
    public primaryXAxis?: Object;
    public chartData?: Object[];
    public title?: string;
    ngOnInit(): void {
        this.chartData = stackedData;
        this.primaryXAxis = {
            valueType: 'Category',
            title: 'Months'
        };
        this.title = 'Sales Comparison';
    }

}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
export let stackedData: Object[] = [
        { x: 'Jan', y: 6,  y1: 6,  y2: -1 },
        { x: 'Feb', y: 8 , y1: 8,  y2: -1.5 },
        { x: 'Mar', y: 12, y1: 11, y2: -2 },
        { x: 'Apr', y: 15, y1: 16, y2: -2.5 },
        { x: 'May', y: 20, y1: 21, y2: -3 },
        { x: 'Jun', y: 24, y1: 25, y2: -3.5 },
        { x: 'Jul', y: 28, y1: 27, y2: -4 },
        { x: 'Aug', y: 32, y1: 31, y2: -4.5 },
        { x: 'Sep', y: 33, y1: 34, y2: -5 },
        { x: 'Oct', y: 35, y1: 34, y2: -5.5 },
        { x: 'Nov', y: 40, y1: 41, y2: -6 },
        { x: 'Dec', y: 42, y1: 42, y2: -6.5 }
    ];

Opacity

Use the opacity property to control series transparency. Set a value from 0 for fully transparent to 1 for fully opaque.

import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { StackingBarSeriesService, CategoryService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { stackedData } from './datasource';
@Component({
imports: [
         ChartModule
    ],

providers: [StackingBarSeriesService, CategoryService],
standalone: true,
    selector: 'app-container',
    template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [title]='title'>
        <e-series-collection>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y' name='Apple' opacity='0.7'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y1' name='Orange' opacity='0.7'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y2' name='Wastage' opacity='0.7'></e-series>
        </e-series-collection>
    </ejs-chart>`
})
export class AppComponent implements OnInit {
    public primaryXAxis?: Object;
    public chartData?: Object[];
    public title?: string;
    ngOnInit(): void {
        this.chartData = stackedData;
        this.primaryXAxis = {
            valueType: 'Category',
            title: 'Months'
        };
        this.title = 'Sales Comparison';
    }

}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
export let stackedData: Object[] = [
        { x: 'Jan', y: 6,  y1: 6,  y2: -1 },
        { x: 'Feb', y: 8 , y1: 8,  y2: -1.5 },
        { x: 'Mar', y: 12, y1: 11, y2: -2 },
        { x: 'Apr', y: 15, y1: 16, y2: -2.5 },
        { x: 'May', y: 20, y1: 21, y2: -3 },
        { x: 'Jun', y: 24, y1: 25, y2: -3.5 },
        { x: 'Jul', y: 28, y1: 27, y2: -4 },
        { x: 'Aug', y: 32, y1: 31, y2: -4.5 },
        { x: 'Sep', y: 33, y1: 34, y2: -5 },
        { x: 'Oct', y: 35, y1: 34, y2: -5.5 },
        { x: 'Nov', y: 40, y1: 41, y2: -6 },
        { x: 'Dec', y: 42, y1: 42, y2: -6.5 }
    ];

Border

Use the border property to customize the color and width of the series border.

import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { StackingBarSeriesService, CategoryService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { stackedData } from './datasource';
@Component({
imports: [
         ChartModule
    ],

providers: [StackingBarSeriesService, CategoryService],
standalone: true,
    selector: 'app-container',
    template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [title]='title'>
        <e-series-collection>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y' name='Apple' [border]='border'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y1' name='Orange' [border]='border1'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y2' name='Wastage' [border]='border2'></e-series>
        </e-series-collection>
    </ejs-chart>`
})
export class AppComponent implements OnInit {
    public primaryXAxis?: Object;
    public chartData?: Object[];
    public border?: Object;
    public border2?: Object;
    public border1?: Object;
    public title?: string;
    ngOnInit(): void {
        this.chartData = stackedData;
        this.primaryXAxis = {
            valueType: 'Category',
            title: 'Months'
        };
        this.border = { width: 2, color: '#ff4251', dashArray: '2,5' };
        this.border1 = { width: 2, color: '#4C4C4C', dashArray: '2,5' };
        this.border2 = { width: 2, color: '#794F1B', dashArray: '2,5' };
        this.title = 'Sales Comparison';
    }

}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
export let stackedData: Object[] = [
        { x: 'Jan', y: 6,  y1: 6,  y2: -1 },
        { x: 'Feb', y: 8 , y1: 8,  y2: -1.5 },
        { x: 'Mar', y: 12, y1: 11, y2: -2 },
        { x: 'Apr', y: 15, y1: 16, y2: -2.5 },
        { x: 'May', y: 20, y1: 21, y2: -3 },
        { x: 'Jun', y: 24, y1: 25, y2: -3.5 },
        { x: 'Jul', y: 28, y1: 27, y2: -4 },
        { x: 'Aug', y: 32, y1: 31, y2: -4.5 },
        { x: 'Sep', y: 33, y1: 34, y2: -5 },
        { x: 'Oct', y: 35, y1: 34, y2: -5.5 },
        { x: 'Nov', y: 40, y1: 41, y2: -6 },
        { x: 'Dec', y: 42, y1: 42, y2: -6.5 }
    ];

Empty points

A data point whose mapped value is null or undefined is considered empty. Configure empty-point behavior with emptyPointSettings.mode. The default mode is Gap; use another supported mode when the chart must display a replacement value instead of a gap.

Mode

Use mode to control how the series handles an empty point. The supported modes are:

  • Gap: Leaves a gap at the empty point. This is the default mode.
  • Zero: Replaces the missing value with zero.
  • Average: Replaces the missing value with an average derived from neighboring points.
  • Drop: Omits the empty point from rendering.
import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { StackingBarSeriesService, CategoryService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { stackedData } from './datasource';
@Component({
imports: [
         ChartModule
    ],

providers: [StackingBarSeriesService, CategoryService],
standalone: true,
    selector: 'app-container',
    template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [title]='title'>
        <e-series-collection>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y' name='Apple' [emptyPointSettings]='emptyPointSettings'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y1' name='Orange' [emptyPointSettings]='emptyPointSettings1'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y2' name='Wastage' [emptyPointSettings]='emptyPointSettings2'></e-series>
        </e-series-collection>
    </ejs-chart>`
})
export class AppComponent implements OnInit {
    public primaryXAxis?: Object;
    public chartData?: Object[];
    public border?: Object;
    public border2?: Object;
    public border1?: Object;
    public title?: string;
    public emptyPointSettings?: Object;
    public emptyPointSettings1?: Object;
    public emptyPointSettings2?: Object;
    ngOnInit(): void {
        this.chartData = stackedData;
        this.primaryXAxis = {
            valueType: 'Category',
            title: 'Months'
        };
        this.title = 'Sales Comparison';
        this.emptyPointSettings = {
            mode: 'Zero'
        };
        this.emptyPointSettings1 = {
            mode: 'Gap'
        };
        this.emptyPointSettings2 = {
            mode: 'Average'
        };
    }

}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
export let stackedData: object[] = [
    { x: 2000, y: 0.61, y1: 0.03, y2: 0.48},
    { x: 2001, y: 0.81, y1: 0.05, y2: 0.53 },
    { x: 2002, y: 0.91, y1: 0.06, y2: null },
    { x: 2003, y: 1,    y1: 0.09, y2: 0.61 },
    { x: 2004, y: 1.19, y1: 0.14, y2: 0.63 },
    { x: 2005, y: 1.47, y1: undefined, y2: 0.64 },
    { x: 2006, y: 1.74, y1: 0.29, y2: 0.66 },
    { x: 2007, y: null, y1: 0.46, y2: 0.76 },
    { x: 2008, y: 1.99, y1: 0.64, y2: 0.77 },
    { x: 2009, y: 1.70, y1: 0.75, y2: 0.55 }
];

Empty-point fill

Use emptyPointSettings.fill to set the fill color of an empty point when the selected mode renders a replacement point. It has no visible effect when the empty point is rendered as a gap.

import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { StackingBarSeriesService, CategoryService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { stackedData } from './datasource';
@Component({
imports: [
         ChartModule
    ],

providers: [StackingBarSeriesService, CategoryService],
standalone: true,
    selector: 'app-container',
    template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [title]='title'>
        <e-series-collection>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y' name='Apple' [emptyPointSettings]='emptyPointSettings'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y1' name='Orange' [emptyPointSettings]='emptyPointSettings1'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y2' name='Wastage' [emptyPointSettings]='emptyPointSettings2'></e-series>
        </e-series-collection>
    </ejs-chart>`
})
export class AppComponent implements OnInit {
    public primaryXAxis?: Object;
    public chartData?: Object[];
    public border?: Object;
    public border2?: Object;
    public border1?: Object;
    public title?: string;
    public emptyPointSettings?: Object;
    public emptyPointSettings1?: Object;
    public emptyPointSettings2?: Object;
    ngOnInit(): void {
        this.chartData = stackedData;
        this.primaryXAxis = {
            valueType: 'Category',
            title: 'Months'
        };
        this.title = 'Sales Comparison';
        this.emptyPointSettings = {
            mode: 'Zero'
        };
        this.emptyPointSettings1 = {
            mode: 'Gap'
        };
        this.emptyPointSettings2 = {
            mode: 'Average',
            fill: 'red'
        };
    }

}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
export let stackedData: object[] = [
    { x: 2000, y: 0.61, y1: 0.03, y2: 0.48},
    { x: 2001, y: 0.81, y1: 0.05, y2: 0.53 },
    { x: 2002, y: 0.91, y1: 0.06, y2: null },
    { x: 2003, y: 1,    y1: 0.09, y2: 0.61 },
    { x: 2004, y: 1.19, y1: 0.14, y2: 0.63 },
    { x: 2005, y: 1.47, y1: undefined, y2: 0.64 },
    { x: 2006, y: 1.74, y1: 0.29, y2: 0.66 },
    { x: 2007, y: null, y1: 0.46, y2: 0.76 },
    { x: 2008, y: 1.99, y1: 0.64, y2: 0.77 },
    { x: 2009, y: 1.70, y1: 0.75, y2: 0.55 }
];

Empty-point border

Use emptyPointSettings.border to set the width and color of an empty point’s border when the selected mode renders a replacement point.

import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { StackingBarSeriesService, CategoryService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { stackedData } from './datasource';
@Component({
imports: [
         ChartModule
    ],

providers: [StackingBarSeriesService, CategoryService],
standalone: true,
    selector: 'app-container',
    template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [title]='title'>
        <e-series-collection>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y' name='Apple' [emptyPointSettings]='emptyPointSettings'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y1' name='Orange' [emptyPointSettings]='emptyPointSettings1'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y2' name='Wastage' [emptyPointSettings]='emptyPointSettings2'></e-series>
        </e-series-collection>
    </ejs-chart>`
})
export class AppComponent implements OnInit {
    public primaryXAxis?: Object;
    public chartData?: Object[];
    public border?: Object;
    public border2?: Object;
    public border1?: Object;
    public title?: string;
    public emptyPointSettings?: Object;
    public emptyPointSettings1?: Object;
    public emptyPointSettings2?: Object;
    ngOnInit(): void {
        this.chartData = stackedData;
        this.primaryXAxis = {
            valueType: 'Category',
            title: 'Months'
        };
        this.title = 'Sales Comparison';
        this.emptyPointSettings = {
            mode: 'Zero'
        };
        this.emptyPointSettings1 = {
            mode: 'Gap'
        };
        this.emptyPointSettings2 = {
            mode: 'Average',
            fill: 'red',
            border: { width: 2, color: 'green' }
        };
    }

}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
export let stackedData: object[] = [
    { x: 2000, y: 0.61, y1: 0.03, y2: 0.48},
    { x: 2001, y: 0.81, y1: 0.05, y2: 0.53 },
    { x: 2002, y: 0.91, y1: 0.06, y2: null },
    { x: 2003, y: 1,    y1: 0.09, y2: 0.61 },
    { x: 2004, y: 1.19, y1: 0.14, y2: 0.63 },
    { x: 2005, y: 1.47, y1: undefined, y2: 0.64 },
    { x: 2006, y: 1.74, y1: 0.29, y2: 0.66 },
    { x: 2007, y: null, y1: 0.46, y2: 0.76 },
    { x: 2008, y: 1.99, y1: 0.64, y2: 0.77 },
    { x: 2009, y: 1.70, y1: 0.75, y2: 0.55 }
];

Stacking group

Use stackingGroup to organize stacked bar and 100% stacked bar series into separate stacks. Series with the same group name are stacked together; series with different group names form separate stacks.

import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { StackingBarSeriesService, CategoryService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { stackedData } from './datasource';
@Component({
imports: [
         ChartModule
    ],

providers: [StackingBarSeriesService, CategoryService],
standalone: true,
    selector: 'app-container',
    template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [title]='title'>
        <e-series-collection>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y' stackingGroup='JohnAndAndrew'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y1' stackingGroup='JohnAndAndrew'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y2'  stackingGroup='ThomasAndMichael'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y2'  stackingGroup='ThomasAndMichael'></e-series>
        </e-series-collection>
    </ejs-chart>`
})
export class AppComponent implements OnInit {
    public primaryXAxis?: Object;
    public chartData?: Object[];
    public title?: string;
    ngOnInit(): void {
        this.chartData = stackedData;
        this.primaryXAxis = {
            valueType: 'Category',
            title: 'Months'
        };
        this.title = 'Sales by year';
    }

}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
export let stackedData: Object[] = [
    { x: 2007, y: 453, y1: 876, y2: 356, y3: 122 },
    { x: 2008, y: 354, y1: 564, y2: 876, y3: 444 },
    { x: 2009, y: 282, y1: 242, y2: 898, y3: 222 },
    { x: 2010, y: 321, y1: 121, y2: 567, y3: 231 },
    { x: 2011, y: 333, y1: 343, y2: 456, y3: 122 },
    { x: 2012, y: 351, y1: 451, y2: 345, y3: 333 },
    { x: 2013, y: 403, y1: 203, y2: 543, y3: 354 },
    { x: 2014, y: 421, y1: 431, y2: 654, y3: 100 }
];

Cylindrical stacked bar chart

Set the columnFacet property to Cylinder to render a stacked bar series with a cylindrical shape. The default value is Rectangle.

import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { StackingBarSeriesService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { stackedData } from './datasource';
@Component({
imports: [
         ChartModule
    ],

providers: [StackingBarSeriesService],
standalone: true,
    selector: 'app-container',
    template: `<ejs-chart id="chart-container">
        <e-series-collection>
            <e-series [dataSource]='chartData' type='StackingBar' columnFacet= 'Cylinder' xName='x' yName='y'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' columnFacet= 'Cylinder' xName='x' yName='y1'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' columnFacet= 'Cylinder' xName='x' yName='y2'></e-series>
        </e-series-collection>
    </ejs-chart>`
})
export class AppComponent implements OnInit {
    public chartData?: Object[];
    ngOnInit(): void {
        this.chartData = stackedData;
    }

}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
export let stackedData: Object[] = [
        { x: 2000, y: 0.61, y1: 0.03, y2: 0.48},
        { x: 2001, y: 0.81, y1: 0.05, y2: 0.53 },
        { x: 2002, y: 0.91, y1: 0.06, y2: 0.57 },
        { x: 2003, y: 1, y1: 0.09, y2: 0.61 },
        { x: 2004, y: 1.19, y1: 0.14, y2: 0.63 },
        { x: 2005, y: 1.47, y1: 0.20, y2: 0.64 },
        { x: 2006, y: 1.74, y1: 0.29, y2: 0.66 },
        { x: 2007, y: 1.98, y1: 0.46, y2: 0.76 },
        { x: 2008, y: 1.99, y1: 0.64, y2: 0.77 },
        { x: 2009, y: 1.70, y1: 0.75, y2: 0.55 }
    ];

Stack labels

Stack labels display the total value for each stack. Enable them by setting stackLabelSettings.visible to true in the chart configuration. For negative stacks, the label is positioned relative to the negative stack.

import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { StackingBarSeriesService, CategoryService, DataLabelService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { stackedData } from './datasource';
@Component({
imports: [
         ChartModule
    ],

providers: [ StackingBarSeriesService, CategoryService, DataLabelService],
standalone: true,
    selector: 'app-container',
    template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [title]='title' [stackLabels]='stackLabels'>
        <e-series-collection>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y' name='Apple' [marker]='marker'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y1' name='Orange' [marker]='marker'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y2' name='Wastage' [marker]='marker'></e-series>
        </e-series-collection>
    </ejs-chart>`
})
export class AppComponent implements OnInit {
    public primaryXAxis?: Object;
    public chartData?: Object[];
    public title?: string;
    public marker?: Object;
    public stackLabels?:Object;
    ngOnInit(): void {
        this.chartData = stackedData;
        this.primaryXAxis = {
            valueType: 'Category',
            title: 'Months'
        };
        this.marker = { dataLabel: { visible: true } };
        this.stackLabels = { visible: true };
        this.title = 'Sales Comparison';
    }

}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
export let stackedData: Object[] = [
        { x: 'Jan', y: 6,  y1: 6,  y2: -1 },
        { x: 'Feb', y: 8 , y1: 8,  y2: -1.5 },
        { x: 'Mar', y: 12, y1: 11, y2: -2 },
        { x: 'Apr', y: 15, y1: 16, y2: -2.5 },
        { x: 'May', y: 20, y1: 21, y2: -3 },
        { x: 'Jun', y: 24, y1: 25, y2: -3.5 },
        { x: 'Jul', y: 28, y1: 27, y2: -4 },
        { x: 'Aug', y: 32, y1: 31, y2: -4.5 },
        { x: 'Sep', y: 33, y1: 34, y2: -5 },
        { x: 'Oct', y: 35, y1: 34, y2: -5.5 },
        { x: 'Nov', y: 40, y1: 41, y2: -6 },
        { x: 'Dec', y: 42, y1: 42, y2: -6.5 }
    ];

Stack label customization

Use the following stackLabelSettings properties to customize stack labels:

  • visible: Displays stack labels when set to true. The default is false.
  • fill: Sets the label background using a valid CSS color. The default is transparent.
  • format: Formats label text and supports placeholders such as {value} for the total stack value. The default is null.
  • angle: Sets the rotation angle in degrees. The default is 0.
  • rx: Sets the horizontal corner radius of the label background. The default is 5.
  • ry: Sets the vertical corner radius of the label background. The default is 5.
  • margin: Sets the spacing around the label.
  • border: Sets the label border. Configure its width and color for rounded corners to be visible.
  • font: Customizes the label text size, color, style, weight, and family.
import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { StackingBarSeriesService, CategoryService, DataLabelService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { stackedData } from './datasource';
@Component({
imports: [
         ChartModule
    ],

providers: [ StackingBarSeriesService, CategoryService, DataLabelService],
standalone: true,
    selector: 'app-container',
    template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [title]='title' [stackLabels]='stackLabels'>
        <e-series-collection>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y' name='Apple' [marker]='marker'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y1' name='Orange' [marker]='marker'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y2' name='Wastage' [marker]='marker'></e-series>
        </e-series-collection>
    </ejs-chart>`
})
export class AppComponent implements OnInit {
    public primaryXAxis?: Object;
    public chartData?: Object[];
    public title?: string;
    public marker?: Object;
    public stackLabels?:Object;
    ngOnInit(): void {
        this.chartData = stackedData;
        this.primaryXAxis = {
            valueType: 'Category',
            title: 'Months'
        };
        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.title = 'Sales Comparison';
    }

}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
export let stackedData: Object[] = [
        { x: 'Jan', y: 6,  y1: 6,  y2: -1 },
        { x: 'Feb', y: 8 , y1: 8,  y2: -1.5 },
        { x: 'Mar', y: 12, y1: 11, y2: -2 },
        { x: 'Apr', y: 15, y1: 16, y2: -2.5 },
        { x: 'May', y: 20, y1: 21, y2: -3 },
        { x: 'Jun', y: 24, y1: 25, y2: -3.5 },
        { x: 'Jul', y: 28, y1: 27, y2: -4 },
        { x: 'Aug', y: 32, y1: 31, y2: -4.5 },
        { x: 'Sep', y: 33, y1: 34, y2: -5 },
        { x: 'Oct', y: 35, y1: 34, y2: -5.5 },
        { x: 'Nov', y: 40, y1: 41, y2: -6 },
        { x: 'Dec', y: 42, y1: 42, y2: -6.5 }
    ];

Corner radius

Series corner radius

Use cornerRadius to round the corners of all points in the stacked bar series. Configure individual corners with topLeft, topRight, bottomLeft, and bottomRight.

import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { IPointRenderEventArgs } from '@syncfusion/ej2-charts';
import { StackingBarSeriesService, CategoryService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { stackedData } from './datasource';
@Component({
imports: [
         ChartModule
    ],

providers: [StackingBarSeriesService, CategoryService],
standalone: true,
    selector: 'app-container',
    template: `<ejs-chart id="chart-container" (pointRender)='pointRender($event)' [primaryXAxis]='primaryXAxis' [title]='title'>
        <e-series-collection>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y' name='Apple'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y1' name='Orange' [cornerRadius]='cornerRadius'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y2' name='Wastage' [cornerRadius]='cornerRadius'></e-series>
        </e-series-collection>
    </ejs-chart>`
})
export class AppComponent implements OnInit {
    public primaryXAxis?: Object;
    public chartData?: Object[];
    public title?: string;
    public cornerRadius?: object;
    ngOnInit(): void {
        this.chartData = stackedData;
        this.primaryXAxis = {
            valueType: 'Category',
            title: 'Months'
        };
        this.cornerRadius = { topRight: 10, bottomRight: 10 };
        this.title = 'Sales by year';
    }
    public pointRender(args: IPointRenderEventArgs) {
        if (args.point.index % 2 !== 0) {
            args.fill = '#ff6347';
        }
        else {
            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 stackedData: Object[] = [
    { x: 2007, y: 453, y1: 876, y2: 356, y3: 122 },
    { x: 2008, y: 354, y1: 564, y2: 876, y3: 444 },
    { x: 2009, y: 282, y1: 242, y2: 898, y3: 222 },
    { x: 2010, y: 321, y1: 121, y2: 567, y3: 231 },
    { x: 2011, y: 333, y1: 343, y2: 456, y3: 122 },
    { x: 2012, y: 351, y1: 451, y2: 345, y3: 333 },
    { x: 2013, y: 403, y1: 203, y2: 543, y3: 354 },
    { x: 2014, y: 421, y1: 431, y2: 654, y3: 100 }
];

Point corner radius

Handle the pointRender event and set the event argument’s cornerRadius property to customize an individual point before it is rendered.

import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { IPointRenderEventArgs } from '@syncfusion/ej2-charts';
import { StackingBarSeriesService, CategoryService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { stackedData } from './datasource';
@Component({
imports: [
         ChartModule
    ],

providers: [StackingBarSeriesService, CategoryService],
standalone: true,
    selector: 'app-container',
    template: `<ejs-chart id="chart-container" (pointRender)='pointRender($event)' [primaryXAxis]='primaryXAxis' [title]='title'>
        <e-series-collection>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y' name='Apple'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y1' name='Orange'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y2' name='Wastage'></e-series>
        </e-series-collection>
    </ejs-chart>`
})
export class AppComponent implements OnInit {
    public primaryXAxis?: Object;
    public chartData?: Object[];
    public title?: string;
    ngOnInit(): void {
        this.chartData = stackedData;
        this.primaryXAxis = {
            valueType: 'Category',
            title: 'Months'
        };
        this.title = 'Sales by year';
    }
    public pointRender(args: IPointRenderEventArgs) {
        if (args.point.index === 1 && args.point.series.index === 1) {
            args.cornerRadius = { topLeft: 0, bottomLeft: 0, topRight: 10, bottomRight: 10 };
        }
        if (args.point.index === 4 && args.point.series.index === 1) {
            args.cornerRadius = { topLeft: 0, bottomLeft: 0, topRight: 10, bottomRight: 10 };
        }
        if (args.point.index === 6 && args.point.series.index === 1) {
            args.cornerRadius = { topLeft: 0, bottomLeft: 0, topRight: 10, bottomRight: 10 };
        }
        if (args.point.index === 8 && args.point.series.index === 1) {
            args.cornerRadius = { topLeft: 0, bottomLeft: 0, topRight: 10, bottomRight: 10 };
        }
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
export let stackedData: Object[] = [
    { x: 2007, y: 453, y1: 876, y2: 356, y3: 122 },
    { x: 2008, y: 354, y1: 564, y2: 876, y3: 444 },
    { x: 2009, y: 282, y1: 242, y2: 898, y3: 222 },
    { x: 2010, y: 321, y1: 121, y2: 567, y3: 231 },
    { x: 2011, y: 333, y1: 343, y2: 456, y3: 122 },
    { x: 2012, y: 351, y1: 451, y2: 345, y3: 333 },
    { x: 2013, y: 403, y1: 203, y2: 543, y3: 354 },
    { x: 2014, y: 421, y1: 431, y2: 654, y3: 100 }
];

Events

Series render

The seriesRender event runs before a series is rendered. Use its event arguments to customize supported series properties such as data, fill, and name.

import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { ISeriesRenderEventArgs } from '@syncfusion/ej2-charts';
import { StackingBarSeriesService, CategoryService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { stackedData } from './datasource';
@Component({
imports: [
         ChartModule
    ],

providers: [StackingBarSeriesService, CategoryService],
standalone: true,
    selector: 'app-container',
    template: `<ejs-chart id="chart-container" (seriesRender)='seriesRender($event)' [primaryXAxis]='primaryXAxis' [title]='title'>
        <e-series-collection>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y' name='Apple'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y1' name='Orange'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y2' name='Wastage'></e-series>
        </e-series-collection>
    </ejs-chart>`
})
export class AppComponent implements OnInit {
    public primaryXAxis?: Object;
    public chartData?: Object[];
    public title?: string;
    ngOnInit(): void {
        this.chartData = stackedData;
        this.primaryXAxis = {
            valueType: 'Category',
            title: 'Months'
        };
        this.title = 'Sales by year';
    }
    public seriesRender(args: ISeriesRenderEventArgs) {
        if (args.series.index === 0) {
            args.fill = '#ff4251';
        }
        else if (args.series.index === 1) {
            args.fill = '#4C4C4C';
        }
        else if (args.series.index === 2) {
            args.fill = '#794F1B';
        }
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));
export let stackedData: Object[] = [
    { x: 2007, y: 453, y1: 876, y2: 356, y3: 122 },
    { x: 2008, y: 354, y1: 564, y2: 876, y3: 444 },
    { x: 2009, y: 282, y1: 242, y2: 898, y3: 222 },
    { x: 2010, y: 321, y1: 121, y2: 567, y3: 231 },
    { x: 2011, y: 333, y1: 343, y2: 456, y3: 122 },
    { x: 2012, y: 351, y1: 451, y2: 345, y3: 333 },
    { x: 2013, y: 403, y1: 203, y2: 543, y3: 354 },
    { x: 2014, y: 421, y1: 431, y2: 654, y3: 100 }
];

Point render

The pointRender event runs before each point is rendered. Use its event arguments to customize supported point properties. See Point corner radius for a per-point styling example.

import { ChartModule } from '@syncfusion/ej2-angular-charts';
import { IPointRenderEventArgs } from '@syncfusion/ej2-charts';
import { StackingBarSeriesService, CategoryService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { stackedData } from './datasource';
@Component({
imports: [
         ChartModule
    ],

providers: [StackingBarSeriesService, CategoryService],
standalone: true,
    selector: 'app-container',
    template: `<ejs-chart id="chart-container" (pointRender)='pointRender($event)' [primaryXAxis]='primaryXAxis' [title]='title'>
        <e-series-collection>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y' name='Apple'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y1' name='Orange'></e-series>
            <e-series [dataSource]='chartData' type='StackingBar' xName='x' yName='y2' name='Wastage'></e-series>
        </e-series-collection>
    </ejs-chart>`
})
export class AppComponent implements OnInit {
    public primaryXAxis?: Object;
    public chartData?: Object[];
    public title?: string;
    ngOnInit(): void {
        this.chartData = stackedData;
        this.primaryXAxis = {
            valueType: 'Category',
            title: 'Months'
        };
        this.title = 'Sales by year';
    }
    public pointRender(args: IPointRenderEventArgs) {
        if (args.point.index % 2 !== 0) {
            args.fill = '#ff6347';
        }
        else {
            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 stackedData: Object[] = [
    { x: 2007, y: 453, y1: 876, y2: 356, y3: 122 },
    { x: 2008, y: 354, y1: 564, y2: 876, y3: 444 },
    { x: 2009, y: 282, y1: 242, y2: 898, y3: 222 },
    { x: 2010, y: 321, y1: 121, y2: 567, y3: 231 },
    { x: 2011, y: 333, y1: 343, y2: 456, y3: 122 },
    { x: 2012, y: 351, y1: 451, y2: 345, y3: 333 },
    { x: 2013, y: 403, y1: 203, y2: 543, y3: 354 },
    { x: 2014, y: 421, y1: 431, y2: 654, y3: 100 }
];

Troubleshooting

  • No bars are displayed: Confirm that StackingBarSeriesService and the required axis services are registered, the series type is StackingBar, and the xName and yName fields exist in the data source.
  • Series do not stack together: Confirm that the series use the same chart type, compatible category values, and the same stackingGroup when grouping is configured.
  • A point is missing: Check whether its mapped value is null or undefined, and review emptyPointSettings.mode.
  • A gradient is not displayed: Confirm that the SVG gradient ID exists in index.html and exactly matches the ID referenced by the series fill value.

See also