UNPKG

highcharts-angular

Version:
207 lines (198 loc) 10.1 kB
import * as i0 from '@angular/core'; import { InjectionToken, signal, inject, Injectable, effect, input, model, output, DestroyRef, ElementRef, PLATFORM_ID, computed, untracked, afterRenderEffect, Directive, ChangeDetectionStrategy, Component, makeEnvironmentProviders } from '@angular/core'; import { isPlatformServer } from '@angular/common'; const HIGHCHARTS_LOADER = new InjectionToken('HIGHCHARTS_LOADER'); const HIGHCHARTS_ROOT_MODULES = new InjectionToken('HIGHCHARTS_ROOT_MODULES'); const HIGHCHARTS_OPTIONS = new InjectionToken('HIGHCHARTS_OPTIONS'); const HIGHCHARTS_CONFIG = new InjectionToken('HIGHCHARTS_CONFIG'); const HIGHCHARTS_TIMEOUT = new InjectionToken('HIGHCHARTS_TIMEOUT'); class HighchartsChartService { constructor() { this.highcharts = signal(null); this.loader = inject(HIGHCHARTS_LOADER); this.globalOptions = inject(HIGHCHARTS_OPTIONS, { optional: true, }); this.globalModules = inject(HIGHCHARTS_ROOT_MODULES, { optional: true, }); } async loadHighchartsWithModules(partialConfig) { const highcharts = await this.loader(); // Ensure Highcharts core is loaded await Promise.allSettled([...(this.globalModules?.() ?? []), ...(partialConfig?.modules?.() ?? [])]); // Return the Highcharts instance return highcharts; } load(partialConfig) { this.loadHighchartsWithModules(partialConfig).then(highcharts => { if (this.globalOptions) { highcharts.setOptions(this.globalOptions); } this.highcharts.set(highcharts); }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: HighchartsChartService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: HighchartsChartService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: HighchartsChartService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }] }); class HighchartsChartDirective { delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } keepChartUpToDate() { effect(async () => { // Wait for the chart to be created this.update(); const chart = await this.chart(); if (!this.chartCreated) { if (chart) { this.chartCreated = true; } } else { chart?.update(this.options(), true, this.oneToOne()); } }); } async destroyChart() { const chart = await this.chart(); if (chart) { // #56 chart.destroy(); } } constructor() { /** * Type of the chart constructor. */ this.constructorType = input('chart'); /** * When enabled, Updates `series`, `xAxis`, `yAxis`, and `annotations` to match new options. * Items are added/removed as needed. Series with `id`s are matched by `id`; * unmatched items are removed. Omitted `series` leaves existing ones unchanged. */ this.oneToOne = input(false); /** * Options for the Highcharts chart. */ this.options = input.required(); /** * Whether to redraw the chart. * Check how update works in Highcharts * API doc here: https://api.highcharts.com/class-reference/Highcharts.Chart#update */ this.update = model(); this.chartInstance = output(); // #26 this.destroyRef = inject(DestroyRef); this.el = inject(ElementRef); this.platformId = inject(PLATFORM_ID); this.relativeConfig = inject(HIGHCHARTS_CONFIG, { optional: true, }); this.timeout = inject(HIGHCHARTS_TIMEOUT, { optional: true, }); this.highchartsChartService = inject(HighchartsChartService); this.chartCreated = false; this.constructorChart = computed(() => { const highCharts = this.highchartsChartService.highcharts(); if (highCharts) { return highCharts[this.constructorType()]; } return undefined; }); // Create the chart as soon as we can this.chart = computed(async () => { await this.delay(this.relativeConfig?.timeout ?? this.timeout ?? 500); return this.constructorChart()?.(this.el.nativeElement, // Use untracked, so we don't re-create new chart everytime options change untracked(() => this.options()), // Use Highcharts callback to emit chart instance, so it is available as early // as possible. So that Angular is already aware of the instance if Highcharts raise // events during the initialization that happens before coming back to Angular createdChart => this.chartInstance.emit(createdChart)); }); // should stop loading on the server side for SSR if (this.platformId && isPlatformServer(this.platformId)) { return; } // make sure to load global config + modules on demand this.highchartsChartService.load(this.relativeConfig); this.destroyRef.onDestroy(() => this.destroyChart()); // #44 afterRenderEffect(() => { if (this.update()) { this.update.set(false); // clear the flag after update } }); // Keep the chart up to date whenever options change or the update special input is set to true this.keepChartUpToDate(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: HighchartsChartDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.14", type: HighchartsChartDirective, isStandalone: true, selector: "[highchartsChart]", inputs: { constructorType: { classPropertyName: "constructorType", publicName: "constructorType", isSignal: true, isRequired: false, transformFunction: null }, oneToOne: { classPropertyName: "oneToOne", publicName: "oneToOne", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, update: { classPropertyName: "update", publicName: "update", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { update: "updateChange", chartInstance: "chartInstance" }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: HighchartsChartDirective, decorators: [{ type: Directive, args: [{ selector: '[highchartsChart]', }] }], ctorParameters: () => [] }); class HighchartsChartComponent { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: HighchartsChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: HighchartsChartComponent, isStandalone: true, selector: "highcharts-chart", hostDirectives: [{ directive: HighchartsChartDirective, inputs: ["constructorType", "constructorType", "oneToOne", "oneToOne", "options", "options", "update", "update"], outputs: ["chartInstance", "chartInstance", "updateChange", "updateChange"] }], ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: HighchartsChartComponent, decorators: [{ type: Component, args: [{ selector: 'highcharts-chart', template: '', hostDirectives: [ { directive: HighchartsChartDirective, inputs: ['constructorType', 'oneToOne', 'options', 'update'], outputs: ['chartInstance', 'updateChange'], }, ], changeDetection: ChangeDetectionStrategy.OnPush, }] }] }); const emptyModuleFactoryFunction = () => []; const defaultInstanceFactoryFunction = () => import('highcharts/esm/highcharts').then(m => m.default); function provideHighchartsInstance(instance) { return makeEnvironmentProviders([ { provide: HIGHCHARTS_LOADER, useValue: instance ?? defaultInstanceFactoryFunction, }, ]); } function provideHighchartsOptions(options) { return makeEnvironmentProviders([{ provide: HIGHCHARTS_OPTIONS, useValue: options }]); } function provideHighchartsRootModules(modules) { return makeEnvironmentProviders([{ provide: HIGHCHARTS_ROOT_MODULES, useValue: modules }]); } function providePartialHighcharts(config) { return { provide: HIGHCHARTS_CONFIG, useValue: config }; } function provideHighcharts(config = {}) { const providers = [ provideHighchartsInstance(config.instance), provideHighchartsRootModules(config.modules ?? emptyModuleFactoryFunction), { provide: HIGHCHARTS_TIMEOUT, useValue: config.timeout }, ]; if (config.options) { providers.push(provideHighchartsOptions(config.options)); } return makeEnvironmentProviders(providers); } /* * Public API Surface of highcharts-angular */ /** * Generated bundle index. Do not edit. */ export { HighchartsChartComponent, HighchartsChartDirective, provideHighcharts, providePartialHighcharts }; //# sourceMappingURL=highcharts-angular.mjs.map