Average Profit Bar Chart with One Product Line Highlighted in Angular
Using ApexCharts with Angular
This Average Profit Bar Chart with One Product Line Highlighted example wires ApexCharts into Angular through the ng-apexcharts component.
Install it with npm install ng-apexcharts apexcharts, then mount the chart with <apx-chart [series]="series" [chart]="chart"></apx-chart>.
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';
import 'apexcharts/features/highlight-filter';
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 money = (v: any): any => {
return (v < 0 ? '-$' : '$') + Math.abs(Math.round(v))
};
private STORES: any = ['Seattle', 'Denver', 'Austin', 'Chicago', 'Boston', 'Miami'];
private ALL: any = [42, -18, 31, 24, 12, -9];
private LINES: any = {
premium: [
{ x: 'Seattle', y: 42, highlight: 61 },
{ x: 'Denver', y: -18, highlight: -4 },
{ x: 'Austin', y: 31, highlight: 48 },
{ x: 'Chicago', y: 24, highlight: 19 },
{ x: 'Boston', y: 12, highlight: 27 },
{ x: 'Miami', y: -9, highlight: 6 },
],
budget: [
{ x: 'Seattle', y: 42, highlight: 18 },
{ x: 'Denver', y: -18, highlight: -26 },
{ x: 'Austin', y: 31, highlight: 12 },
{ x: 'Chicago', y: 24, highlight: 28 },
{ x: 'Boston', y: 12, highlight: -3 },
{ x: 'Miami', y: -9, highlight: -21 },
],
};
private seriesFor = (line: any): any => {
return [
{
name: 'Avg profit per order',
data: line
? this.LINES[line]
: this.STORES.map(function (s, i) {
return { x: s, y: this.ALL[i] }
}),
},
]
};
private pickLine = (chart: any, line: any): any => {
document.querySelectorAll('[data-line]').forEach(function (b) {
b.classList.toggle('active', b.getAttribute('data-line') === line)
})
return chart.updateSeries(this.seriesFor(line))
};
private wireLines = (chart: any): any => {
document.querySelectorAll('[data-line]').forEach(function (b) {
b.addEventListener('click', function () {
this.pickLine(chart, b.getAttribute('data-line'))
})
})
};
public chartOptions: Partial<ChartOptions> = {
series: this.seriesFor('premium'),
chart: {
id: 'profit',
type: 'bar',
height: 360,
toolbar: { show: false },
},
colors: ['#0d9488'],
plotOptions: {
bar: { horizontal: true, barHeight: '62%', borderRadius: 4 },
},
dataLabels: {
enabled: true,
formatter: this.money,
},
xaxis: {
labels: { formatter: this.money },
},
grid: { xaxis: { lines: { show: true } }, yaxis: { lines: { show: false } } },
tooltip: {
y: { formatter: this.money },
},
};
ngAfterViewInit() {
(window as any).ApexCharts.setLicense('APEX-eyJleHBpcnlEYXRlIjoiMjEyNi0wNy0wNCIsImlzc3VlRGF0ZSI6IjIwMjYtMDctMjgiLCJwbGFuIjoicHJlbWl1bSIsImRvbWFpbnMiOlsiYXBleGNoYXJ0cy5jb20iLCIxMjcuMC4wLjEiLCJsb2NhbGhvc3QiXSwic2lnIjoieVBmb1VCc0Z3TU9ZdUEyaEZkR0I2Y1FtZ0JITUtXcVdJSjB2NVRESXRZbFR3eDJMUmh6R2x0RUc3VXJ4X0s3b25ZMWRZb2Z2VGItN01ydFYyNDVyOWcifQ==');
this.wireLines(this.chart)
function pickLine(chart, line) {
document.querySelectorAll('[data-line]').forEach(function (b) {
b.classList.toggle('active', b.getAttribute('data-line') === line)
})
return this.chart.updateSeries(this.seriesFor(line))
}
function wireLines(chart) {
document.querySelectorAll('[data-line]').forEach(function (b) {
b.addEventListener('click', () => {
this.pickLine(chart, b.getAttribute('data-line'))
})
})
}
}
ngOnDestroy() {
// no cleanup needed
}
}