Bubble Chart in Angular Charts
Bubble
A bubble series renders data as bubbles whose size is proportional to a third value (the z-value), with the position determined by the x and y values.

Configure a bubble series as follows:
-
Set the series type: Set the series
typetoBubble. -
Register the service: Register
BubbleSeriesServicein the moduleprovidersarray, or inApplicationConfig.providersfor standalone applications. Confirm thatChartModuleis imported. -
Map the data fields: Bind the data with
dataSource, and map the x, y, and bubble-size fields withxName,yName, andsize.
import { ChartModule, BubbleSeriesService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { bubbleData } from './datasource';
@Component({
imports: [ChartModule],
providers: [BubbleSeriesService],
standalone: true,
selector: 'app-container',
template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [primaryYAxis]='primaryYAxis' [title]='title'>
<e-series-collection>
<e-series [dataSource]='data' type='Bubble' xName='x' yName='y' size='size' name='pound'></e-series>
</e-series-collection>
</ejs-chart>`
})
export class AppComponent implements OnInit {
public title?: string;
public data?: Object[];
public primaryXAxis?: Object;
public primaryYAxis?: Object;
ngOnInit(): void {
this.primaryXAxis = {
title: 'Literacy Rate',
minimum: 60,
maximum: 100,
interval: 5
};
this.primaryYAxis = {
title: 'GDP Growth Rate',
minimum: 0,
maximum: 16,
interval: 2
};
this.data = bubbleData;
this.title = 'GDP vs Literacy Rate';
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));export let bubbleData: Object[] = [
{ x: 92.2, y: 7.8, size: 1.347, text: 'China' },
{ x: 74, y: 6.5, size: 1.241, text: 'India' },
{ x: 90.4, y: 6.0, size: 0.238, text: 'Indonesia' },
{ x: 99.4, y: 2.2, size: 0.312, text: 'US' },
{ x: 88.6, y: 1.3, size: 0.197, text: 'Brazil' },
{ x: 99, y: 0.7, size: 0.0818, text: 'Germany' },
{ x: 72, y: 2.0, size: 0.0826, text: 'Egypt' },
{ x: 99.6, y: 3.4, size: 0.143, text: 'Russia' },
{ x: 99, y: 0.2, size: 0.128, text: 'Japan' },
{ x: 86.1, y: 4.0, size: 0.115, text: 'Mexico' },
{ x: 92.6, y: 6.6, size: 0.096, text: 'Philippines' },
{ x: 61.3, y: 14.5, size: 0.162, text: 'Nigeria' }];Series customization
Customize a bubble series using the following properties.
Fill
Use the fill property to set a single solid bubble color. Accepted values are CSS color names (for example, blue), hexadecimal strings (for example, #1A75FF), and rgba(...) strings.
import { ChartModule, BubbleSeriesService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { bubbleData } from './datasource';
@Component({
imports: [ChartModule],
providers: [BubbleSeriesService],
standalone: true,
selector: 'app-container',
template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [primaryYAxis]='primaryYAxis' [title]='title'>
<e-series-collection>
<e-series [dataSource]='data' type='Bubble' xName='x' yName='y' size='size' name='pound' fill='blue'></e-series>
</e-series-collection>
</ejs-chart>`
})
export class AppComponent implements OnInit {
public title?: string;
public data?: Object[];
public primaryXAxis?: Object;
public primaryYAxis?: Object;
ngOnInit(): void {
this.primaryXAxis = {
title: 'Literacy Rate',
minimum: 60,
maximum: 100,
interval: 5
};
this.primaryYAxis = {
title: 'GDP Growth Rate',
minimum: 0,
maximum: 16,
interval: 2
};
this.data = bubbleData;
this.title = 'GDP vs Literacy Rate';
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));export let bubbleData: Object[] = [
{ x: 92.2, y: 7.8, size: 1.347, text: 'China' },
{ x: 74, y: 6.5, size: 1.241, text: 'India' },
{ x: 90.4, y: 6.0, size: 0.238, text: 'Indonesia' },
{ x: 99.4, y: 2.2, size: 0.312, text: 'US' },
{ x: 88.6, y: 1.3, size: 0.197, text: 'Brazil' },
{ x: 99, y: 0.7, size: 0.0818, text: 'Germany' },
{ x: 72, y: 2.0, size: 0.0826, text: 'Egypt' },
{ x: 99.6, y: 3.4, size: 0.143, text: 'Russia' },
{ x: 99, y: 0.2, size: 0.128, text: 'Japan' },
{ x: 86.1, y: 4.0, size: 0.115, text: 'Mexico' },
{ x: 92.6, y: 6.6, size: 0.096, text: 'Philippines' },
{ x: 61.3, y: 14.5, size: 0.162, text: 'Nigeria' }];Opacity
Use the opacity property to control bubble transparency. Set a value from 0 (fully transparent) to 1 (fully opaque).
import { ChartModule, BubbleSeriesService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { bubbleData } from './datasource';
@Component({
imports: [ChartModule],
providers: [BubbleSeriesService],
standalone: true,
selector: 'app-container',
template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [primaryYAxis]='primaryYAxis' [title]='title'>
<e-series-collection>
<e-series [dataSource]='data' type='Bubble' xName='x' yName='y' size='size' name='pound' opacity='0.5'></e-series>
</e-series-collection>
</ejs-chart>`
})
export class AppComponent implements OnInit {
public title?: string;
public data?: Object[];
public primaryXAxis?: Object;
public primaryYAxis?: Object;
ngOnInit(): void {
this.primaryXAxis = {
title: 'Literacy Rate',
minimum: 60,
maximum: 100,
interval: 5
};
this.primaryYAxis = {
title: 'GDP Growth Rate',
minimum: 0,
maximum: 16,
interval: 2
};
this.data = bubbleData;
this.title = 'GDP vs Literacy Rate';
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));export let bubbleData: Object[] = [
{ x: 92.2, y: 7.8, size: 1.347, text: 'China' },
{ x: 74, y: 6.5, size: 1.241, text: 'India' },
{ x: 90.4, y: 6.0, size: 0.238, text: 'Indonesia' },
{ x: 99.4, y: 2.2, size: 0.312, text: 'US' },
{ x: 88.6, y: 1.3, size: 0.197, text: 'Brazil' },
{ x: 99, y: 0.7, size: 0.0818, text: 'Germany' },
{ x: 72, y: 2.0, size: 0.0826, text: 'Egypt' },
{ x: 99.6, y: 3.4, size: 0.143, text: 'Russia' },
{ x: 99, y: 0.2, size: 0.128, text: 'Japan' },
{ x: 86.1, y: 4.0, size: 0.115, text: 'Mexico' },
{ x: 92.6, y: 6.6, size: 0.096, text: 'Philippines' },
{ x: 61.3, y: 14.5, size: 0.162, text: 'Nigeria' }];Size mapping
Use the size property to map each bubble radius to a numeric value from the data source.
import { ChartModule, BubbleSeriesService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { bubbleData } from './datasource';
@Component({
imports: [ChartModule],
providers: [BubbleSeriesService],
standalone: true,
selector: 'app-container',
template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [primaryYAxis]='primaryYAxis' [title]='title'>
<e-series-collection>
<e-series [dataSource]='data' type='Bubble' xName='x' yName='y' size='size' name='pound'></e-series>
</e-series-collection>
</ejs-chart>`
})
export class AppComponent implements OnInit {
public title?: string;
public data?: Object[];
public primaryXAxis?: Object;
public primaryYAxis?: Object;
ngOnInit(): void {
this.primaryXAxis = {
title: 'Literacy Rate',
minimum: 60,
maximum: 100,
interval: 5
};
this.primaryYAxis = {
title: 'GDP Growth Rate',
minimum: 0,
maximum: 16,
interval: 2
};
this.data = bubbleData;
this.title = 'GDP vs Literacy Rate';
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));export let bubbleData: Object[] = [
{ x: 92.2, y: 7.8, size: 1.347, text: 'China' },
{ x: 74, y: 6.5, size: 1.241, text: 'India' },
{ x: 90.4, y: 6.0, size: 0.238, text: 'Indonesia' },
{ x: 99.4, y: 2.2, size: 0.312, text: 'US' },
{ x: 88.6, y: 1.3, size: 0.197, text: 'Brazil' },
{ x: 99, y: 0.7, size: 0.0818, text: 'Germany' },
{ x: 72, y: 2.0, size: 0.0826, text: 'Egypt' },
{ x: 99.6, y: 3.4, size: 0.143, text: 'Russia' },
{ x: 99, y: 0.2, size: 0.128, text: 'Japan' },
{ x: 86.1, y: 4.0, size: 0.115, text: 'Mexico' },
{ x: 92.6, y: 6.6, size: 0.096, text: 'Philippines' },
{ x: 61.3, y: 14.5, size: 0.162, text: 'Nigeria' }];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 |
Skip the empty point; subsequent bubbles are still rendered. |
Zero |
Treat the empty point as 0 and render the bubble at the origin. |
Drop |
Drop the empty bubble; subsequent points are still rendered. |
Average |
Replace the empty value with the average of the surrounding points. |
import { ChartModule, BubbleSeriesService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { bubbleData } from './datasource';
@Component({
imports: [ChartModule],
providers: [BubbleSeriesService],
standalone: true,
selector: 'app-container',
template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [primaryYAxis]='primaryYAxis' [title]='title'>
<e-series-collection>
<e-series [dataSource]='data' type='Bubble' xName='x' yName='y' size='size' name='pound' [emptyPointSettings]='emptyPointSettings'></e-series>
</e-series-collection>
</ejs-chart>`
})
export class AppComponent implements OnInit {
public title?: string;
public data?: Object[];
public emptyPointSettings?: Object;
public primaryXAxis?: Object;
public primaryYAxis?: Object;
ngOnInit(): void {
this.primaryXAxis = {
title: 'Literacy Rate',
minimum: 60,
maximum: 100,
interval: 5
};
this.primaryYAxis = {
title: 'GDP Growth Rate',
minimum: 0,
maximum: 16,
interval: 2
};
this.data = bubbleData;
this.emptyPointSettings = {
mode: 'Zero'
};
this.title = 'GDP vs Literacy Rate';
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));export let bubbleData: Object[] = [
{ x: 92.2, y: 7.8, size: 1.347 },
{ x: 74, y: 6.5, size: 1.241 },
{ x: 90.4, y: null, size: 0.238 },
{ x: 99.4, y: 2.2, size: 0.312 },
{ x: 88.6, y: 1.3, size: 0.197 },
{ x: 99, y: 0.7, size: 0.0818 },
{ x: 72, y: 2.0, size: 0.0826 },
{ x: 99.6, y: 3.4, size: 0.143 },
{ x: 99, y: undefined, size: 0.128 },
{ x: 86.1, y: 4.0, size: 0.115 },
{ x: 92.6, y: 6.6, size: 0.096 },
{ x: 61.3, y: 14.5, size: 0.162 }
];Empty-point fill
Use the emptyPointSettings.fill property to customize the fill color of empty-point bubbles.
import { ChartModule, BubbleSeriesService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { bubbleData } from './datasource';
@Component({
imports: [ChartModule],
providers: [BubbleSeriesService],
standalone: true,
selector: 'app-container',
template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [primaryYAxis]='primaryYAxis' [title]='title'>
<e-series-collection>
<e-series [dataSource]='data' type='Bubble' xName='x' yName='y' size='size' name='pound' [emptyPointSettings]='emptyPointSettings'></e-series>
</e-series-collection>
</ejs-chart>`
})
export class AppComponent implements OnInit {
public title?: string;
public data?: Object[];
public emptyPointSettings?: Object;
public primaryXAxis?: Object;
public primaryYAxis?: Object;
ngOnInit(): void {
this.primaryXAxis = {
title: 'Literacy Rate',
minimum: 60,
maximum: 100,
interval: 5
};
this.primaryYAxis = {
title: 'GDP Growth Rate',
minimum: 0,
maximum: 16,
interval: 2
};
this.data = bubbleData;
this.emptyPointSettings = {
mode: 'Average',
fill: 'red'
};
this.title = 'GDP vs Literacy Rate';
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));export let bubbleData: Object[] = [
{ x: 92.2, y: 7.8, size: 1.347 },
{ x: 74, y: 6.5, size: 1.241 },
{ x: 90.4, y: null, size: 0.238 },
{ x: 99.4, y: 2.2, size: 0.312 },
{ x: 88.6, y: 1.3, size: 0.197 },
{ x: 99, y: 0.7, size: 0.0818 },
{ x: 72, y: 2.0, size: 0.0826 },
{ x: 99.6, y: 3.4, size: 0.143 },
{ x: 99, y: undefined, size: 0.128 },
{ x: 86.1, y: 4.0, size: 0.115 },
{ x: 92.6, y: 6.6, size: 0.096 },
{ x: 61.3, y: 14.5, size: 0.162 }
];Empty-point border
Use the emptyPointSettings.border property to customize the width and color of an empty-point bubble’s stroke.
import { ChartModule, BubbleSeriesService } from '@syncfusion/ej2-angular-charts';
import { Component, OnInit } from '@angular/core';
import { bubbleData } from './datasource';
@Component({
imports: [ChartModule],
providers: [BubbleSeriesService],
standalone: true,
selector: 'app-container',
template: `<ejs-chart id="chart-container" [primaryXAxis]='primaryXAxis' [primaryYAxis]='primaryYAxis' [title]='title'>
<e-series-collection>
<e-series [dataSource]='data' type='Bubble' xName='x' yName='y' size='size' name='pound' [emptyPointSettings]='emptyPointSettings'></e-series>
</e-series-collection>
</ejs-chart>`
})
export class AppComponent implements OnInit {
public title?: string;
public data?: Object[];
public emptyPointSettings?: Object;
public primaryXAxis?: Object;
public primaryYAxis?: Object;
ngOnInit(): void {
this.primaryXAxis = {
title: 'Literacy Rate',
minimum: 60,
maximum: 100,
interval: 5
};
this.primaryYAxis = {
title: 'GDP Growth Rate',
minimum: 0,
maximum: 16,
interval: 2
};
this.data = bubbleData;
this.emptyPointSettings = {
mode: 'Zero',
fill: 'red',
border: { width: 2, color: 'green' }
};
this.title = 'GDP vs Literacy Rate';
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));export let bubbleData: Object[] = [
{ x: 92.2, y: 7.8, size: 1.347 },
{ x: 74, y: 6.5, size: 1.241 },
{ x: 90.4, y: null, size: 0.238 },
{ x: 99.4, y: 2.2, size: 0.312 },
{ x: 88.6, y: 1.3, size: 0.197 },
{ x: 99, y: 0.7, size: 0.0818 },
{ x: 72, y: 2.0, size: 0.0826 },
{ x: 99.6, y: 3.4, size: 0.143 },
{ x: 99, y: undefined, size: 0.128 },
{ x: 86.1, y: 4.0, size: 0.115 },
{ x: 92.6, y: 6.6, size: 0.096 },
{ x: 61.3, y: 14.5, size: 0.162 }
];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, BubbleSeriesService } from '@syncfusion/ej2-angular-charts';
import { ISeriesRenderEventArgs } from '@syncfusion/ej2-charts';
import { Component, OnInit } from '@angular/core';
import { bubbleData } from './datasource';
@Component({
imports: [ChartModule],
providers: [BubbleSeriesService],
standalone: true,
selector: 'app-container',
template: `<ejs-chart id="chart-container" (seriesRender)='seriesRender($event)' [primaryXAxis]='primaryXAxis' [primaryYAxis]='primaryYAxis' [title]='title'>
<e-series-collection>
<e-series [dataSource]='data' type='Bubble' xName='x' yName='y' size='size' name='pound'></e-series>
</e-series-collection>
</ejs-chart>`
})
export class AppComponent implements OnInit {
public title?: string;
public data?: Object[];
public primaryXAxis?: Object;
public primaryYAxis?: Object;
ngOnInit(): void {
this.primaryXAxis = {
title: 'Literacy Rate',
minimum: 60,
maximum: 100,
interval: 5
};
this.primaryYAxis = {
title: 'GDP Growth Rate',
minimum: 0,
maximum: 16,
interval: 2
};
this.data = bubbleData;
this.title = 'GDP vs Literacy Rate';
}
public seriesRender(args: ISeriesRenderEventArgs): void {
args.fill = '#ff6347';
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));export let bubbleData: Object[] = [
{ x: 92.2, y: 7.8, size: 1.347, text: 'China' },
{ x: 74, y: 6.5, size: 1.241, text: 'India' },
{ x: 90.4, y: 6.0, size: 0.238, text: 'Indonesia' },
{ x: 99.4, y: 2.2, size: 0.312, text: 'US' },
{ x: 88.6, y: 1.3, size: 0.197, text: 'Brazil' },
{ x: 99, y: 0.7, size: 0.0818, text: 'Germany' },
{ x: 72, y: 2.0, size: 0.0826, text: 'Egypt' },
{ x: 99.6, y: 3.4, size: 0.143, text: 'Russia' },
{ x: 99, y: 0.2, size: 0.128, text: 'Japan' },
{ x: 86.1, y: 4.0, size: 0.115, text: 'Mexico' },
{ x: 92.6, y: 6.6, size: 0.096, text: 'Philippines' },
{ x: 61.3, y: 14.5, size: 0.162, text: 'Nigeria' }];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, BubbleSeriesService } from '@syncfusion/ej2-angular-charts';
import { IPointRenderEventArgs } from '@syncfusion/ej2-charts';
import { Component, OnInit } from '@angular/core';
import { bubbleData } from './datasource';
@Component({
imports: [ChartModule],
providers: [BubbleSeriesService],
standalone: true,
selector: 'app-container',
template: `<ejs-chart id="chart-container" (pointRender)='pointRender($event)' [primaryXAxis]='primaryXAxis' [primaryYAxis]='primaryYAxis' [title]='title'>
<e-series-collection>
<e-series [dataSource]='data' type='Bubble' xName='x' yName='y' size='size' name='pound'></e-series>
</e-series-collection>
</ejs-chart>`
})
export class AppComponent implements OnInit {
public title?: string;
public data?: Object[];
public primaryXAxis?: Object;
public primaryYAxis?: Object;
ngOnInit(): void {
this.primaryXAxis = {
title: 'Literacy Rate',
minimum: 60,
maximum: 100,
interval: 5
};
this.primaryYAxis = {
title: 'GDP Growth Rate',
minimum: 0,
maximum: 16,
interval: 2
};
this.data = bubbleData;
this.title = 'GDP vs Literacy Rate';
}
public pointRender(args: IPointRenderEventArgs): void {
if (args.point.maximum < 38) {
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 bubbleData: Object[] = [
{ x: 92.2, y: 7.8, size: 1.347, text: 'China' },
{ x: 74, y: 6.5, size: 1.241, text: 'India' },
{ x: 90.4, y: 6.0, size: 0.238, text: 'Indonesia' },
{ x: 99.4, y: 2.2, size: 0.312, text: 'US' },
{ x: 88.6, y: 1.3, size: 0.197, text: 'Brazil' },
{ x: 99, y: 0.7, size: 0.0818, text: 'Germany' },
{ x: 72, y: 2.0, size: 0.0826, text: 'Egypt' },
{ x: 99.6, y: 3.4, size: 0.143, text: 'Russia' },
{ x: 99, y: 0.2, size: 0.128, text: 'Japan' },
{ x: 86.1, y: 4.0, size: 0.115, text: 'Mexico' },
{ x: 92.6, y: 6.6, size: 0.096, text: 'Philippines' },
{ x: 61.3, y: 14.5, size: 0.162, text: 'Nigeria' }];Troubleshooting
The following symptoms map to the most common configuration issues.
-
Bubbles are not rendered: Confirm that
BubbleSeriesServiceis registered, the seriestypeisBubble, and thatxName,yName, andsizemap to numeric fields in the data source. -
All bubbles are the same size: The
sizefield is missing or non-numeric. Verify the data type and clamp values. -
An empty point renders as a zero-radius bubble: Review
emptyPointSettings.mode. UseGapto skip rendering orDropto keep subsequent bubbles. -
pointRenderdoes not fire: Confirm you bind the event on the<ejs-chart>element with(pointRender)="...", not on the series.