UNPKG

@syncfusion/ej2-circulargauge

Version:
1,021 lines 67.2 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; /* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable max-len */ /** * Circular Gauge */ import { Property, NotifyPropertyChanges, Component, animationMode } from '@syncfusion/ej2-base'; import { Complex, Browser, isNullOrUndefined } from '@syncfusion/ej2-base'; import { Event, EventHandler, Collection, Internationalization } from '@syncfusion/ej2-base'; import { remove, createElement } from '@syncfusion/ej2-base'; import { SvgRenderer } from '@syncfusion/ej2-svg-base'; import { removeElement, getElement, stringToNumber, measureText, toPixel, textElement, getAngleFromValue, getAngleFromLocation, getPathArc, getPointer, RectOption, Size, GaugeLocation, Rect, TextOption } from './utils/helper-common'; import { setStyles, getValueFromAngle, getRange } from './utils/helper-circular-gauge'; import { Border, Margin, Font, TooltipSettings, LegendSettings } from './model/base'; import { Axis } from './axes/axis'; import { Annotations } from './annotations/annotations'; import { GaugeTooltip } from './user-interaction/tooltip'; import { load, loaded, gaugeMouseMove, gaugeMouseLeave, gaugeMouseDown, pointerMove } from './model/constants'; import { rangeMove, pointerStart, rangeStart, pointerEnd, rangeEnd } from './model/constants'; import { gaugeMouseUp, dragEnd, dragMove, dragStart, resized } from './model/constants'; import { AxisLayoutPanel } from './axes/axis-panel'; import { getThemeStyle } from './model/theme'; import { textTrim, titleTooltip } from './utils/helper-legend'; import { Legend } from './legend/legend'; import { PdfExport } from './model/pdf-export'; import { ImageExport } from './model/image-export'; import { Print } from './model/print'; import { Gradient } from './axes/gradient'; /** * Represents the circular gauge control. This is used to customize the properties of the circular gauge to visualize the data in circular scale. * ```html * <div id="gauge"/> * <script> * var gaugeObj = new CircularGauge(); * gaugeObj.appendTo("#gauge"); * </script> * ``` */ var CircularGauge = /** @class */ (function (_super) { __extends(CircularGauge, _super); /** * Constructor for creating the widget * * @param {CircularGaugeModel} options - Specifies the options * @param {string} element - Specifies the element * @hidden */ function CircularGauge(options, element) { var _this = _super.call(this, options, element) || this; /** @private */ _this.allowLoadingAnimation = false; /** @private */ _this.isRangeUpdate = false; /** @private */ _this.isAnimationProgress = true; /** @private */ _this.isResize = false; /** @private */ _this.isOverAllAnimationComplete = false; /** @private */ _this.isDrag = false; /** * @private */ _this.gradientCount = 0; CircularGauge_1.Inject(Gradient); if (element) { _this.appendTo(element); } return _this; } CircularGauge_1 = CircularGauge; /** * To create svg object, renderer and binding events for the container. * * @returns {void} */ CircularGauge.prototype.preRender = function () { if (!isNullOrUndefined(this.element)) { this.unWireEvents(); this.trigger(load, { gauge: this }); this.initPrivateVariable(); this.setCulture(); this.createSvg(); this.wireEvents(); } }; /** * To render the circular gauge elements * * @returns {void} */ CircularGauge.prototype.render = function () { if (!isNullOrUndefined(this.element)) { this.setTheme(); this.calculateBounds(); this.isPropertyChange = false; this.allowLoadingAnimation = ((this.animationDuration === 0 && animationMode === 'Enable') || this.animationDuration > 0) && !this.isOverAllAnimationComplete; this.renderElements(true); this.renderAnimation(); this.renderComplete(); } }; CircularGauge.prototype.setTheme = function () { this.themeStyle = getThemeStyle(this.theme); }; /** * Method to unbind events for circular gauge * * @returns {void} */ CircularGauge.prototype.unWireEvents = function () { EventHandler.remove(this.element, Browser.touchStartEvent, this.gaugeOnMouseDown); EventHandler.remove(this.element, Browser.touchMoveEvent, this.mouseMove); EventHandler.remove(this.element, Browser.touchEndEvent, this.mouseEnd); EventHandler.remove(this.element, 'click', this.gaugeOnMouseClick); EventHandler.remove(this.element, 'contextmenu', this.gaugeRightClick); EventHandler.remove(this.element, (Browser.isPointer ? 'pointerleave' : 'mouseleave'), this.mouseLeave); window.removeEventListener((Browser.isTouch && ('orientation' in window && 'onorientationchange' in window)) ? 'orientationchange' : 'resize', this.resizeEvent); }; /** * Method to bind events for circular gauge * * @returns {void} */ CircularGauge.prototype.wireEvents = function () { /*! Bind the Event handler */ EventHandler.add(this.element, Browser.touchStartEvent, this.gaugeOnMouseDown, this); EventHandler.add(this.element, Browser.touchMoveEvent, this.mouseMove, this); EventHandler.add(this.element, Browser.touchEndEvent, this.mouseEnd, this); EventHandler.add(this.element, 'click', this.gaugeOnMouseClick, this); EventHandler.add(this.element, 'contextmenu', this.gaugeRightClick, this); EventHandler.add(this.element, (Browser.isPointer ? 'pointerleave' : 'mouseleave'), this.mouseLeave, this); this.resizeEvent = this.gaugeResize.bind(this); window.addEventListener((Browser.isTouch && ('orientation' in window && 'onorientationchange' in window)) ? 'orientationchange' : 'resize', this.resizeEvent); /*! Apply the style for circular gauge */ this.setGaugeStyle(this.element); }; /** * Handles the mouse click on accumulation chart. * * @param {PointerEvent} e - Specifies the pointer event * @returns {boolean} - Returns the boolean value * @private */ CircularGauge.prototype.gaugeOnMouseClick = function (e) { this.setMouseXY(e); if (this.legendModule && this.legendSettings.visible) { this.legendModule.click(e); } return false; }; /** * Handles the mouse move. * * @param {PointerEvent} e - Specifies the pointer event * @returns {boolean} - Returns the boolean value * @private */ CircularGauge.prototype.mouseMove = function (e) { var _this = this; this.setMouseXY(e); var args = this.getMouseArgs(e, 'touchmove', gaugeMouseMove); this.trigger('gaugeMouseMove', args, function (observedArgs) { var dragArgs; var pointerDrag = false; if ((!isNullOrUndefined(_this.activePointer) ? _this.activePointer.pathElement[0].id === args.target.id : true)) { var pointerIndex = args.target.id.indexOf('_Pointer_') > -1 ? parseInt(args.target.id.slice(-1), 10) : null; var axisIndex = args.target.id.indexOf('_Axis_') > -1 ? parseInt(args.target.id.split('_Axis_')[1], 10) : null; pointerDrag = (_this.allowPointerDrag && !isNullOrUndefined(axisIndex) && !isNullOrUndefined(pointerIndex)) ? _this.axes[axisIndex].pointers[pointerIndex].enableDrag : _this.enablePointerDrag; _this.isPointerDragged = pointerDrag; } if (!args.cancel) { if ((_this.isPointerDragged || _this.enableRangeDrag) && _this.svgObject.getAttribute('cursor') !== 'grabbing') { if ((args.target.id.indexOf('_Pointer_') !== -1 && _this.isPointerDragged) || (_this.enableRangeDrag && args.target.id.indexOf('_Range_') !== -1)) { _this.svgObject.setAttribute('cursor', 'pointer'); } else { _this.svgObject.setAttribute('cursor', 'auto'); } } else if (_this.svgObject.getAttribute('cursor') !== 'grabbing') { _this.svgObject.setAttribute('cursor', 'auto'); } var svgElement = getElement(_this.element.id + '_svg'); var extraWidth = _this.element.getBoundingClientRect().left - svgElement.getBoundingClientRect().left; if (_this.isPointerDragged && _this.activePointer) { _this.isDrag = true; e.preventDefault(); var dragPointInd = parseInt(_this.activePointer.pathElement[0].id.slice(-1), 10); var dragAxisInd = parseInt(_this.activePointer.pathElement[0].id.split('_Axis_')[1], 10); dragArgs = { axis: _this.activeAxis, pointer: _this.activePointer, previousValue: _this.activePointer.currentValue, name: dragMove, type: pointerMove, currentValue: null, axisIndex: dragAxisInd, pointerIndex: dragPointInd }; _this.pointerDrag(new GaugeLocation(args.x + extraWidth, args.y), dragAxisInd, dragPointInd); dragArgs.currentValue = _this.activePointer.currentValue; _this.trigger(dragMove, dragArgs); _this.activeRange = null; } else if (_this.enableRangeDrag && _this.activeRange) { _this.isDrag = true; e.preventDefault(); var dragAxisInd = parseInt(_this.activeRange.pathElement[0].id.split('_Axis_')[1], 10); var dragRangeInd = parseInt(_this.activeRange.pathElement[0].id.split('Range_')[1], 10); dragArgs = { axis: _this.activeAxis, name: dragMove, type: rangeMove, range: _this.activeRange, axisIndex: dragAxisInd, rangeIndex: dragRangeInd }; _this.rangeDrag(new GaugeLocation(args.x + extraWidth, args.y), dragAxisInd, dragRangeInd); _this.trigger(dragMove, dragArgs); } } }); this.notify(Browser.touchMoveEvent, e); titleTooltip(e, e.clientX, e.clientY, this, false); return false; }; /** * Handles the mouse leave. * * @param {PointerEvent} e - Specifies the pointer event * @returns {boolean} - Returns the boolean value * @private */ CircularGauge.prototype.mouseLeave = function (e) { this.setMouseXY(e); this.activeAxis = null; this.activePointer = null; this.activeRange = null; this.svgObject.setAttribute('cursor', 'auto'); var args = this.getMouseArgs(e, 'touchmove', gaugeMouseLeave); this.trigger(gaugeMouseLeave, args); return false; }; /** * Handles the mouse right click. * * @param {MouseEvent | PointerEvent} event - Specifies the pointer or mouse event. * @returns {boolean} - Returns the boolean value. * @private */ CircularGauge.prototype.gaugeRightClick = function (event) { if (event.buttons === 2 || event.pointerType === 'touch') { event.preventDefault(); event.stopPropagation(); return false; } return true; }; /** * Handles the pointer draf while mouse move on gauge. * * @param {GaugeLocation} location - Specifies the location of the gauge * @param {number} axisIndex - Specifies the axis index * @param {number} pointerIndex - Specifies the pointer index * @returns {void} * @private */ CircularGauge.prototype.pointerDrag = function (location, axisIndex, pointerIndex) { var axis = this.activeAxis; var range = axis.visibleRange; var value = getValueFromAngle(getAngleFromLocation(this.midPoint, location), range.max, range.min, axis.startAngle, axis.endAngle, axis.direction === 'ClockWise'); if (value >= range.min && value <= range.max) { this.axes[axisIndex].pointers[pointerIndex].value = value; this.activePointer.currentValue = value; this.gaugeAxisLayoutPanel.pointerRenderer.setPointerValue(axis, this.activePointer, value); } }; /** * Handles the range draf while mouse move on gauge. * * @param {GaugeLocation} location - Specifies the gauge location * @param {number} axisIndex - Specifies the axis index * @param {number} rangeIndex - Specifies the range index * @returns {void} * @private */ CircularGauge.prototype.rangeDrag = function (location, axisIndex, rangeIndex) { if (this.activeAxis) { var axis = this.activeAxis; var range = axis.visibleRange; var value = getValueFromAngle(getAngleFromLocation(this.midPoint, location), range.max, range.min, axis.startAngle, axis.endAngle, axis.direction === 'ClockWise'); if (value >= range.min && value <= range.max) { var previousValue1 = this.activeRange.currentValue; this.activeRange.currentValue = value; var add = (this.activeRange.end - this.activeRange.start); var div = add / 2; var avg = parseFloat(this.activeRange.start.toString()) + div; var start = typeof this.activeRange.start === 'string' ? parseFloat(this.activeRange.start) : this.activeRange.start; var end = typeof this.activeRange.end === 'string' ? parseFloat(this.activeRange.end) : this.activeRange.end; this.startValue = (value < avg) ? value : ((previousValue1 < avg) ? previousValue1 : ((start < end) ? this.activeRange.start : this.activeRange.end)); this.endValue = (value < avg) ? ((previousValue1 > avg) ? previousValue1 : ((start < end) ? this.activeRange.end : this.activeRange.start)) : value; this.axes[axisIndex].ranges[rangeIndex].start = this.startValue; this.axes[axisIndex].ranges[rangeIndex].end = this.endValue; if (this.isTouch) { this.setRangeValue(axisIndex, rangeIndex, this.startValue, this.endValue); } } } }; /** * Handles the mouse down on gauge. * * @param {PointerEvent} e - Specifies the pointer event * @returns {boolean} - Returns the boolean value * @private */ CircularGauge.prototype.gaugeOnMouseDown = function (e) { var _this = this; this.setMouseXY(e); var currentPointer; var currentRange; var args = this.getMouseArgs(e, 'touchstart', gaugeMouseDown); var pointerDrag = false; var pointerIndex = args.target.id.indexOf('_Pointer_') > -1 ? parseInt(args.target.id.slice(-1), 10) : null; var axisIndex = args.target.id.indexOf('_Axis_') > -1 ? parseInt(args.target.id.split('_Axis_')[1], 10) : null; if (!isNullOrUndefined(axisIndex) && !isNullOrUndefined(pointerIndex)) { pointerDrag = this.allowPointerDrag ? this.axes[axisIndex].pointers[pointerIndex].enableDrag : this.enablePointerDrag; } this.trigger('gaugeMouseDown', args, function (observedArgs) { if (!args.cancel && args.target.id.indexOf(_this.element.id + '_Axis_') >= 0 && args.target.id.indexOf('_Pointer_') >= 0) { currentPointer = getPointer(args.target.id, _this); _this.activeAxis = _this.axes[currentPointer.axisIndex]; _this.activePointer = _this.activeAxis.pointers[currentPointer.pointerIndex]; if (isNullOrUndefined(_this.activePointer.pathElement)) { _this.activePointer.pathElement = [e.target]; } if (_this.activePointer.type === 'Marker' && _this.activePointer.markerShape === 'Text' && _this.activePointer.pathElement.length === 0) { _this.activePointer.pathElement = [e.target]; } var pointInd = parseInt(_this.activePointer.pathElement[0].id.slice(-1), 10); var axisInd = parseInt(_this.activePointer.pathElement[0].id.split('_Axis_')[1], 10); _this.trigger(dragStart, { axis: _this.activeAxis, name: dragStart, type: pointerStart, pointer: _this.activePointer, currentValue: _this.activePointer.currentValue, pointerIndex: pointInd, axisIndex: axisInd }); if (pointerDrag) { _this.svgObject.setAttribute('cursor', 'grabbing'); } } else if (!args.cancel && args.target.id.indexOf(_this.element.id + '_Axis_') >= 0 && args.target.id.indexOf('_Range_') >= 0) { currentRange = getRange(args.target.id, _this); _this.activeAxis = _this.axes[currentRange.axisIndex]; _this.activeRange = _this.activeAxis.ranges[currentRange.rangeIndex]; if (isNullOrUndefined(_this.activeRange.pathElement)) { _this.activeRange.pathElement = [e.target]; } var rangeInd = parseInt(_this.activeRange.pathElement[0].id.split('Range_')[1], 10); var axisInd = parseInt(_this.activeRange.pathElement[0].id.split('_Axis_')[1], 10); _this.trigger(dragStart, { axis: _this.activeAxis, name: dragStart, type: rangeStart, range: _this.activeRange, axisIndex: axisInd, rangeIndex: rangeInd }); if (_this.enableRangeDrag) { _this.svgObject.setAttribute('cursor', 'grabbing'); } } }); return false; }; /** * Handles the mouse end. * * @param {PointerEvent} e - Specifies the pointer event * @returns {boolean} - Returns the boolean value * @private */ CircularGauge.prototype.mouseEnd = function (e) { this.setMouseXY(e); var args = this.getMouseArgs(e, 'touchend', gaugeMouseUp); this.isTouch = e.pointerType === 'touch' || e.pointerType === '2' || e.type === 'touchend'; this.trigger(gaugeMouseUp, args); var pointerDrag = false; if (this.activeAxis && this.activePointer) { var pointerIndex = parseInt(this.activePointer.pathElement[0].id.slice(-1), 10); var axisIndex = parseInt(this.activePointer.pathElement[0].id.split('_Axis_')[1], 10); if (!isNullOrUndefined(axisIndex) && !isNullOrUndefined(pointerIndex)) { pointerDrag = this.allowPointerDrag ? this.axes[axisIndex].pointers[pointerIndex].enableDrag : this.enablePointerDrag; } if (pointerDrag) { this.svgObject.setAttribute('cursor', 'auto'); this.trigger(dragEnd, { name: dragEnd, type: pointerEnd, axis: this.activeAxis, pointer: this.activePointer, currentValue: this.activePointer.currentValue, axisIndex: axisIndex, pointerIndex: pointerIndex }); this.activeAxis = null; this.activePointer = null; this.isPointerDragged = false; } } else if (this.activeAxis && this.activeRange && this.enableRangeDrag) { this.svgObject.setAttribute('cursor', 'auto'); var rangeInd = parseInt(this.activeRange.pathElement[0].id.slice(-1), 10); var axisInd = parseInt(this.activeRange.pathElement[0].id.split('_Axis_')[1], 10); this.trigger(dragEnd, { name: dragEnd, type: rangeEnd, axis: this.activeAxis, range: this.activeRange, axisIndex: axisInd, rangeIndex: rangeInd }); this.activeAxis = null; this.activeRange = null; } if (!isNullOrUndefined(this.activePointer)) { this.activePointer = null; } this.isDrag = false; this.svgObject.setAttribute('cursor', 'auto'); this.notify(Browser.touchEndEvent, e); if (e.type.indexOf('touch') > -1 && (args.target.id === (this.element.id + '_CircularGaugeTitle') || args.target.id.indexOf('_gauge_legend_') > -1)) { var touchArg = e; titleTooltip(e, touchArg.changedTouches[0].pageX, touchArg.changedTouches[0].pageY, this, true); } return false; }; /** * Handles the mouse event arguments. * * @param {PointerEvent} e - Specifies the pointer event * @param {string} type - Specifies the type * @param {string} name - Specifies the name * @returns {IMouseEventArgs} - Returns the mouse event args * @private */ CircularGauge.prototype.getMouseArgs = function (e, type, name) { var rect = this.element.getBoundingClientRect(); var location = new GaugeLocation(-rect.left, -rect.top); var isTouch = (e.type === type); location.x += isTouch ? e.changedTouches[0].clientX : e.clientX; location.y += isTouch ? e.changedTouches[0].clientY : e.clientY; return { cancel: false, name: name, x: location.x, y: location.y, target: isTouch ? e.target : e.target }; }; /** * Handles the gauge resize. * * @param {Event} e - Specifies the event * @returns {boolean} - Returns the boolean value * @private */ CircularGauge.prototype.gaugeResize = function (e) { var _this = this; if (!this.isDestroyed) { // eslint-disable-next-line prefer-const var args = { gauge: this, previousSize: this.availableSize, name: resized, cancel: false, currentSize: this.calculateSvgSize() }; this.trigger(resized, args); if (!args.cancel) { if (this.resizeTo) { clearTimeout(this.resizeTo); } if (!isNullOrUndefined(this.element) && this.element.classList.contains('e-circulargauge')) { this.animatePointer = false; this.resizeTo = window.setTimeout(function () { _this.isResize = true; _this.isPropertyChange = true; _this.createSvg(); _this.calculateBounds(); _this.allowLoadingAnimation = false; if (_this.isOverAllAnimationComplete) { _this.loadingAnimationDuration = []; } _this.renderElements(); _this.isResize = false; }, 500); } } } return false; }; /** * Applying styles for circular gauge elements * * @param {HTMLElement} element - Specifies the html element * @returns {void} */ CircularGauge.prototype.setGaugeStyle = function (element) { element.style.touchAction = 'element'; element.style.msTouchAction = 'element'; element.style.msContentZooming = 'none'; element.style.msUserSelect = 'none'; element.style.webkitUserSelect = 'none'; element.style.position = 'relative'; }; /** * Method to set culture for gauge * * @returns {void} */ CircularGauge.prototype.setCulture = function () { this.intl = new Internationalization(); }; /** * Methods to create svg element for circular gauge. * * @returns {void} */ CircularGauge.prototype.createSvg = function () { this.removeSvg(); if (isNullOrUndefined(this.renderer)) { this.renderer = new SvgRenderer(this.element.id); } if (isNullOrUndefined(this.gaugeAxisLayoutPanel)) { this.gaugeAxisLayoutPanel = new AxisLayoutPanel(this); } this.availableSize = this.calculateSvgSize(); this.svgObject = this.renderer.createSvg({ id: this.element.id + '_svg', width: this.availableSize.width, height: this.availableSize.height }); }; /** * To Remove the SVG from circular gauge. * * @returns {void} * @private */ CircularGauge.prototype.removeSvg = function () { if (!isNullOrUndefined(this.element)) { removeElement(this.element.id + '_Secondary_Element'); if (this.svgObject) { while (this.svgObject.childNodes.length > 0) { while (this.svgObject.childNodes.length > 0) { this.svgObject.removeChild(this.svgObject.firstChild); } if (!this.svgObject.hasChildNodes() && this.svgObject.parentNode) { remove(this.svgObject); } } if (!this.svgObject.hasChildNodes() && this.svgObject.parentNode) { remove(this.svgObject); } } removeElement(this.element.id + '_svg'); this.clearTemplate(); } }; /** * To initialize the circular gauge private variable. * * @returns {void} * @private */ CircularGauge.prototype.initPrivateVariable = function () { if (this.element.id === '') { var collection = document.getElementsByClassName('e-circulargauge').length; this.element.id = 'circulargauge_control_' + collection; } this.renderer = new SvgRenderer(this.element.id); this.gaugeAxisLayoutPanel = new AxisLayoutPanel(this); this.animatePointer = true; }; /** * To calculate the size of the circular gauge element. * * @returns {void} */ CircularGauge.prototype.calculateSvgSize = function () { var containerWidth = this.element.offsetWidth; var containerHeight = this.element.offsetHeight; var borderWidth = parseInt(this.element.style.borderWidth.split('px').join(''), 10) * 2; var width = stringToNumber(this.width, containerWidth) || containerWidth || 600; var height = stringToNumber(this.height, containerHeight) || containerHeight || 450; width = !isNaN(borderWidth) ? (width - borderWidth) : width; height = !isNaN(borderWidth) ? (height - borderWidth) : height; return new Size(width, height); }; /** * To calculate the spacing of the circular gauge element. * * @param {number} top - Specifies the top value * @param {number} left - Specifies the left value * @param {number} width - Specifies the width * @param {number} height - Specifies the height * @param {number} radius - Specifies the radius * @param {number} titleHeight - Specifies the titleHeight * @param {number} isUpperAngle - Specifies the isUpperAngle * @param {number} isLowerAngle - Specifies the isLowerAngle * @param {number} isFullPercent - Specifies the boolean value * @param {number} isUpper - Specifies the boolean value * @param {number} isLower - Specifies the boolean value * @returns {void} */ /* eslint-disable max-len */ CircularGauge.prototype.radiusAndCenterCalculation = function (top, left, width, height, radius, titleHeight, isUpperAngle, isLowerAngle, isFullPercent, radiusPercent, isUpper, isLower) { var rect; var bottom = this.margin.bottom + this.border.width; var minRadius; var widthRadius; var centerX; var centerY; if (this.moveToCenter && this.axes.length === 1 && isNullOrUndefined(this.centerXpoint) && isNullOrUndefined(this.centerYpoint)) { rect = new Rect(left, top, width, height); } else { if (!this.allowMargin) { if (!isNullOrUndefined(this.legendModule) && (width > height) && (this.legendSettings.position === 'Top' || this.legendSettings.position === 'Bottom')) { minRadius = Math.min(width, height) / 2; rect = new Rect((left + (width / 2) - minRadius), (top + (height / 2) - minRadius), minRadius * 2, minRadius * 2); } else { if (width > height && (isLowerAngle && isLower || isUpperAngle && isUpper)) { widthRadius = ((width) / 2); var heightValue = isUpper && isLower ? (height / 2) : (height * (3 / 4)); if (widthRadius > heightValue) { widthRadius = heightValue; } rect = new Rect((left + (width / 2) - widthRadius), (top + (height / 2) - widthRadius), widthRadius * 2, widthRadius * 2); } else { if (height > width) { var heightRadius = height / 2; rect = new Rect((left + (width / 2) - radius), (top + (height / 2) - heightRadius), radius * 2, heightRadius * 2); } else { rect = new Rect((left + (width / 2) - radius), (top + (height / 2) - radius), radius * 2, radius * 2); } } } } else { rect = new Rect((left + (width / 2) - radius), (top + (height / 2) - radius), radius * 2, radius * 2); } } this.gaugeRect = rect; if (this.legendModule && this.legendSettings.visible) { this.legendModule.getLegendOptions(this.axes); this.legendModule.calculateLegendBounds(this.gaugeRect, this.availableSize); } if (!this.allowMargin) { if (!isNullOrUndefined(this.legendModule) && (isUpperAngle || isLowerAngle) && (width > height) && (this.legendSettings.position === 'Top' || this.legendSettings.position === 'Bottom')) { var difference = height - this.gaugeRect.height; this.gaugeRect.width = width - ((this.availableSize.width - this.gaugeRect.width) / 2); this.gaugeRect.y = this.gaugeRect.y - difference; this.gaugeRect.height = this.gaugeRect.height + difference + ((this.availableSize.height - this.gaugeRect.height) / 2); } else if (!isNullOrUndefined(this.legendModule) && (isUpperAngle || isLowerAngle) && (width > height) && (this.legendSettings.position === 'Left' || this.legendSettings.position === 'Right')) { var difference = this.gaugeRect.height - this.gaugeRect.width; this.gaugeRect.x = this.legendSettings.position === 'Right' ? this.gaugeRect.x + this.margin.right : this.gaugeRect.x; this.gaugeRect.width = this.legendSettings.position === 'Left' ? Math.abs(width - ((this.availableSize.width - this.gaugeRect.width + difference) / 2)) : Math.abs(width - ((this.availableSize.width - this.gaugeRect.width) / 2) - 10); } centerX = this.centerXpoint !== null ? stringToNumber(this.centerXpoint, this.availableSize.width) : this.gaugeRect.x + (this.gaugeRect.width / 2); if ((isUpperAngle || isLowerAngle) && !isNullOrUndefined(this.legendModule)) { centerX = (this.legendSettings.position === 'Top' || this.legendSettings.position === 'Bottom') ? this.availableSize.width / 2 : this.legendSettings.position === 'Right' ? (this.gaugeRect.width / 2) + this.margin.right : centerX; } centerY = ((isUpperAngle || isLowerAngle) ? (isUpperAngle ? (((this.gaugeRect.height * (3 / 4) + this.gaugeRect.y) - bottom)) : (((this.gaugeRect.height * (1 / 4)) + (this.gaugeRect.y)))) : this.gaugeRect.y + (this.gaugeRect.height / 2)); centerY = !isFullPercent && (isUpperAngle || isLowerAngle) ? (this.gaugeRect.height / 2) + this.gaugeRect.y + (radiusPercent * (3 / 4) * (1 / 2)) : centerY; if (!isNullOrUndefined(this.axes) && this.axes.length > 1 && !isNullOrUndefined(this.midPoint)) { isUpper = isUpperAngle ? isUpperAngle : isUpper; isLower = isLowerAngle ? isLowerAngle : isLower; if (isUpper && isLower) { centerY = (this.availableSize.height / 2) - bottom; } } } else { centerX = this.centerXpoint !== null ? stringToNumber(this.centerXpoint, this.availableSize.width) : this.gaugeRect.x + (this.gaugeRect.width / 2); centerY = this.centerYpoint !== null ? stringToNumber(this.centerYpoint, this.availableSize.height) : this.gaugeRect.y + (this.gaugeRect.height / 2); } this.midPoint = new GaugeLocation(centerX, centerY); }; /** * Method to calculate the availble size for circular gauge. * * @returns {void} */ CircularGauge.prototype.calculateBounds = function () { var padding = 5; var rect; var margin = this.margin; var titleHeight = 0; if (this.title) { titleHeight = measureText(this.title, this.titleStyle).height + padding; } var top = margin.top + titleHeight + this.border.width; var left = margin.left + this.border.width; var isUpper = false; var isLower = false; var width = this.availableSize.width - left - margin.right - this.border.width; var height = this.availableSize.height - top - this.border.width - margin.bottom; var radius = Math.min(width, height) / 2; this.centerXpoint = (this.centerX === '') ? null : this.centerX; this.centerYpoint = (this.centerY === '') ? null : this.centerY; if (this.moveToCenter && this.axes.length === 1 && isNullOrUndefined(this.centerXpoint) && isNullOrUndefined(this.centerYpoint)) { rect = new Rect(left, top, width, height); } if (!this.allowMargin) { for (var j = 0; j < this.axes.length; j++) { var isUpperAngle = 270 <= this.axes[j].startAngle && this.axes[j].startAngle <= 360 && 0 <= this.axes[j].endAngle && this.axes[j].endAngle <= 90; var isLowerAngle = 90 >= this.axes[j].startAngle && this.axes[j].startAngle <= 180 && 180 <= this.axes[j].endAngle && 270 <= this.axes[j].endAngle && 0 !== this.axes[j].startAngle && 360 !== this.axes[j].endAngle; isUpper = isUpperAngle ? isUpperAngle : isUpper; isLower = isLowerAngle ? isLowerAngle : isLower; var isFullPercent = this.axes[j].radius !== null ? parseInt(this.axes[0].radius.split('%')[0], 10) >= 100 : true; var radiusPercent = this.axes[j].radius !== null ? radius * (parseInt(this.axes[0].radius.split('%')[0], 10) / 100) : radius; this.radiusAndCenterCalculation(top, left, width, height, radius, titleHeight, isUpperAngle, isLowerAngle, isFullPercent, radiusPercent, isUpper, isLower); } } else { rect = new Rect((left + (width / 2) - radius), (top + (height / 2) - radius), radius * 2, radius * 2); this.radiusAndCenterCalculation(top, left, width, height, radius, titleHeight, false, false, null, null, false, false); } this.gaugeAxisLayoutPanel.measureAxis(this.gaugeRect); }; /** * To render elements for circular gauge * * @param {boolean} animate - Specifies whether animation is true or false * @returns {void} */ CircularGauge.prototype.renderElements = function (animate) { if (animate === void 0) { animate = true; } this.renderBorder(); this.renderTitle(); this.gaugeAxisLayoutPanel.renderAxes(animate); this.renderLegend(); this.element.appendChild(this.svgObject); this.trigger(loaded, { gauge: this }); removeElement('gauge-measuretext'); }; CircularGauge.prototype.renderAnimation = function () { if (this.allowLoadingAnimation) { for (var i = 0; i < this.axes.length; i++) { this.gaugeAxisLayoutPanel.axisLineAnimation(i, this.loadingAnimationDuration[i], this); } } }; /** * Method to render legend for accumulation chart * * @returns {void} */ CircularGauge.prototype.renderLegend = function () { if (!this.legendModule || !this.legendSettings.visible) { return null; } if (this.legendModule.legendCollection.length) { this.legendModule.renderLegend(this.legendSettings, this.legendModule.legendBounds); } }; /** * Method to render the title for circular gauge. * * @returns {void} */ CircularGauge.prototype.renderTitle = function () { if (this.title) { // eslint-disable-next-line prefer-const var style = { color: this.titleStyle.color, size: this.titleStyle.size || this.themeStyle.titleFontSize, fontFamily: this.titleStyle.fontFamily || this.themeStyle.fontFamily, fontStyle: this.titleStyle.fontStyle, fontWeight: this.titleStyle.fontWeight || this.themeStyle.titleFontWeight, opacity: this.titleStyle.opacity }; var titleSize = style.size; if (!isNaN(Number(titleSize))) { style.size = titleSize + 'px'; } var width = Math.abs((this.margin.left + this.margin.right) - this.availableSize.width); var trimmedTitle = textTrim(width, this.title, style); var size = measureText(trimmedTitle, style); var options = new TextOption(this.element.id + '_CircularGaugeTitle', this.availableSize.width / 2, this.margin.top + 3 * (size.height / 4), 'middle', trimmedTitle); var element = textElement(options, style, style.color || this.themeStyle.titleFontColor, this.svgObject, ''); element.setAttribute('aria-label', this.description || this.title); element.setAttribute('role', 'region'); element.setAttribute('tabindex', this.tabIndex.toString()); } }; /** * Method to render the border for circular gauge. * * @returns {void} */ CircularGauge.prototype.renderBorder = function () { var borderWidth = this.border.width; if (borderWidth > 0 || (this.background || this.themeStyle.backgroundColor)) { this.svgObject.appendChild(this.renderer.drawRectangle(new RectOption(this.element.id + '_CircularGaugeBorder', this.background || this.themeStyle.backgroundColor, this.border, null, new Rect(borderWidth / 2, borderWidth / 2, this.availableSize.width - borderWidth, this.availableSize.height - borderWidth)))); } }; /* eslint-disable valid-jsdoc */ /** * This method is used to set the pointer value dynamically for circular gauge. * * @param {number} axisIndex - Specifies the index value for the axis in circular gauge. * @param {number} pointerIndex - Specifies the index value for the pointer in circular gauge. * @param {number} value - Specifies the value for the pointer in circular gauge. */ CircularGauge.prototype.setPointerValue = function (axisIndex, pointerIndex, value) { var _this = this; var axis = this.axes[axisIndex]; var pointer = axis.pointers[pointerIndex]; var pointerRadius = pointer.currentRadius; this.allowLoadingAnimation = false; if (!this.isDestroyed && pointer.currentValue !== value) { var enableAnimation_1 = pointer.animation.enable || animationMode === 'Enable'; value = value < axis.visibleRange.min ? axis.visibleRange.min : value; value = value > axis.visibleRange.max ? axis.visibleRange.max : value; pointer['isPointerAnimation'] = true; document.getElementById(this.element.id + '_Axis_' + axisIndex + '_Pointer_' + pointerIndex).style.visibility = 'visible'; if (!isNullOrUndefined(pointer.pathElement)) { pointer.pathElement.map(function (element) { if (pointer.type === 'RangeBar') { setStyles(element, pointer.color, pointer.border); if (enableAnimation_1) { _this.gaugeAxisLayoutPanel.pointerRenderer.performRangeBarAnimation(element, pointer.currentValue, value, axis, pointer, axisIndex); } else { _this.isAnimationProgress = false; _this.gaugeAxisLayoutPanel.pointerRenderer.setPointerValue(axis, pointer, value); } } else { if (element.id.indexOf('_Pointer_NeedleCap_') >= 0) { setStyles(element, pointer.cap.color, pointer.cap.border); } else if (element.id.indexOf('_Pointer_NeedleTail_') >= 0) { setStyles(element, pointer.needleTail.color, pointer.needleTail.border); } else if (element.id.indexOf('_Pointer_NeedleRect_') >= 0) { setStyles(element, 'transparent', { color: 'transparent', width: 0 }); } else if (pointer.type === 'Marker' && pointer.markerShape !== 'Text') { setStyles(element, pointer.color, pointer.border); } if (enableAnimation_1) { if (pointer.type === 'Marker' && pointer.markerShape === 'Text') { _this.gaugeAxisLayoutPanel.pointerRenderer.performTextAnimation(element, pointer.currentValue, value, axis, pointer, axisIndex); } else { _this.gaugeAxisLayoutPanel.pointerRenderer.performNeedleAnimation(element, pointer.currentValue, value, axis, pointer, axisIndex); } } else { _this.gaugeAxisLayoutPanel.pointerRenderer.setPointerValue(axis, pointer, value); } } }); } if (this.allowLoadingAnimation && !pointer.animation.enable) { this.allowLoadingAnimation = false; pointer.value = value; } } this.isProtectedOnChange = true; pointer.previousValue = pointer.currentValue; pointer.currentValue = value; pointer.value = value; this.isProtectedOnChange = false; }; /** * This method is used to set the annotation content dynamically for circular gauge. * * @param {number} axisIndex - Specifies the index value for the axis in circular gauge. * @param {number} annotationIndex - Specifies the index value for the annotation in circular gauge. * @param {string | Function} content - Specifies the content for the annotation in circular gauge. * @returns {void} */ CircularGauge.prototype.setAnnotationValue = function (axisIndex, annotationIndex, content) { if (!this.isDestroyed) { this.allowLoadingAnimation = false; var isElementExist = getElement(this.element.id + '_Annotations_' + axisIndex) !== null; var element = getElement(this.element.id + '_Annotations_' + axisIndex) || createElement('div', { id: this.element.id + '_Annotations_' + axisIndex, styles: this.animationDuration > 0 ? 'opacity: 0' : 'opacity: 1' }); var annotation = this.axes[axisIndex].annotations[annotationIndex]; if (content !== null) { removeElement(this.element.id + '_Axis_' + axisIndex + '_Annotation_' + annotationIndex); annotation.content = content; this.annotationsModule.createTemplate(element, annotationIndex, axisIndex, this); var secondaryElement = getElement(this.element.id + '_Secondary_Element'); if (!isElementExist && !isNullOrUndefined(secondaryElement)) { secondaryElement.appendChild(element); } } } }; /** * This method is used to print the rendered circular gauge. * * @param {string[] | string | Element} id - Specifies the element to print the circular gauge. */ CircularGauge.prototype.print = function (id) { if (this.allowPrint && this.printModule) { this.printModule.print(this, id); } }; /** * This method is used to perform the export functionality for the circular gauge. * * @param {ExportType} type - Specifies the type of the export. * @param {string} fileName - Specifies the file name for the exported file. * @param {PdfPageOrientation} orientation - Specifies the orientation for the exported PDF document. * @param {boolean} allowDownload - Specifies whether to download as a file. * @returns {Promise<string>} - Specifies the base64 string of the exported image which is returned when the allowDownload is set to false. */ CircularGauge.prototype.export = function (type, fileName, orientation, allowDownload) { var _this = this; if (isNullOrUndefined(allowDownload)) { allowDownload = true; } if (type === 'PDF' && this.allowPdfExport && this.pdfExportModule) { // eslint-disable-next-line return new Promise(function (resolve, reject) { resolve(_this.pdfExportModule.export(_this, type, fileName, orientation, allowDownload)); }); } else if (this.allowImageExport && (type !== 'PDF') && this.imageExportModule) { // eslint-disable-next-line return new Promise(function (resolve, reject) { resolve(_this.imageExportModule.export(_this, type, fileName, allowDownload)); }); } return null; }; /** * Method to set mouse x, y from events * * @param {PointerEvent} e - Specifies the pointer event * @returns {void} */ CircularGauge.prototype.setMouseXY = function (e) { var pageX; var pageY; var svgRect = getElement(this.element.id + '_svg').getBoundingClientRect(); var rect = this.element.getBoundingClientRect(); if (e.type.indexOf('touch') > -1) { this.isTouch = true; var touchArg = e; pageY = touchArg.changedTouches[0].clientY; pageX = touchArg.changedTouches[0].clientX; } else { this.isTouch = e.pointerType === 'touch' || e.pointerType === '2'; pageX = e.clientX; pageY = e.clientY; } this.mouseY = (pageY - rect.top) - Math.max(svgRect.top - rect.top, 0); this.mouseX = (pageX - rect.left) - Math.max(svgRect.left - rect.left, 0); }; /** *