@progress/kendo-angular-gauges
Version:
Kendo UI Angular Gauges
254 lines (253 loc) • 9.37 kB
JavaScript
/**-----------------------------------------------------------------------------------------
* 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']
}] } });