UNPKG

@progress/kendo-angular-gauges

Version:
254 lines (253 loc) 9.37 kB
/**----------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the project root for more information *-------------------------------------------------------------------------------------------*/ import { HostBinding, NgZone, Input, ViewChild, ElementRef, Renderer2, Directive } from '@angular/core'; import { ConfigurationService, ThemeService } from '../services'; import { IntlService } from '@progress/kendo-angular-intl'; import { exportSVG, exportImage } from '@progress/kendo-drawing'; import { ResizeSensorComponent } from '@progress/kendo-angular-common'; import { LocalizationService } from '@progress/kendo-angular-l10n'; import { validatePackage } from '@progress/kendo-licensing'; import { packageMetadata } from '../package-metadata'; import * as i0 from "@angular/core"; import * as i1 from "../services"; import * as i2 from "@progress/kendo-angular-intl"; import * as i3 from "@progress/kendo-angular-l10n"; const inDocument = (element) => { let node = element; while (node && node !== document.body) { node = node.parentNode; } return Boolean(node); }; /** * @hidden */ export class GaugeComponent { configurationService; themeService; intlService; localizationService; element; renderer; ngZone; /** * Specifies options for the Gauge area. */ gaugeArea; /** * Specifies the output type. */ renderAs; /** * The maximum number of times the Gauge resizes per second. * Defaults to `10`. To disable the automatic resizing, set `resizeRateLimit` to `0`. */ resizeRateLimit = 10; /** * Specifies the scale options. */ scale; /** * Specifies if the changes will be animated. */ transitions; surfaceElement; resizeSensor; className = true; options; theme = null; instance; subscriptions; redrawTimeout; rtl = false; constructor(configurationService, themeService, intlService, localizationService, element, renderer, ngZone) { this.configurationService = configurationService; this.themeService = themeService; this.intlService = intlService; this.localizationService = localizationService; this.element = element; this.renderer = renderer; this.ngZone = ngZone; validatePackage(packageMetadata); } ngOnInit() { this.setDirection(); this.subscriptions = this.intlService.changes.subscribe(this.intlChange.bind(this)); this.subscriptions.add(this.localizationService.changes.subscribe(this.rtlChange.bind(this))); } ngAfterViewChecked() { if (typeof document === 'undefined') { return; } let updateMethod; if (!this.instance) { updateMethod = this.init; } else if (this.configurationService.hasChanges) { updateMethod = this.updateOptions; } else if (this.configurationService.valueChange) { updateMethod = this.setValues; } if (updateMethod) { clearTimeout(this.redrawTimeout); if (!this.instance && !inDocument(this.element.nativeElement)) { // required in case the gauge is initialized by ng-content outside of the DOM this.defer(() => { this.updateCall(updateMethod); }); } else { this.updateCall(updateMethod); } } } updateCall(updateMethod) { this.updateDirection(); updateMethod.call(this); this.updateSize(); } updateOptions() { this.instance.setOptions(this.configurationService.read()); } setValues() { this.instance.allValues(this.configurationService.readValues()); } ngOnChanges(changes) { this.configurationService.copyChanges('', changes); } ngOnDestroy() { if (this.instance) { this.instance.destroy(); } this.subscriptions.unsubscribe(); clearTimeout(this.redrawTimeout); } /** * Exports the Gauge as an image. The export operation is asynchronous and returns a promise. * * @param {ImageExportOptions} options - The parameters for the exported image. * @returns {Promise<string>} - A promise that will be resolved with a PNG image that is encoded as a Data URI. */ exportImage(options = {}) { return this.exportVisual().then((visual) => { return exportImage(visual, options); }); } /** * Exports the Gauge as an SVG document. The export operation is asynchronous and returns a promise. * * @param {SVGExportOptions} options - The parameters for the exported file. * @returns {Promise<string>} - A promise that will be resolved with an SVG document that is encoded as a Data URI. */ exportSVG(options = {}) { return this.exportVisual().then((visual) => { return exportSVG(visual, options); }); } /** * Exports the Gauge as a Drawing `Scene`. * * @returns {Promise<Group>} - A promise that will be resolved with the export visual. */ exportVisual() { return Promise.resolve(this.instance.exportVisual()); } /** * @hidden */ onResize() { if (this.autoResize) { this.resize(); } } /** * Detects the size of the container and redraws the Gauge. * Resizing is automatic unless you set the `resizeRateLimit` option to `0`. */ resize() { if (this.instance) { this.instance.resize(); } } init() { if (!this.surfaceElement) { return; } this.createInstance(this.surfaceElement.nativeElement, this.configurationService.read(), this.themeService.read(), { intlService: this.intlService, rtl: this.rtl }); } get autoResize() { return this.resizeRateLimit > 0; } updateSize() { this.resizeSensor.acceptSize(); } intlChange() { if (this.instance) { this.deferredRedraw(); } } rtlChange() { if (this.instance && this.rtl !== this.isRTL) { this.deferredRedraw(); } } deferredRedraw() { this.defer(() => { this.updateDirection(); this.instance.noTransitionsRedraw(); }); } defer(callback) { this.ngZone.runOutsideAngular(() => { clearTimeout(this.redrawTimeout); this.redrawTimeout = setTimeout(callback, 0); }); } updateDirection() { const current = this.isRTL; if (this.rtl !== current) { this.setDirection(); if (this.instance) { this.instance.setDirection(current); } } } setDirection() { this.rtl = this.isRTL; if (this.element) { this.renderer.setAttribute(this.element.nativeElement, 'dir', this.rtl ? 'rtl' : 'ltr'); } } get isRTL() { return Boolean(this.localizationService.rtl); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GaugeComponent, deps: [{ token: i1.ConfigurationService }, { token: i1.ThemeService }, { token: i2.IntlService }, { token: i3.LocalizationService }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: GaugeComponent, inputs: { gaugeArea: "gaugeArea", renderAs: "renderAs", resizeRateLimit: "resizeRateLimit", scale: "scale", transitions: "transitions" }, host: { properties: { "class.k-gauge": "this.className" } }, viewQueries: [{ propertyName: "surfaceElement", first: true, predicate: ["surface"], descendants: true, static: true }, { propertyName: "resizeSensor", first: true, predicate: ResizeSensorComponent, descendants: true, static: true }], usesOnChanges: true, ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: GaugeComponent, decorators: [{ type: Directive }], ctorParameters: function () { return [{ type: i1.ConfigurationService }, { type: i1.ThemeService }, { type: i2.IntlService }, { type: i3.LocalizationService }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }]; }, propDecorators: { gaugeArea: [{ type: Input }], renderAs: [{ type: Input }], resizeRateLimit: [{ type: Input }], scale: [{ type: Input }], transitions: [{ type: Input }], surfaceElement: [{ type: ViewChild, args: ['surface', { static: true }] }], resizeSensor: [{ type: ViewChild, args: [ResizeSensorComponent, { static: true }] }], className: [{ type: HostBinding, args: ['class.k-gauge'] }] } });