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.

Stacked line chart showing cumulative trends
Configure a stacked line series as follows:

  1. Set the series type: Set the series type to StackingLine. Use StackingLine100 to render a 100% stacked line chart.
  2. Register the service: Register StackingLineSeriesService (and any required axis services) in the module providers array, or in ApplicationConfig.providers for standalone applications. Confirm that ChartModule is imported.
  3. Bind the data: Add at least two <e-series> entries that share the same type. Bind each entry to the data via dataSource, and assign a different xName / yName pair 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 StackingLineSeriesService is registered, every series uses type StackingLine (or StackingLine100), and that xName / yName map to valid fields.
  • Stack labels do not appear: Confirm that DataLabelService is registered and that stackLabels.visible is set to true.
  • An empty point is missing: Review emptyPointSettings.mode and verify that the mapped value is null or undefined (not 0 or '').
  • The width property has no effect: Confirm that you are setting width on the <e-series> directive and not on border.width.

See also