Browse Source

improve chart component

pull/10082/head
Mehmet Erim 5 years ago
parent
commit
216c4a8b8d
  1. 11
      npm/ng-packs/packages/components/chart.js/src/chart.component.html
  2. 130
      npm/ng-packs/packages/components/chart.js/src/chart.component.ts
  3. 5
      npm/ng-packs/packages/components/chart.js/src/chart.module.ts

11
npm/ng-packs/packages/components/chart.js/src/chart.component.html

@ -1,11 +0,0 @@
<div
style="position:relative"
[style.width]="responsive && !width ? null : width"
[style.height]="responsive && !height ? null : height"
>
<canvas
[attr.width]="responsive && !width ? null : width"
[attr.height]="responsive && !height ? null : height"
(click)="onCanvasClick($event)"
></canvas>
</div>

130
npm/ng-packs/packages/components/chart.js/src/chart.component.ts

@ -1,24 +1,42 @@
import { import {
AfterViewInit, AfterViewInit,
ChangeDetectionStrategy,
ChangeDetectorRef, ChangeDetectorRef,
Component, Component,
ElementRef, ElementRef,
EventEmitter, EventEmitter,
Input, Input,
OnChanges,
OnDestroy, OnDestroy,
Output Output,
SimpleChanges
} from '@angular/core'; } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { chartJsLoaded$ } from './widget-utils'; let Chart: any;
declare const Chart: any;
@Component({ @Component({
selector: 'abp-chart', selector: 'abp-chart',
templateUrl: './chart.component.html', template: `
<div
style="position:relative"
[style.width]="responsive && !width ? null : width"
[style.height]="responsive && !height ? null : height"
>
<canvas
[attr.width]="responsive && !width ? null : width"
[attr.height]="responsive && !height ? null : height"
(click)="onCanvasClick($event)"
></canvas>
</div>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
exportAs: 'abpChart',
}) })
export class ChartComponent implements AfterViewInit, OnDestroy { export class ChartComponent implements AfterViewInit, OnDestroy, OnChanges {
@Input() type: string; @Input() type: string;
@Input() data: any = {};
@Input() options: any = {}; @Input() options: any = {};
@Input() plugins: any[] = []; @Input() plugins: any[] = [];
@ -29,68 +47,43 @@ export class ChartComponent implements AfterViewInit, OnDestroy {
@Input() responsive = true; @Input() responsive = true;
// eslint-disable-next-line @angular-eslint/no-output-on-prefix @Output() dataSelect = new EventEmitter();
@Output() readonly onDataSelect: EventEmitter<any> = new EventEmitter();
@Output() readonly initialized = new BehaviorSubject(this);
private _initialized: boolean; initialized: boolean
_data: any;
chart: any; chart: any;
constructor(public el: ElementRef, private cdRef: ChangeDetectorRef) {} constructor(public el: ElementRef, private cdr: 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();
}
ngAfterViewInit() { ngAfterViewInit() {
chartJsLoaded$.subscribe(() => { import('chart.js/auto').then(module => {
this.testChartJs(); Chart = module.default;
this.initChart(); this.initChart();
this._initialized = true; this.initialized = true;
}); });
} }
testChartJs() { onCanvasClick(event) {
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 => {
if (this.chart) { if (this.chart) {
const element = this.chart.getElementAtEvent(event); const element = this.chart.getElementsAtEventForMode(
const dataset = this.chart.getDatasetAtEvent(event); event,
if (element && element.length && dataset) { 'nearest',
this.onDataSelect.emit({ { intersect: true },
originalEvent: event, false,
element: element[0], );
dataset, 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 = () => { initChart = () => {
const opts = this.options || {}; const opts = this.options || {};
@ -101,15 +94,20 @@ export class ChartComponent implements AfterViewInit, OnDestroy {
opts.maintainAspectRatio = false; opts.maintainAspectRatio = false;
} }
this.chart = new Chart(this.canvas, { this.chart = new Chart(this.el.nativeElement.children[0].children[0], {
type: this.type, type: this.type as any,
data: this.data, data: this.data,
options: this.options, options: this.options,
plugins: this.plugins,
}); });
}
this.cdRef.detectChanges(); getCanvas = () => {
}; return this.el.nativeElement.children[0].children[0];
}
getBase64Image = () => {
return this.chart.toBase64Image();
}
generateLegend = () => { generateLegend = () => {
if (this.chart) { if (this.chart) {
@ -120,22 +118,28 @@ export class ChartComponent implements AfterViewInit, OnDestroy {
refresh = () => { refresh = () => {
if (this.chart) { if (this.chart) {
this.chart.update(); this.chart.update();
this.cdRef.detectChanges(); this.cdr.detectChanges();
} }
}; };
reinit = () => { reinit = () => {
if (this.chart) { if (!this.chart) return;
this.chart.destroy(); this.chart.destroy();
this.initChart(); this.initChart();
}
}; };
ngOnDestroy() { ngOnDestroy() {
if (this.chart) { if (this.chart) {
this.chart.destroy(); this.chart.destroy();
this._initialized = false; this.initialized = false;
this.chart = null; this.chart = null;
} }
} }
ngOnChanges(changes: SimpleChanges) {
if (changes.data?.currentValue || changes.options?.currentValue) {
this.chart.destroy();
this.initChart();
}
}
} }

5
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 { APP_INITIALIZER, Injector, ModuleWithProviders, NgModule } from '@angular/core';
import { ChartComponent } from './chart.component'; import { ChartComponent } from './chart.component';
declare const Chart: any declare const Chart: any
@NgModule({ @NgModule({
imports: [], imports: [CommonModule],
exports: [], exports: [ChartComponent],
declarations: [ChartComponent], declarations: [ChartComponent],
providers: [], providers: [],
}) })

Loading…
Cancel
Save