A wrapper for the Google Charts library written in Angular.
Angular Google Charts now supports Angular's modern standalone components architecture! ✨
- ✅ Angular 16-20 Compatible: Full support for Angular versions 16 through 20
- 🚀 Standalone-First: Modern development approach with better tree-shaking
- 💛 Composable: Write complicated dashboards using all the features provided by
google.charts
Angular Version | Library Version | Maintenance | Standalone Components |
---|---|---|---|
>= 16.0.0 < 21.0.0 | 16.1.x | ✅ Active Support | ✅ Available (16.1.x) |
>= 12.0.0 < 16.0.0 | 12.0.x | ❌ Not Maintained | ❌ Not Available |
npm install angular-google-charts
1. Bootstrap your app with providers:
// main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { provideGoogleCharts } from 'angular-google-charts';
import { AppComponent } from './app.component';
bootstrapApplication(AppComponent, {
providers: [provideGoogleCharts()]
});
2. Use components directly in your templates:
// app.component.ts
import { Component } from '@angular/core';
import { GoogleChart, ChartType } from 'angular-google-charts';
@Component({
selector: 'app-root',
standalone: true,
imports: [GoogleChart],
template: `
<h1>My Dashboard</h1>
<google-chart
type="PieChart"
[data]="pieChartData"
[columns]="pieChartColumns"
[options]="pieChartOptions"
[width]="500"
[height]="400"
>
</google-chart>
`
})
export class AppComponent {
pieChartData = [
['Work', 11],
['Eat', 2],
['Commute', 2],
['Watch TV', 2],
['Sleep', 7]
];
pieChartColumns = ['Task', 'Hours per Day'];
pieChartOptions = {
title: 'My Daily Activities',
pieHole: 0.4
};
}
Configure Google Charts options globally:
// main.ts
bootstrapApplication(AppComponent, {
providers: [
provideGoogleCharts({
version: '49',
mapsApiKey: 'your-api-key'
})
]
});
All components are available as standalone versions:
GoogleChart
- Main chart componentChartWrapper
- 1:1 wrapper for Google's ChartWrapperDashboard
- Dashboard container with controlsControlWrapper
- Interactive chart controlsChartEditor
- Chart editing interface
Basic Chart:
import { GoogleChart } from 'angular-google-charts';
@Component({
standalone: true,
imports: [GoogleChart],
template: `<google-chart [type]="type" [data]="data"></google-chart>`
})
Dashboard with Controls:
import { Dashboard, ControlWrapper, GoogleChart } from 'angular-google-charts';
@Component({
standalone: true,
imports: [Dashboard, ControlWrapper, GoogleChart],
template: `
<dashboard [data]="dashboardData" [columns]="dashboardColumns">
<control-wrapper [for]="myChart" type="CategoryFilter"></control-wrapper>
<google-chart #myChart type="ColumnChart"></google-chart>
</dashboard>
`
})
All Google Charts types are supported. Check the ChartType file for the complete list or visit the Google Charts Gallery.
Property | Type | Description |
---|---|---|
[type] |
ChartType |
Required. Chart type (e.g., 'PieChart', 'BarChart') |
[data] |
any[][] |
Required. Chart data as 2D array |
[columns] |
string[] | object[] |
Column definitions |
[options] |
object |
Chart-specific options |
Property | Type | Description |
---|---|---|
[title] |
string |
Chart title |
[width] |
number |
Width in pixels |
[height] |
number |
Height in pixels |
[formatters] |
Formatter[] |
Data formatters |
[dynamicResize] |
boolean |
Auto-resize on window resize |
// Simple data format
myData = [
['London', 8136000],
['New York', 8538000],
['Paris', 2244000],
['Berlin', 3470000]
];
// With custom formatting
myData = [
['London', { v: 8136000, f: '8.14M' }],
['New York', { v: 8538000, f: '8.54M' }]
];
Customize charts with Google Charts options:
myOptions = {
title: 'Population by City',
colors: ['#e0440e', '#e6693e', '#ec8f6e'],
is3D: true,
pieHole: 0.4,
legend: { position: 'bottom' }
};
All chart events are supported:
@Component({
template: `
<google-chart
(ready)="onChartReady($event)"
(select)="onChartSelect($event)"
(error)="onChartError($event)"
(mouseover)="onMouseOver($event)"
(mouseleave)="onMouseLeave($event)"
>
</google-chart>
`
})
export class MyComponent {
onChartReady(event: ChartReadyEvent) {
console.log('Chart ready:', event);
}
onChartSelect(event: ChartSelectionChangedEvent) {
console.log('Selection changed:', event.selection);
}
}
Create powerful dashboards with multiple charts and controls:
@Component({
standalone: true,
imports: [Dashboard, ControlWrapper, GoogleChart],
template: `
<dashboard [data]="salesData" [columns]="salesColumns">
<!-- Date range filter -->
<control-wrapper [for]="[salesChart, regionChart]" type="DateRangeFilter" [options]="dateFilterOptions">
</control-wrapper>
<!-- Category filter -->
<control-wrapper [for]="salesChart" type="CategoryFilter" [options]="categoryFilterOptions"> </control-wrapper>
<!-- Charts controlled by filters -->
<google-chart #salesChart type="LineChart"></google-chart>
<google-chart #regionChart type="GeoChart"></google-chart>
</dashboard>
`
})
export class SalesDashboard {
salesData = [
['Date', 'Region', 'Sales'],
[new Date(2024, 0, 1), 'North', 1000],
[new Date(2024, 0, 2), 'South', 1200]
// ... more data
];
}
Enable users to customize charts with the built-in editor:
import { Component, ViewChild } from '@angular/core';
import { ChartEditor, GoogleChart } from 'angular-google-charts';
@Component({
standalone: true,
imports: [ChartEditor, GoogleChart],
template: `
<chart-editor></chart-editor>
<google-chart #myChart [type]="chartType" [data]="chartData"></google-chart>
<button (click)="editChart()">Edit Chart</button>
`
})
export class EditableChart {
@ViewChild(ChartEditor) editor!: ChartEditor;
@ViewChild('myChart') chart!: GoogleChart;
editChart() {
this.editor
.editChart(this.chart)
.afterClosed()
.subscribe(result => {
if (result) {
console.log('Chart updated!');
}
});
}
}
For custom implementations:
import { Component, ViewChild, ElementRef, OnInit } from '@angular/core';
import { ScriptLoaderService } from 'angular-google-charts';
@Component({
standalone: true,
template: `<div #chartContainer></div>`
})
export class CustomChart implements OnInit {
@ViewChild('chartContainer', { static: true })
container!: ElementRef;
constructor(private loader: ScriptLoaderService) {}
ngOnInit() {
this.loader.loadChartPackages('corechart').subscribe(() => {
const chart = new google.visualization.PieChart(this.container.nativeElement);
chart.draw(this.createDataTable(), this.getOptions());
});
}
}
Create reusable chart components:
import { Component, Input } from '@angular/core';
import { GoogleChart } from 'angular-google-charts';
@Component({
selector: 'sales-chart',
standalone: true,
imports: [GoogleChart],
template: `
<google-chart type="ComboChart" [data]="processedData" [options]="chartOptions" [width]="width" [height]="height">
</google-chart>
`
})
export class SalesChart {
@Input() salesData: any[] = [];
@Input() width = 600;
@Input() height = 400;
get processedData() {
// Transform your data here
return this.salesData;
}
get chartOptions() {
return {
title: 'Sales Performance',
vAxes: {
0: { title: 'Revenue ($)' },
1: { title: 'Units Sold' }
},
series: {
0: { type: 'columns', targetAxisIndex: 0 },
1: { type: 'line', targetAxisIndex: 1 }
}
};
}
}
For faster initial chart rendering, add to your index.html
:
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js" async></script>
<script type="text/javascript" src="https://www.gstatic.com/charts/49/loader.js" async></script>
Load charts only when needed:
async loadChart() {
const { GoogleChart } = await import('angular-google-charts');
// Use the component dynamically
}
Still using NgModules? No problem! Your existing code continues to work:
// ✅ This still works!
@NgModule({
imports: [GoogleChartsModule.forRoot()]
})
export class AppModule {}
To migrate to standalone components:
-
Replace imports:
// Before import { GoogleChartsModule } from 'angular-google-charts'; // After import { GoogleChart, provideGoogleCharts } from 'angular-google-charts';
-
Update bootstrap:
// Before platformBrowserDynamic().bootstrapModule(AppModule); // After bootstrapApplication(AppComponent, { providers: [provideGoogleCharts()] });
-
Update components:
@Component({ standalone: true, imports: [GoogleChart], // Add specific imports // ... rest of component })
provideGoogleCharts({
version: '49', // Google Charts version
mapsApiKey: 'API_KEY', // For GeoChart and Maps
safeMode: true // Enable safe mode (Charts 47+)
});
For dynamic configuration:
// service
@Injectable({ providedIn: 'root' })
export class ConfigService {
private configSubject = new ReplaySubject<GoogleChartsConfig>(1);
config$ = this.configSubject.asObservable();
updateConfig(config: GoogleChartsConfig) {
this.configSubject.next(config);
}
}
// main.ts
bootstrapApplication(AppComponent, {
providers: [
{
provide: GOOGLE_CHARTS_LAZY_CONFIG,
useFactory: (service: ConfigService) => service.config$,
deps: [ConfigService]
}
]
});
Note: While NgModule usage is still supported, we recommend using standalone components for new projects.
Click to see NgModule documentation
import { GoogleChartsModule } from 'angular-google-charts';
@NgModule({
imports: [
GoogleChartsModule,
// or with configuration
GoogleChartsModule.forRoot({ version: '49' })
],
declarations: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule {}
GoogleChartsModule.forRoot({
version: 'chart-version',
mapsApiKey: 'your-api-key'
});
@Injectable()
export class GoogleChartsConfigService {
private configSubject = new ReplaySubject<GoogleChartsConfig>(1);
readonly config$ = this.configSubject.asObservable();
constructor(private http: HttpClient) {}
loadLazyConfigValues(): void {
this.http
.post('https://api.example.com/config', {})
.pipe(take(1))
.subscribe(config => this.configSubject.next(config));
}
}
export function googleChartsConfigFactory(configService: GoogleChartsConfigService): Observable<GoogleChartsConfig> {
return configService.config$;
}
@NgModule({
providers: [
GoogleChartsConfigService,
{
provide: GOOGLE_CHARTS_LAZY_CONFIG,
useFactory: googleChartsConfigFactory,
deps: [GoogleChartsConfigService]
}
]
})
export class AppModule {}
export const googleChartsConfigSubject = new ReplaySubject<GoogleChartsConfig>(1);
// Call this from anywhere
googleChartsConfigSubject.next(config);
@NgModule({
providers: [
{
provide: GOOGLE_CHARTS_LAZY_CONFIG,
useValue: googleChartsConfigSubject.asObservable()
}
]
})
export class AppModule {}
Important Notes:
- You can use
forRoot()
ORGOOGLE_CHARTS_LAZY_CONFIG
, not both - Lazy-loaded configs delay chart rendering until config is available
This project is provided under the MIT license.
We welcome contributions!
- 📖 Documentation
- 🐛 Issues
⭐ Like this project? Give it a star on GitHub!