100% Stacked Line Chart in Angular Charts

100% Stacked Line

A 100% stacked line chart displays the relative percentage contribution of each series, with the total normalized to 100% at every point.

100% Stacked line chart showing data trends

To render a 100% stacked line series in your chart, you need to follow a few steps to configure it correctly.

Here’s a concise guide on how to do this:

  1. Set the series type: Set the series type to StackingLine100. The 100% stacked variant normalizes the stacked totals at each x value so that all series always sum to 100%.
  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 but use different yName values. Each wrapper series contributes one slice of the 100% total at every data point.
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='StackingLine100' xName='x' yName='y' name='John' [marker]='marker'></e-series>
            <e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y1' name='Peter' [marker]='marker'></e-series>
            <e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y2' name='Steve' [marker]='marker'></e-series>
            <e-series [dataSource]='chartData' type='StackingLine100' 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: 'Percentage',
            interval: 25,
            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 100% 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='StackingLine100' xName='x' yName='y' name='John' [marker]='marker' fill='#ff4251'></e-series>
            <e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y1' name='Peter' [marker]='marker' fill='#4C4C4C'></e-series>
            <e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y2' name='Steve' [marker]='marker' fill='#794F1B'></e-series>
            <e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y3' name='Charle' [marker]='marker' fill='#1a9a6f'></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: 'Percentage',
            interval: 25,
            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 also reference an SVG gradient. Define each gradient in an SVG <defs> element and assign it in the url(#gradientId) format.

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

  • HTML
  • <svg>
        <defs>
            <linearGradient id="gradient1">
                <stop offset="0%" style="stop-color:blue;stop-opacity:1" />
                <stop offset="50%" style="stop-color:violet;stop-opacity:1" />
            </linearGradient>
        </defs>
    </svg>
    
    <svg>
        <defs>
            <linearGradient id="gradient2">
                <stop offset="0%" style="stop-color:darkred;stop-opacity:1" />
                <stop offset="50%" style="stop-color:darkorange;stop-opacity:1" />
            </linearGradient>
        </defs>
    </svg>
    
    <svg>
        <defs>
            <linearGradient id="gradient3">
                <stop offset="0%" style="stop-color:darkmagenta;stop-opacity:1" />
                <stop offset="50%" style="stop-color:darkcyan;stop-opacity:1" />
            </linearGradient>
        </defs>
    </svg>
    
    <svg>
        <defs>
            <linearGradient id="gradient4">
                <stop offset="0%" style="stop-color:darkviolet;stop-opacity:1" />
                <stop offset="50%" style="stop-color:darkgoldenrod;stop-opacity:1" />
            </linearGradient>
        </defs>
    </svg>

    Set each series fill to url(#gradient1), url(#gradient2), … and so on.

    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='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: 'Percentage',
                interval: 25,
                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='StackingLine100' xName='x' yName='y' name='John' [marker]='marker' opacity='0.5'></e-series>
                <e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y1' name='Peter' [marker]='marker' opacity='0.5'></e-series>
                <e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y2' name='Steve' [marker]='marker' opacity='0.5'></e-series>
                <e-series [dataSource]='chartData' type='StackingLine100' 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: 'Percentage',
                interval: 25,
                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='StackingLine100' xName='x' yName='y' name='John' [marker]='marker' dashArray='2,5'></e-series>
                <e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y1' name='Peter' [marker]='marker' dashArray='2,5'></e-series>
                <e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y2' name='Steve' [marker]='marker' dashArray='2,5'></e-series>
                <e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y3' name='Charle' [marker]='marker' dashArray='2,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: 'Percentage',
                interval: 25,
                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='StackingLine100' xName='x' yName='y' name='John' [marker]='marker' width='5'></e-series>
                <e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y1' name='Peter' [marker]='marker' width='5'></e-series>
                <e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y2' name='Steve' [marker]='marker' width='5'></e-series>
                <e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y3' name='Charle' [marker]='marker' width='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: 'Percentage',
                interval: 25,
                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='StackingLine100' xName='x' yName='y' name='John' [marker]='marker' [emptyPointSettings]='emptyPointSettings'></e-series>
                <e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y1' name='Peter' [marker]='marker'></e-series>
                <e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y2' name='Steve' [marker]='marker' [emptyPointSettings]='emptyPointSettings1'></e-series>
                <e-series [dataSource]='chartData' type='StackingLine100' 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: 'Percentage',
                interval: 25,
                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='StackingLine100' xName='x' yName='y' name='John' [marker]='marker' [emptyPointSettings]='emptyPointSettings'></e-series>
                <e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y1' name='Peter' [marker]='marker'></e-series>
                <e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y2' name='Steve' [marker]='marker' [emptyPointSettings]='emptyPointSettings1'></e-series>
                <e-series [dataSource]='chartData' type='StackingLine100' 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: 'Percentage',
                interval: 25,
                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='StackingLine100' xName='x' yName='y' name='John' [marker]='marker' [emptyPointSettings]='emptyPointSettings'></e-series>
                <e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y1' name='Peter' [marker]='marker'></e-series>
                <e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y2' name='Steve' [marker]='marker' [emptyPointSettings]='emptyPointSettings1'></e-series>
                <e-series [dataSource]='chartData' type='StackingLine100' 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: 'Percentage',
                interval: 25,
                labelFormat: '{value}%'
            };
            this.chartData = chartData;
            this.marker = { visible: true };
            this.emptyPointSettings = { mode: 'Average', fill: 'red', border: { width: 1.5, color: '#0F9D58' } };
            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 }
    ];

    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='StackingLine100' xName='x' yName='y' name='John' [marker]='marker'></e-series>
                <e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y1' name='Peter' [marker]='marker'></e-series>
                <e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y2' name='Steve' [marker]='marker'></e-series>
                <e-series [dataSource]='chartData' type='StackingLine100' 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: 'Percentage',
                interval: 25,
                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='StackingLine100' xName='x' yName='y' name='John' [marker]='marker'></e-series>
                <e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y1' name='Peter' [marker]='marker'></e-series>
                <e-series [dataSource]='chartData' type='StackingLine100' xName='x' yName='y2' name='Steve' [marker]='marker'></e-series>
                <e-series [dataSource]='chartData' type='StackingLine100' 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: 'Percentage',
                interval: 25,
                labelFormat: '{value}%'
            };
            this.chartData = chartData;
            this.marker = { visible: true };
        }
    
        public pointRender(args: IPointRenderEventArgs): void {
            if (args.point.y !== undefined && args.point.y < 70) {
                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 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

    • All stacks collapse to a single value: Verify each <e-series> references a different yName. If every series uses the same field, the stack will sum to that one value rather than accumulate across series.
    • The 100% normalization is missing: Confirm that the series type is exactly StackingLine100 (not StackingLine).
    • 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