UNPKG

ngx-echarts

Version:
408 lines (401 loc) 17.8 kB
import * as i0 from '@angular/core'; import { InjectionToken, EventEmitter, Directive, Inject, Input, Output, NgModule } from '@angular/core'; import { ReplaySubject, Subscription, Subject, asyncScheduler, Observable } from 'rxjs'; import { throttleTime, switchMap } from 'rxjs/operators'; class ChangeFilterV2 { constructor() { this.subject = new ReplaySubject(1); this.subscriptions = new Subscription(); } doFilter(changes) { this.subject.next(changes); } dispose() { this.subscriptions.unsubscribe(); } notEmpty(key, handler) { this.subscriptions.add(this.subject.subscribe(changes => { if (changes[key]) { const value = changes[key].currentValue; if (value !== undefined && value !== null) { handler(value); } } })); } has(key, handler) { this.subscriptions.add(this.subject.subscribe(changes => { if (changes[key]) { const value = changes[key].currentValue; handler(value); } })); } notFirst(key, handler) { this.subscriptions.add(this.subject.subscribe(changes => { if (changes[key] && !changes[key].isFirstChange()) { const value = changes[key].currentValue; handler(value); } })); } notFirstAndEmpty(key, handler) { this.subscriptions.add(this.subject.subscribe(changes => { if (changes[key] && !changes[key].isFirstChange()) { const value = changes[key].currentValue; if (value !== undefined && value !== null) { handler(value); } } })); } } const NGX_ECHARTS_CONFIG = new InjectionToken('NGX_ECHARTS_CONFIG'); class NgxEchartsDirective { constructor(config, el, ngZone) { this.el = el; this.ngZone = ngZone; this.options = null; this.theme = null; this.initOpts = null; this.merge = null; this.autoResize = true; this.loading = false; this.loadingType = 'default'; this.loadingOpts = null; // ngx-echarts events this.chartInit = new EventEmitter(); this.optionsError = new EventEmitter(); // echarts mouse events this.chartClick = this.createLazyEvent('click'); this.chartDblClick = this.createLazyEvent('dblclick'); this.chartMouseDown = this.createLazyEvent('mousedown'); this.chartMouseMove = this.createLazyEvent('mousemove'); this.chartMouseUp = this.createLazyEvent('mouseup'); this.chartMouseOver = this.createLazyEvent('mouseover'); this.chartMouseOut = this.createLazyEvent('mouseout'); this.chartGlobalOut = this.createLazyEvent('globalout'); this.chartContextMenu = this.createLazyEvent('contextmenu'); // echarts events this.chartHighlight = this.createLazyEvent('highlight'); this.chartDownplay = this.createLazyEvent('downplay'); this.chartSelectChanged = this.createLazyEvent('selectchanged'); this.chartLegendSelectChanged = this.createLazyEvent('legendselectchanged'); this.chartLegendSelected = this.createLazyEvent('legendselected'); this.chartLegendUnselected = this.createLazyEvent('legendunselected'); this.chartLegendLegendSelectAll = this.createLazyEvent('legendselectall'); this.chartLegendLegendInverseSelect = this.createLazyEvent('legendinverseselect'); this.chartLegendScroll = this.createLazyEvent('legendscroll'); this.chartDataZoom = this.createLazyEvent('datazoom'); this.chartDataRangeSelected = this.createLazyEvent('datarangeselected'); this.chartGraphRoam = this.createLazyEvent('graphroam'); this.chartGeoRoam = this.createLazyEvent('georoam'); this.chartTreeRoam = this.createLazyEvent('treeroam'); this.chartTimelineChanged = this.createLazyEvent('timelinechanged'); this.chartTimelinePlayChanged = this.createLazyEvent('timelineplaychanged'); this.chartRestore = this.createLazyEvent('restore'); this.chartDataViewChanged = this.createLazyEvent('dataviewchanged'); this.chartMagicTypeChanged = this.createLazyEvent('magictypechanged'); this.chartGeoSelectChanged = this.createLazyEvent('geoselectchanged'); this.chartGeoSelected = this.createLazyEvent('geoselected'); this.chartGeoUnselected = this.createLazyEvent('geounselected'); this.chartAxisAreaSelected = this.createLazyEvent('axisareaselected'); this.chartBrush = this.createLazyEvent('brush'); this.chartBrushEnd = this.createLazyEvent('brushend'); this.chartBrushSelected = this.createLazyEvent('brushselected'); this.chartGlobalCursorTaken = this.createLazyEvent('globalcursortaken'); this.chartRendered = this.createLazyEvent('rendered'); this.chartFinished = this.createLazyEvent('finished'); this.animationFrameID = null; this.chart$ = new ReplaySubject(1); this.resize$ = new Subject(); this.changeFilter = new ChangeFilterV2(); this.echarts = config.echarts; } ngOnChanges(changes) { this.changeFilter.doFilter(changes); } ngOnInit() { if (!window.ResizeObserver) { throw new Error('please install a polyfill for ResizeObserver'); } this.resizeSub = this.resize$ .pipe(throttleTime(100, asyncScheduler, { leading: false, trailing: true })) .subscribe(() => this.resize()); if (this.autoResize) { this.resizeOb = this.ngZone.runOutsideAngular(() => new window.ResizeObserver(() => { this.animationFrameID = window.requestAnimationFrame(() => this.resize$.next()); })); this.resizeOb.observe(this.el.nativeElement); } this.changeFilter.notFirstAndEmpty('options', opt => this.onOptionsChange(opt)); this.changeFilter.notFirstAndEmpty('merge', opt => this.setOption(opt)); this.changeFilter.has('loading', v => this.toggleLoading(!!v)); this.changeFilter.notFirst('theme', () => this.refreshChart()); } ngOnDestroy() { window.clearTimeout(this.initChartTimer); if (this.resizeSub) { this.resizeSub.unsubscribe(); } if (this.animationFrameID) { window.cancelAnimationFrame(this.animationFrameID); } if (this.resizeOb) { this.resizeOb.unobserve(this.el.nativeElement); } if (this.loadingSub) { this.loadingSub.unsubscribe(); } this.changeFilter.dispose(); this.dispose(); } ngAfterViewInit() { this.initChartTimer = window.setTimeout(() => this.initChart()); } dispose() { if (this.chart) { if (!this.chart.isDisposed()) { this.chart.dispose(); } this.chart = null; } } /** * resize chart */ resize() { if (this.chart) { this.chart.resize(); } } toggleLoading(loading) { if (this.chart) { loading ? this.chart.showLoading(this.loadingType, this.loadingOpts) : this.chart.hideLoading(); } else { this.loadingSub = this.chart$.subscribe(chart => loading ? chart.showLoading(this.loadingType, this.loadingOpts) : chart.hideLoading()); } } setOption(option, opts) { if (this.chart) { try { this.chart.setOption(option, opts); } catch (e) { console.error(e); this.optionsError.emit(e); } } } /** * dispose old chart and create a new one. */ async refreshChart() { this.dispose(); await this.initChart(); } createChart() { const dom = this.el.nativeElement; if (window && window.getComputedStyle) { const prop = window.getComputedStyle(dom, null).getPropertyValue('height'); if ((!prop || prop === '0px') && (!dom.style.height || dom.style.height === '0px')) { dom.style.height = '400px'; } } // here a bit tricky: we check if the echarts module is provided as function returning native import('...') then use the promise // otherwise create the function that imitates behaviour above with a provided as is module return this.ngZone.runOutsideAngular(() => { const load = typeof this.echarts === 'function' ? this.echarts : () => Promise.resolve(this.echarts); return load().then(({ init }) => init(dom, this.theme, this.initOpts)); }); } async initChart() { await this.onOptionsChange(this.options); if (this.merge && this.chart) { this.setOption(this.merge); } } async onOptionsChange(opt) { if (!opt) { return; } if (this.chart) { this.setOption(this.options, true); } else { this.chart = await this.createChart(); this.chart$.next(this.chart); this.chartInit.emit(this.chart); this.setOption(this.options, true); } } // allows to lazily bind to only those events that are requested through the `@Output` by parent components // see https://stackoverflow.com/questions/51787972/optimal-reentering-the-ngzone-from-eventemitter-event for more info createLazyEvent(eventName) { return this.chartInit.pipe(switchMap((chart) => new Observable(observer => { chart.on(eventName, (data) => this.ngZone.run(() => observer.next(data))); return () => { if (this.chart) { if (!this.chart.isDisposed()) { chart.off(eventName); } } }; }))); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: NgxEchartsDirective, deps: [{ token: NGX_ECHARTS_CONFIG }, { token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.0.1", type: NgxEchartsDirective, isStandalone: true, selector: "echarts, [echarts]", inputs: { options: "options", theme: "theme", initOpts: "initOpts", merge: "merge", autoResize: "autoResize", loading: "loading", loadingType: "loadingType", loadingOpts: "loadingOpts" }, outputs: { chartInit: "chartInit", optionsError: "optionsError", chartClick: "chartClick", chartDblClick: "chartDblClick", chartMouseDown: "chartMouseDown", chartMouseMove: "chartMouseMove", chartMouseUp: "chartMouseUp", chartMouseOver: "chartMouseOver", chartMouseOut: "chartMouseOut", chartGlobalOut: "chartGlobalOut", chartContextMenu: "chartContextMenu", chartHighlight: "chartHighlight", chartDownplay: "chartDownplay", chartSelectChanged: "chartSelectChanged", chartLegendSelectChanged: "chartLegendSelectChanged", chartLegendSelected: "chartLegendSelected", chartLegendUnselected: "chartLegendUnselected", chartLegendLegendSelectAll: "chartLegendLegendSelectAll", chartLegendLegendInverseSelect: "chartLegendLegendInverseSelect", chartLegendScroll: "chartLegendScroll", chartDataZoom: "chartDataZoom", chartDataRangeSelected: "chartDataRangeSelected", chartGraphRoam: "chartGraphRoam", chartGeoRoam: "chartGeoRoam", chartTreeRoam: "chartTreeRoam", chartTimelineChanged: "chartTimelineChanged", chartTimelinePlayChanged: "chartTimelinePlayChanged", chartRestore: "chartRestore", chartDataViewChanged: "chartDataViewChanged", chartMagicTypeChanged: "chartMagicTypeChanged", chartGeoSelectChanged: "chartGeoSelectChanged", chartGeoSelected: "chartGeoSelected", chartGeoUnselected: "chartGeoUnselected", chartAxisAreaSelected: "chartAxisAreaSelected", chartBrush: "chartBrush", chartBrushEnd: "chartBrushEnd", chartBrushSelected: "chartBrushSelected", chartGlobalCursorTaken: "chartGlobalCursorTaken", chartRendered: "chartRendered", chartFinished: "chartFinished" }, exportAs: ["echarts"], usesOnChanges: true, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: NgxEchartsDirective, decorators: [{ type: Directive, args: [{ standalone: true, selector: 'echarts, [echarts]', exportAs: 'echarts', }] }], ctorParameters: () => [{ type: undefined, decorators: [{ type: Inject, args: [NGX_ECHARTS_CONFIG] }] }, { type: i0.ElementRef }, { type: i0.NgZone }], propDecorators: { options: [{ type: Input }], theme: [{ type: Input }], initOpts: [{ type: Input }], merge: [{ type: Input }], autoResize: [{ type: Input }], loading: [{ type: Input }], loadingType: [{ type: Input }], loadingOpts: [{ type: Input }], chartInit: [{ type: Output }], optionsError: [{ type: Output }], chartClick: [{ type: Output }], chartDblClick: [{ type: Output }], chartMouseDown: [{ type: Output }], chartMouseMove: [{ type: Output }], chartMouseUp: [{ type: Output }], chartMouseOver: [{ type: Output }], chartMouseOut: [{ type: Output }], chartGlobalOut: [{ type: Output }], chartContextMenu: [{ type: Output }], chartHighlight: [{ type: Output }], chartDownplay: [{ type: Output }], chartSelectChanged: [{ type: Output }], chartLegendSelectChanged: [{ type: Output }], chartLegendSelected: [{ type: Output }], chartLegendUnselected: [{ type: Output }], chartLegendLegendSelectAll: [{ type: Output }], chartLegendLegendInverseSelect: [{ type: Output }], chartLegendScroll: [{ type: Output }], chartDataZoom: [{ type: Output }], chartDataRangeSelected: [{ type: Output }], chartGraphRoam: [{ type: Output }], chartGeoRoam: [{ type: Output }], chartTreeRoam: [{ type: Output }], chartTimelineChanged: [{ type: Output }], chartTimelinePlayChanged: [{ type: Output }], chartRestore: [{ type: Output }], chartDataViewChanged: [{ type: Output }], chartMagicTypeChanged: [{ type: Output }], chartGeoSelectChanged: [{ type: Output }], chartGeoSelected: [{ type: Output }], chartGeoUnselected: [{ type: Output }], chartAxisAreaSelected: [{ type: Output }], chartBrush: [{ type: Output }], chartBrushEnd: [{ type: Output }], chartBrushSelected: [{ type: Output }], chartGlobalCursorTaken: [{ type: Output }], chartRendered: [{ type: Output }], chartFinished: [{ type: Output }] } }); const provideEcharts = () => { return { provide: NGX_ECHARTS_CONFIG, useFactory: () => ({ echarts: () => import('echarts') }), }; }; const provideEchartsCore = (config) => { return { provide: NGX_ECHARTS_CONFIG, useValue: config, }; }; class NgxEchartsModule { static forRoot(config) { return { ngModule: NgxEchartsModule, providers: [provideEchartsCore(config)], }; } static forChild() { return { ngModule: NgxEchartsModule, }; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: NgxEchartsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.1", ngImport: i0, type: NgxEchartsModule, imports: [NgxEchartsDirective], exports: [NgxEchartsDirective] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: NgxEchartsModule }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: NgxEchartsModule, decorators: [{ type: NgModule, args: [{ imports: [NgxEchartsDirective], exports: [NgxEchartsDirective], }] }] }); /* * Public API Surface of ngx-echarts */ /** * Generated bundle index. Do not edit. */ export { NGX_ECHARTS_CONFIG, NgxEchartsDirective, NgxEchartsModule, provideEcharts, provideEchartsCore }; //# sourceMappingURL=ngx-echarts.mjs.map