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 PAW: any = 'M 26 71 A 24 21 0 1 1 74 71 A 24 21 0 1 1 26 71 Z ' +
'M 10 48 A 9.5 12 -35 1 1 27 36 A 9.5 12 -35 1 1 10 48 Z ' +
'M 29 33 A 10 12.5 -12 1 1 48 29 A 10 12.5 -12 1 1 29 33 Z ' +
'M 52 29 A 10 12.5 12 1 1 71 33 A 10 12.5 12 1 1 52 29 Z ' +
'M 73 36 A 9.5 12 35 1 1 90 48 A 9.5 12 35 1 1 73 36 Z';
private paw: any = ApexUnitShapes.shapeFrom(this.PAW, {
name: 'paw',
// The count below which the toes stop reading as toes. Ask for fewer and the
// chart says so in the console rather than drawing mush.
minUnits: 180,
});
private ridge: any = ApexUnitShapes.strokeFrom(
'M 6 76 L 24 44 L 40 60 L 58 22 L 74 46 L 94 30',
{
name: 'ridge',
width: 12,
order: 'cols',
},
);
private sunflower = (objects: any, rect: any): any => {
var cx = rect.x + rect.width / 2
var cy = rect.y + rect.height / 2
var span = Math.min(rect.width, rect.height) / 2 - 6
var golden = Math.PI * (3 - Math.sqrt(5))
return objects.map(function (o, i) {
var t = Math.sqrt((i + 0.5) / objects.length)
var angle = i * golden
return {
id: o.id,
x: cx + Math.cos(angle) * span * t,
y: cy + Math.sin(angle) * span * t,
}
})
};
public chartOptions: Partial<ChartOptions> = {
series: [1840, 1260, 220, 140],
chart: {
type: 'unit',
height: 430,
animations: {
enabled: true,
speed: 900,
},
},
labels: ['Dogs', 'Cats', 'Rabbits', 'Others'],
colors: ['#008FFB', '#00A96E', '#C98A00', '#E8264F'],
plotOptions: {
unit: {
layout: 'custom',
// Defined in the head script from path data, not imported from the catalog.
positions: this.paw,
transition: 'flow',
unitValue: 5,
clusterLabels: {
show: false,
},
},
},
legend: {
position: 'bottom',
},
};
public chartOptions2: Partial<ChartOptions> = {
series: [4200, 6800, 3100, 900],
chart: {
type: 'unit',
height: 380,
animations: {
enabled: true,
speed: 900,
},
},
labels: ['Spring', 'Summer', 'Autumn', 'Winter'],
colors: ['#00A96E', '#7CB342', '#C98A00', '#0EB8C4'],
plotOptions: {
unit: {
layout: 'custom',
// A centreline plus a width, also from the head script.
positions: this.ridge,
transition: 'flow',
unitValue: 24,
clusterLabels: {
show: false,
},
},
},
legend: {
position: 'bottom',
},
};
public chartOptions3: Partial<ChartOptions> = {
series: [520, 300, 120, 60],
chart: {
type: 'unit',
height: 430,
animations: {
enabled: true,
speed: 900,
},
},
labels: ['Weekend', 'Day pass', 'Camping', 'Crew'],
colors: ['#008FFB', '#00A96E', '#C98A00', '#E8264F'],
plotOptions: {
unit: {
layout: 'custom',
// A function, not a shape object: this chart imports nothing from the kit.
positions: this.sunflower,
transition: 'flow',
clusterLabels: {
show: false,
},
},
},
legend: {
position: 'bottom',
},
};
ngAfterViewInit() {
(window as any).ApexCharts.setLicense('APEX-eyJleHBpcnlEYXRlIjoiMjEyNi0wNy0wNCIsImlzc3VlRGF0ZSI6IjIwMjYtMDctMjgiLCJwbGFuIjoicHJlbWl1bSIsImRvbWFpbnMiOlsiYXBleGNoYXJ0cy5jb20iLCIxMjcuMC4wLjEiLCJsb2NhbGhvc3QiXSwic2lnIjoieVBmb1VCc0Z3TU9ZdUEyaEZkR0I2Y1FtZ0JITUtXcVdJSjB2NVRESXRZbFR3eDJMUmh6R2x0RUc3VXJ4X0s3b25ZMWRZb2Z2VGItN01ydFYyNDVyOWcifQ==');
}
ngOnDestroy() {
// no cleanup needed
}
}