ngx-echarts
Version:
<!-- Badges section here. -->
367 lines (360 loc) • 16.1 kB
JavaScript
import * as i0 from '@angular/core';
import { InjectionToken, EventEmitter, Directive, Inject, Input, Output, NgModule } from '@angular/core';
import { __awaiter } from 'tslib';
import { of, EMPTY, Subject, asyncScheduler, Observable } from 'rxjs';
import { throttleTime, switchMap } from 'rxjs/operators';
class ChangeFilter {
constructor(changes) {
this.changes = changes;
}
static of(changes) {
return new ChangeFilter(changes);
}
notEmpty(key) {
if (this.changes[key]) {
const value = this.changes[key].currentValue;
if (value !== undefined && value !== null) {
return of(value);
}
}
return EMPTY;
}
has(key) {
if (this.changes[key]) {
const value = this.changes[key].currentValue;
return of(value);
}
return EMPTY;
}
notFirst(key) {
if (this.changes[key] && !this.changes[key].isFirstChange()) {
const value = this.changes[key].currentValue;
return of(value);
}
return EMPTY;
}
notFirstAndEmpty(key) {
if (this.changes[key] && !this.changes[key].isFirstChange()) {
const value = this.changes[key].currentValue;
if (value !== undefined && value !== null) {
return of(value);
}
}
return EMPTY;
}
}
const NGX_ECHARTS_CONFIG = new InjectionToken('NGX_ECHARTS_CONFIG');
class NgxEchartsDirective {
constructor(config, el, ngZone) {
this.el = el;
this.ngZone = ngZone;
this.autoResize = true;
this.loadingType = 'default';
// 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 mouse events
this.chartLegendSelectChanged = this.createLazyEvent('legendselectchanged');
this.chartLegendSelected = this.createLazyEvent('legendselected');
this.chartLegendUnselected = this.createLazyEvent('legendunselected');
this.chartLegendScroll = this.createLazyEvent('legendscroll');
this.chartDataZoom = this.createLazyEvent('datazoom');
this.chartDataRangeSelected = this.createLazyEvent('datarangeselected');
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.chartPieSelectChanged = this.createLazyEvent('pieselectchanged');
this.chartPieSelected = this.createLazyEvent('pieselected');
this.chartPieUnselected = this.createLazyEvent('pieunselected');
this.chartMapSelectChanged = this.createLazyEvent('mapselectchanged');
this.chartMapSelected = this.createLazyEvent('mapselected');
this.chartMapUnselected = this.createLazyEvent('mapunselected');
this.chartAxisAreaSelected = this.createLazyEvent('axisareaselected');
this.chartFocusNodeAdjacency = this.createLazyEvent('focusnodeadjacency');
this.chartUnfocusNodeAdjacency = this.createLazyEvent('unfocusnodeadjacency');
this.chartBrush = this.createLazyEvent('brush');
this.chartBrushEnd = this.createLazyEvent('brushend');
this.chartBrushSelected = this.createLazyEvent('brushselected');
this.chartRendered = this.createLazyEvent('rendered');
this.chartFinished = this.createLazyEvent('finished');
this.animationFrameID = null;
this.resize$ = new Subject();
this.echarts = config.echarts;
}
ngOnChanges(changes) {
const filter = ChangeFilter.of(changes);
filter.notFirstAndEmpty('options').subscribe((opt) => this.onOptionsChange(opt));
filter.notFirstAndEmpty('merge').subscribe((opt) => this.setOption(opt));
filter.has('loading').subscribe((v) => this.toggleLoading(!!v));
filter.notFirst('theme').subscribe(() => this.refreshChart());
}
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);
}
}
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);
}
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();
}
}
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.
*/
refreshChart() {
return __awaiter(this, void 0, void 0, function* () {
this.dispose();
yield 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));
});
}
initChart() {
return __awaiter(this, void 0, void 0, function* () {
yield this.onOptionsChange(this.options);
if (this.merge && this.chart) {
this.setOption(this.merge);
}
});
}
onOptionsChange(opt) {
return __awaiter(this, void 0, void 0, function* () {
if (!opt) {
return;
}
if (this.chart) {
this.setOption(this.options, true);
}
else {
this.chart = yield this.createChart();
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);
}
}
};
})));
}
}
NgxEchartsDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: NgxEchartsDirective, deps: [{ token: NGX_ECHARTS_CONFIG }, { token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
NgxEchartsDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.0.2", type: NgxEchartsDirective, selector: "echarts, [echarts]", inputs: { options: "options", theme: "theme", loading: "loading", initOpts: "initOpts", merge: "merge", autoResize: "autoResize", 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", chartLegendSelectChanged: "chartLegendSelectChanged", chartLegendSelected: "chartLegendSelected", chartLegendUnselected: "chartLegendUnselected", chartLegendScroll: "chartLegendScroll", chartDataZoom: "chartDataZoom", chartDataRangeSelected: "chartDataRangeSelected", chartTimelineChanged: "chartTimelineChanged", chartTimelinePlayChanged: "chartTimelinePlayChanged", chartRestore: "chartRestore", chartDataViewChanged: "chartDataViewChanged", chartMagicTypeChanged: "chartMagicTypeChanged", chartPieSelectChanged: "chartPieSelectChanged", chartPieSelected: "chartPieSelected", chartPieUnselected: "chartPieUnselected", chartMapSelectChanged: "chartMapSelectChanged", chartMapSelected: "chartMapSelected", chartMapUnselected: "chartMapUnselected", chartAxisAreaSelected: "chartAxisAreaSelected", chartFocusNodeAdjacency: "chartFocusNodeAdjacency", chartUnfocusNodeAdjacency: "chartUnfocusNodeAdjacency", chartBrush: "chartBrush", chartBrushEnd: "chartBrushEnd", chartBrushSelected: "chartBrushSelected", chartRendered: "chartRendered", chartFinished: "chartFinished" }, exportAs: ["echarts"], usesOnChanges: true, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: NgxEchartsDirective, decorators: [{
type: Directive,
args: [{
selector: 'echarts, [echarts]',
exportAs: 'echarts',
}]
}], ctorParameters: function () {
return [{ type: undefined, decorators: [{
type: Inject,
args: [NGX_ECHARTS_CONFIG]
}] }, { type: i0.ElementRef }, { type: i0.NgZone }];
}, propDecorators: { options: [{
type: Input
}], theme: [{
type: Input
}], loading: [{
type: Input
}], initOpts: [{
type: Input
}], merge: [{
type: Input
}], autoResize: [{
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
}], chartLegendSelectChanged: [{
type: Output
}], chartLegendSelected: [{
type: Output
}], chartLegendUnselected: [{
type: Output
}], chartLegendScroll: [{
type: Output
}], chartDataZoom: [{
type: Output
}], chartDataRangeSelected: [{
type: Output
}], chartTimelineChanged: [{
type: Output
}], chartTimelinePlayChanged: [{
type: Output
}], chartRestore: [{
type: Output
}], chartDataViewChanged: [{
type: Output
}], chartMagicTypeChanged: [{
type: Output
}], chartPieSelectChanged: [{
type: Output
}], chartPieSelected: [{
type: Output
}], chartPieUnselected: [{
type: Output
}], chartMapSelectChanged: [{
type: Output
}], chartMapSelected: [{
type: Output
}], chartMapUnselected: [{
type: Output
}], chartAxisAreaSelected: [{
type: Output
}], chartFocusNodeAdjacency: [{
type: Output
}], chartUnfocusNodeAdjacency: [{
type: Output
}], chartBrush: [{
type: Output
}], chartBrushEnd: [{
type: Output
}], chartBrushSelected: [{
type: Output
}], chartRendered: [{
type: Output
}], chartFinished: [{
type: Output
}] } });
class NgxEchartsModule {
static forRoot(config) {
return {
ngModule: NgxEchartsModule,
providers: [{ provide: NGX_ECHARTS_CONFIG, useValue: config }],
};
}
static forChild() {
return {
ngModule: NgxEchartsModule,
};
}
}
NgxEchartsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: NgxEchartsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
NgxEchartsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.0.2", ngImport: i0, type: NgxEchartsModule, declarations: [NgxEchartsDirective], exports: [NgxEchartsDirective] });
NgxEchartsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: NgxEchartsModule });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: NgxEchartsModule, decorators: [{
type: NgModule,
args: [{
imports: [],
declarations: [NgxEchartsDirective],
exports: [NgxEchartsDirective],
}]
}] });
/*
* Public API Surface of ngx-echarts
*/
/**
* Generated bundle index. Do not edit.
*/
export { NGX_ECHARTS_CONFIG, NgxEchartsDirective, NgxEchartsModule };
//# sourceMappingURL=ngx-echarts.mjs.map