This demo uses imperative chart updates. The generated code is a faithful Angular translation: open it in CodeSandbox to run and tweak.
import { Component, AfterViewInit, OnDestroy, ViewChild } from '@angular/core';
import {
ChartComponent,
ApexAxisChartSeries,
ApexNonAxisChartSeries,
ApexChart,
ApexXAxis,
ApexYAxis,
ApexTitleSubtitle,
ApexDataLabels,
ApexStroke,
ApexFill,
ApexLegend,
ApexTooltip,
ApexMarkers,
ApexPlotOptions,
ApexResponsive,
ApexGrid,
ApexAnnotations,
ApexStates,
ApexTheme,
NgApexchartsModule,
} from 'ng-apexcharts';
export type ChartOptions = {
series?: ApexAxisChartSeries | ApexNonAxisChartSeries;
chart?: ApexChart;
xaxis?: ApexXAxis;
yaxis?: ApexYAxis | ApexYAxis[];
title?: ApexTitleSubtitle;
subtitle?: ApexTitleSubtitle;
dataLabels?: ApexDataLabels;
stroke?: ApexStroke;
fill?: ApexFill;
legend?: ApexLegend;
tooltip?: ApexTooltip;
markers?: ApexMarkers;
plotOptions?: ApexPlotOptions;
responsive?: ApexResponsive[];
grid?: ApexGrid;
annotations?: ApexAnnotations;
states?: ApexStates;
theme?: ApexTheme;
colors?: string[];
labels?: any;
};
@Component({
selector: 'app-chart',
standalone: true,
imports: [NgApexchartsModule],
templateUrl: './chart.component.html',
})
export class AppChart implements AfterViewInit, OnDestroy {
@ViewChild('chart') chart!: ChartComponent;
private sectorColors: any = ['#1565C0', '#2E7D32', '#C62828', '#EF6C00', '#6A1B9A'];
private bluePalette: any = ['#0D47A1', '#1976D2', '#42A5F5', '#90CAF9'];
private cyanPalette: any = ['#006064', '#00838F', '#00ACC1', '#4DD0E1'];
private greenPalette: any = ['#1B5E20', '#388E3C', '#66BB6A'];
private redPalette: any = ['#B71C1C', '#E53935', '#EF9A9A'];
private amberPalette: any = ['#E65100', '#FB8C00', '#FFB74D'];
private purplePalette: any = ['#4A148C', '#8E24AA', '#CE93D8'];
private distributed: any = { treemap: { distributed: true, enableShades: false } };
public chartOptions: Partial<ChartOptions> = {
series: [
{
data: [
{ x: 'Technology', y: 620, drilldown: 'tech' },
{ x: 'Financials', y: 430, drilldown: 'fin' },
{ x: 'Healthcare', y: 380, drilldown: 'health' },
{ x: 'Energy', y: 290, drilldown: 'energy' },
{ x: 'Consumer', y: 340, drilldown: 'consumer' },
],
},
],
chart: {
type: 'treemap',
height: 450,
toolbar: {
show: false,
},
},
legend: {
show: false,
},
colors: this.sectorColors,
plotOptions: this.distributed,
dataLabels: {
enabled: true,
style: {
fontSize: '14px',
},
},
title: {
text: 'Market Capitalisation by Sector',
align: 'left',
},
subtitle: {
text: 'Click a sector to drill into its industries, then into companies. Use the breadcrumb to go back.',
align: 'left',
},
drilldown: {
enabled: true,
breadcrumb: {
show: true,
position: 'top-right',
rootLabel: 'All Sectors',
separator: ' / ',
},
series: [
{
id: 'tech',
name: 'Technology',
colors: this.bluePalette,
plotOptions: this.distributed,
data: [
{ x: 'Cloud', y: 260, drilldown: 'tech-cloud' },
{ x: 'Devices', y: 190 },
{ x: 'Software', y: 120 },
{ x: 'Semiconductors', y: 50 },
],
},
{
id: 'tech-cloud',
name: 'Cloud',
colors: this.cyanPalette,
plotOptions: this.distributed,
data: [
{ x: 'Compute', y: 110 },
{ x: 'Storage', y: 80 },
{ x: 'Networking', y: 45 },
{ x: 'Analytics', y: 25 },
],
},
{
id: 'fin',
name: 'Financials',
colors: this.greenPalette,
plotOptions: this.distributed,
data: [
{ x: 'Banking', y: 210 },
{ x: 'Insurance', y: 140 },
{ x: 'Payments', y: 80 },
],
},
{
id: 'health',
name: 'Healthcare',
colors: this.redPalette,
plotOptions: this.distributed,
data: [
{ x: 'Pharma', y: 200 },
{ x: 'Devices', y: 110 },
{ x: 'Services', y: 70 },
],
},
{
id: 'energy',
name: 'Energy',
colors: this.amberPalette,
plotOptions: this.distributed,
data: [
{ x: 'Renewables', y: 160 },
{ x: 'Oil & Gas', y: 90 },
{ x: 'Utilities', y: 40 },
],
},
{
id: 'consumer',
name: 'Consumer',
colors: this.purplePalette,
plotOptions: this.distributed,
data: [
{ x: 'Retail', y: 180 },
{ x: 'Food & Beverage', y: 100 },
{ x: 'Apparel', y: 60 },
],
},
],
},
};
ngAfterViewInit() {
(window as any).ApexCharts.setLicense('APEX-eyJpc3N1ZURhdGUiOiIyMDI2LTA0LTE2IiwiZXhwaXJ5RGF0ZSI6IjIwNTItMDQtMTciLCJwbGFuIjoiZW50ZXJwcmlzZSIsImRvbWFpbnMiOlsiYXBleGNoYXJ0cy5jb20iLCIxMjcuMC4wLjEiXX0=');
}
ngOnDestroy() {
// no cleanup needed
}
}