UNPKG

ng2-charts

Version:

Reactive, responsive, beautiful charts for Angular based on Chart.js

238 lines (230 loc) 9.14 kB
import * as i0 from '@angular/core'; import { InjectionToken, Injectable, EventEmitter, inject, ElementRef, NgZone, PLATFORM_ID, Output, Input, Directive } from '@angular/core'; import { registerables, Chart, defaults } from 'chart.js'; import { merge } from 'es-toolkit'; import { isPlatformBrowser } from '@angular/common'; import { BehaviorSubject } from 'rxjs'; import { distinctUntilChanged } from 'rxjs/operators'; const NG_CHARTS_CONFIGURATION = new InjectionToken('Configuration for ngCharts'); /** * Provide all the default registerable as defined by Chart.js */ function withDefaultRegisterables(...registerables$1) { return { registerables: [...registerables, ...registerables$1] }; } /** * Provide configuration for ngCharts. In most cases, you have to pass it some registerables. So either * `withDefaultRegisterables()`, or a custom list of registerables tailored to your needs to reduce bundle size. */ function provideCharts(...configurations) { const config = configurations.reduce(merge, {}); return { provide: NG_CHARTS_CONFIGURATION, useValue: config }; } class ThemeService { constructor() { this.colorschemesOptions = new BehaviorSubject(undefined); } setColorschemesOptions(options) { this.pColorschemesOptions = options; this.colorschemesOptions.next(options); } getColorschemesOptions() { return this.pColorschemesOptions; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ThemeService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: ThemeService, decorators: [{ type: Injectable, args: [{ providedIn: 'root', }] }] }); class BaseChartDirective { constructor() { this.type = 'bar'; this.plugins = []; this.chartClick = new EventEmitter(); this.chartHover = new EventEmitter(); this.ctx = null; this.subs = []; this.themeOverrides = {}; this.element = inject(ElementRef); this.zone = inject(NgZone); this.themeService = inject(ThemeService); this.config = inject(NG_CHARTS_CONFIGURATION, { optional: true }); this.platformId = inject(PLATFORM_ID); this.isBrowser = isPlatformBrowser(this.platformId); if (this.config?.registerables) { Chart.register(...this.config.registerables); } if (this.config?.defaults) { defaults.set(this.config.defaults); } // Only get canvas context in browser environment if (this.isBrowser) { this.ctx = this.element.nativeElement.getContext('2d'); } this.subs.push(this.themeService.colorschemesOptions .pipe(distinctUntilChanged()) .subscribe((r) => this.themeChanged(r))); } ngOnChanges(changes) { if (!this.isBrowser) { return; // Skip chart operations in SSR } const requireRender = ['type']; const propertyNames = Object.getOwnPropertyNames(changes); if (propertyNames.some((key) => requireRender.includes(key)) || propertyNames.every((key) => changes[key].isFirstChange())) { this.render(); } else { // For legend changes, we need to update the chart options and re-render if (this.chart && changes['legend']) { const config = this.getChartConfiguration(); if (config.options) { this.chart.options = config.options; } this.update(); } else if (this.chart) { const config = this.getChartConfiguration(); // Using assign to avoid changing the original object reference if (config.data && this.chart.config.data) { Object.assign(this.chart.config.data, config.data); } if (config.plugins && this.chart.config.plugins) { Object.assign(this.chart.config.plugins, config.plugins); } if (config.options && this.chart.config.options) { Object.assign(this.chart.config.options, config.options); } this.update(); } } } ngOnDestroy() { if (this.chart) { this.chart.destroy(); this.chart = void 0; } this.subs.forEach((s) => s.unsubscribe()); } render() { if (!this.isBrowser || !this.ctx) { return undefined; } if (this.chart) { this.chart.destroy(); } return this.zone.runOutsideAngular(() => (this.chart = new Chart(this.ctx, this.getChartConfiguration()))); } update(mode) { if (this.chart && this.isBrowser) { this.zone.runOutsideAngular(() => this.chart?.update(mode)); } } hideDataset(index, hidden) { if (this.chart && this.isBrowser) { this.chart.getDatasetMeta(index).hidden = hidden; this.update(); } } isDatasetHidden(index) { return this.chart?.getDatasetMeta(index)?.hidden; } toBase64Image() { return this.chart?.toBase64Image(); } themeChanged(options) { this.themeOverrides = options; if (this.chart) { if (this.chart.config.options) { Object.assign(this.chart.config.options, this.getChartOptions()); } this.update(); } } getChartOptions() { return [ { onHover: (event, active) => { if (!this.chartHover.observed && !this.chartHover.observers?.length) { return; } this.zone.run(() => this.chartHover.emit({ event, active })); }, onClick: (event, active) => { if (!this.chartClick.observed && !this.chartClick.observers?.length) { return; } this.zone.run(() => this.chartClick.emit({ event, active })); }, }, this.themeOverrides ?? {}, this.options ?? {}, { plugins: { legend: { display: this.legend, }, }, }, ].reduce(merge, {}); } getChartConfiguration() { return { type: this.type, data: this.getChartData(), options: this.getChartOptions(), plugins: this.plugins, }; } getChartData() { return this.data ? this.data : { labels: this.labels || [], datasets: this.datasets || [], }; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: BaseChartDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.1", type: BaseChartDirective, isStandalone: true, selector: "canvas[baseChart]", inputs: { type: "type", legend: "legend", data: "data", options: "options", plugins: "plugins", labels: "labels", datasets: "datasets" }, outputs: { chartClick: "chartClick", chartHover: "chartHover" }, exportAs: ["base-chart"], usesOnChanges: true, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: BaseChartDirective, decorators: [{ type: Directive, args: [{ // eslint-disable-next-line @angular-eslint/directive-selector selector: 'canvas[baseChart]', exportAs: 'base-chart', standalone: true, }] }], ctorParameters: () => [], propDecorators: { type: [{ type: Input }], legend: [{ type: Input }], data: [{ type: Input }], options: [{ type: Input }], plugins: [{ type: Input }], labels: [{ type: Input }], datasets: [{ type: Input }], chartClick: [{ type: Output }], chartHover: [{ type: Output }] } }); /* eslint-disable @typescript-eslint/no-unsafe-function-type */ /* * Public API Surface of ng2-charts */ /** * Generated bundle index. Do not edit. */ export { BaseChartDirective, NG_CHARTS_CONFIGURATION, ThemeService, provideCharts, withDefaultRegisterables }; //# sourceMappingURL=ng2-charts.mjs.map