diff --git a/npm/ng-packs/packages/components/chart.js/src/chart.component.html b/npm/ng-packs/packages/components/chart.js/src/chart.component.html deleted file mode 100644 index 211614c90d..0000000000 --- a/npm/ng-packs/packages/components/chart.js/src/chart.component.html +++ /dev/null @@ -1,11 +0,0 @@ -
- -
diff --git a/npm/ng-packs/packages/components/chart.js/src/chart.component.ts b/npm/ng-packs/packages/components/chart.js/src/chart.component.ts index 499b0b5e33..abf9cae4e5 100644 --- a/npm/ng-packs/packages/components/chart.js/src/chart.component.ts +++ b/npm/ng-packs/packages/components/chart.js/src/chart.component.ts @@ -1,24 +1,42 @@ import { AfterViewInit, + ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, Input, + OnChanges, OnDestroy, - Output + Output, + SimpleChanges } from '@angular/core'; -import { BehaviorSubject } from 'rxjs'; -import { chartJsLoaded$ } from './widget-utils'; -declare const Chart: any; + +let Chart: any; @Component({ selector: 'abp-chart', - templateUrl: './chart.component.html', + template: ` +
+ +
+ `, + changeDetection: ChangeDetectionStrategy.OnPush, + exportAs: 'abpChart', }) -export class ChartComponent implements AfterViewInit, OnDestroy { +export class ChartComponent implements AfterViewInit, OnDestroy, OnChanges { @Input() type: string; + @Input() data: any = {}; + @Input() options: any = {}; @Input() plugins: any[] = []; @@ -29,68 +47,43 @@ export class ChartComponent implements AfterViewInit, OnDestroy { @Input() responsive = true; - // eslint-disable-next-line @angular-eslint/no-output-on-prefix - @Output() readonly onDataSelect: EventEmitter = new EventEmitter(); - - @Output() readonly initialized = new BehaviorSubject(this); + @Output() dataSelect = new EventEmitter(); - private _initialized: boolean; + initialized: boolean - _data: any; chart: any; - constructor(public el: ElementRef, private cdRef: ChangeDetectorRef) {} - - @Input() get data(): any { - return this._data; - } - - set data(val: any) { - this._data = val; - this.reinit(); - } - - get canvas() { - return this.el.nativeElement.children[0].children[0]; - } - - get base64Image() { - return this.chart.toBase64Image(); - } + constructor(public el: ElementRef, private cdr: ChangeDetectorRef) {} ngAfterViewInit() { - chartJsLoaded$.subscribe(() => { - this.testChartJs(); - + import('chart.js/auto').then(module => { + Chart = module.default; this.initChart(); - this._initialized = true; + this.initialized = true; }); } - testChartJs() { - try { - Chart; - } catch (error) { - throw new Error(`Chart is not found. Import the Chart from app.module like shown below: - import('chart.js'); - `); - } - } - - onCanvasClick = event => { + onCanvasClick(event) { if (this.chart) { - const element = this.chart.getElementAtEvent(event); - const dataset = this.chart.getDatasetAtEvent(event); - if (element && element.length && dataset) { - this.onDataSelect.emit({ - originalEvent: event, - element: element[0], - dataset, - }); + const element = this.chart.getElementsAtEventForMode( + event, + 'nearest', + { intersect: true }, + false, + ); + const dataset = this.chart.getElementsAtEventForMode( + event, + 'dataset', + { intersect: true }, + false, + ); + + if (element && element[0] && dataset) { + this.dataSelect.emit({ originalEvent: event, element: element[0], dataset: dataset }); } } - }; + } initChart = () => { const opts = this.options || {}; @@ -101,15 +94,20 @@ export class ChartComponent implements AfterViewInit, OnDestroy { opts.maintainAspectRatio = false; } - this.chart = new Chart(this.canvas, { - type: this.type, + this.chart = new Chart(this.el.nativeElement.children[0].children[0], { + type: this.type as any, data: this.data, options: this.options, - plugins: this.plugins, }); + } - this.cdRef.detectChanges(); - }; + getCanvas = () => { + return this.el.nativeElement.children[0].children[0]; + } + + getBase64Image = () => { + return this.chart.toBase64Image(); + } generateLegend = () => { if (this.chart) { @@ -120,22 +118,28 @@ export class ChartComponent implements AfterViewInit, OnDestroy { refresh = () => { if (this.chart) { this.chart.update(); - this.cdRef.detectChanges(); + this.cdr.detectChanges(); } }; reinit = () => { - if (this.chart) { + if (!this.chart) return; this.chart.destroy(); this.initChart(); - } }; ngOnDestroy() { if (this.chart) { this.chart.destroy(); - this._initialized = false; + this.initialized = false; this.chart = null; } } + + ngOnChanges(changes: SimpleChanges) { + if (changes.data?.currentValue || changes.options?.currentValue) { + this.chart.destroy(); + this.initChart(); + } + } } diff --git a/npm/ng-packs/packages/components/chart.js/src/chart.module.ts b/npm/ng-packs/packages/components/chart.js/src/chart.module.ts index 47e422174c..58a0ccc84f 100644 --- a/npm/ng-packs/packages/components/chart.js/src/chart.module.ts +++ b/npm/ng-packs/packages/components/chart.js/src/chart.module.ts @@ -1,11 +1,12 @@ +import { CommonModule } from '@angular/common'; import { APP_INITIALIZER, Injector, ModuleWithProviders, NgModule } from '@angular/core'; import { ChartComponent } from './chart.component'; declare const Chart: any @NgModule({ - imports: [], - exports: [], + imports: [CommonModule], + exports: [ChartComponent], declarations: [ChartComponent], providers: [], })