UNPKG

@syncfusion/ej2-circulargauge

Version:
592 lines (578 loc) 33.9 kB
/* eslint-disable max-len */ import { CircularGauge } from '../circular-gauge'; import { Axis, Pointer, Range, Annotation } from '../axes/axis'; import { Tooltip, TooltipTheme } from '@syncfusion/ej2-svg-base'; import { IVisiblePointer, ITooltipRenderEventArgs } from '../model/interface'; import { stringToNumber, getAngleFromValue, getLocationFromAngle, getPointer, getLabelFormat, Size, GaugeLocation, Rect, removeElement } from '../utils/helper-common'; import { getMousePosition, getElementSize } from '../utils/helper-tooltip'; import { TooltipSettings } from '../model/base'; import { FontModel, BorderModel } from '../model/base-model'; import { Browser, createElement, isNullOrUndefined, remove, SanitizeHtmlHelper } from '@syncfusion/ej2-base'; import { tooltipRender } from '../model/constants'; import { titleTooltip } from '../utils/helper-legend'; /** * Sets and gets the module that handles the tooltip of the circular gauge * * @hidden */ export class GaugeTooltip { private gauge: CircularGauge; private tooltipEle: HTMLElement; private currentAxis: Axis; private tooltip: TooltipSettings; private currentPointer: Pointer; private currentRange: Range; private currentAnnotation: Annotation; private svgTooltip: Tooltip; private tooltipId: string; private gaugeId: string; private tooltipPosition: string; private arrowInverted: boolean; private tooltipRect: Rect; private clearTimeout: number; private pointerEle: Element; private annotationTargetElement: HTMLElement; /** * Constructor for Tooltip module. * * @param {CircularGauge} gauge - Specifies the instance of the gauge. * @private. */ constructor(gauge: CircularGauge) { this.gauge = gauge; this.tooltipId = this.gauge.element.id + '_CircularGauge_Tooltip'; this.tooltip = <TooltipSettings>gauge.tooltip; this.addEventListener(); } /** * Method to render the tooltip for circular gauge. * * @param {PointerEvent} e - specifies the event argument. * @returns {void} * * @private */ public renderTooltip(e: PointerEvent): void { this.gaugeId = this.gauge.element.getAttribute('id'); let pageX: number; let pageY: number; let target: Element; let touchArg: TouchEvent; let location: GaugeLocation; let samePointerEle: boolean = false; let isTooltipRender: boolean = false; if (e.type.indexOf('touch') !== - 1) { touchArg = <TouchEvent & PointerEvent>e; target = <Element>touchArg.target; pageX = touchArg.changedTouches[0].pageX; pageY = touchArg.changedTouches[0].pageY; } else { target = <Element>e.target; pageX = e.pageX; pageY = e.pageY; } if ((this.tooltip.type.indexOf('Pointer') > -1) && (target.id.indexOf('_Pointer_') >= 0) && (target.id.indexOf(this.gaugeId) >= 0)) { if (this.pointerEle !== null) { samePointerEle = (this.pointerEle === target); } isTooltipRender = true; const svgRect: ClientRect = this.gauge.svgObject.getBoundingClientRect(); const elementRect: ClientRect = this.gauge.element.getBoundingClientRect(); const axisRect: ClientRect = document.getElementById(this.gauge.element.id + '_AxesCollection').getBoundingClientRect(); const rect: Rect = new Rect( Math.abs(elementRect.left - svgRect.left), Math.abs(elementRect.top - svgRect.top), svgRect.width, svgRect.height ); const currentPointer: IVisiblePointer = getPointer(target.id, this.gauge); this.currentAxis = <Axis>this.gauge.axes[currentPointer.axisIndex]; this.currentPointer = <Pointer>(this.currentAxis.pointers)[currentPointer.pointerIndex]; const angle: number = getAngleFromValue( this.currentPointer.currentValue, this.currentAxis.visibleRange.max, this.currentAxis.visibleRange.min, this.currentAxis.startAngle, this.currentAxis.endAngle, this.currentAxis.direction === 'ClockWise' ) % 360; const tooltipFormat: string = this.gauge.tooltip.format || this.currentAxis.labelStyle.format; const customLabelFormat: boolean = tooltipFormat && tooltipFormat.match('{value}') !== null; // eslint-disable-next-line @typescript-eslint/no-explicit-any const format: any = this.gauge.intl.getNumberFormat({ format: getLabelFormat(tooltipFormat), useGrouping: this.gauge.useGroupingSeparator }); this.tooltipElement(); if (this.tooltipEle.childElementCount !== 0 && !this.gauge.enablePointerDrag && !this.gauge.tooltip.showAtMousePosition) { return null; } const roundValue: number = this.roundedValue(this.currentPointer.currentValue); const pointerContent: string = customLabelFormat ? tooltipFormat.replace(new RegExp('{value}', 'g'), format(roundValue)) : format(roundValue); location = getLocationFromAngle(angle, this.currentAxis.currentRadius, this.gauge.midPoint); location.x = (this.tooltip.template && ((angle >= 150 && angle <= 250) || (angle >= 330 && angle <= 360) || (angle >= 0 && angle <= 45))) ? (location.x + 10) : location.x; // eslint-disable-next-line prefer-const let tooltipArgs: ITooltipRenderEventArgs = { name: tooltipRender, cancel: false, content: pointerContent, location: location, axis: this.currentAxis, tooltip: this.tooltip, pointer: this.currentPointer, event: e, gauge: this.gauge, appendInBodyTag: false, type: 'Pointer' }; // eslint-disable-next-line @typescript-eslint/no-explicit-any const pointerTooltip: any = (tooltipArgs: ITooltipRenderEventArgs) => { let template: string | Function = tooltipArgs.tooltip.template; if (template !== null && template.length === 1 && typeof template !== 'function') { template = template[template[0]]; } if (!tooltipArgs.tooltip.showAtMousePosition) { if (template) { const elementSize: Size = getElementSize(template, this.gauge, this.tooltipEle); this.tooltipRect = Math.abs(axisRect.left - svgRect.left) > elementSize.width ? this.findPosition(rect, angle, tooltipArgs.location, true) : rect; } else { this.findPosition(rect, angle, tooltipArgs.location, false); } } else { tooltipArgs.location = getMousePosition(pageX, pageY, this.gauge.svgObject); this.tooltipRect = rect; } if (!tooltipArgs.cancel && !samePointerEle) { const pointerTextStyle: FontModel = { color: tooltipArgs.tooltip.textStyle.color || this.gauge.themeStyle.tooltipFontColor, opacity: tooltipArgs.tooltip.textStyle.opacity || this.gauge.themeStyle.tooltipTextOpacity, fontFamily: tooltipArgs.tooltip.textStyle.fontFamily || this.gauge.themeStyle.fontFamily, fontWeight: tooltipArgs.tooltip.textStyle.fontWeight || this.gauge.themeStyle.fontWeight, fontStyle: tooltipArgs.tooltip.textStyle.fontStyle, size: tooltipArgs.tooltip.textStyle.size || this.gauge.themeStyle.tooltipFontSize }; this.svgTooltip = this.svgTooltipCreate(this.svgTooltip, tooltipArgs, template, this.arrowInverted, this.tooltipRect, this.gauge, tooltipArgs.tooltip.fill, pointerTextStyle, tooltipArgs.tooltip.border); this.svgTooltip.opacity = this.gauge.themeStyle.tooltipFillOpacity || this.svgTooltip.opacity; this.svgTooltip.appendTo(this.tooltipEle); if (template && (this.tooltipPosition === 'LeftTop' || this.tooltipPosition === 'LeftBottom')) { this.tooltipEle.style.left = (parseFloat(this.tooltipEle.style.left) - this.tooltipEle.getBoundingClientRect().width - 20) + 'px'; } if (template && Math.abs(pageY - this.tooltipEle.getBoundingClientRect().top) <= 0) { this.tooltipEle.style.top = (parseFloat(this.tooltipEle.style.top) + 20) + 'px'; } } }; this.gauge.trigger(tooltipRender, tooltipArgs, pointerTooltip); // eslint-disable-next-line @typescript-eslint/no-explicit-any (this.gauge as any).renderReactTemplates(); } else if ((this.tooltip.type.indexOf('Range') > -1) && (target.id.indexOf('_Range_') >= 0) && (!this.gauge.isDrag) && (target.id.indexOf(this.gaugeId) >= 0)) { isTooltipRender = true; const rangeSvgRect: ClientRect = this.gauge.svgObject.getBoundingClientRect(); const rangeElementRect: ClientRect = this.gauge.element.getBoundingClientRect(); const rangeAxisRect: ClientRect = document.getElementById(this.gauge.element.id + '_AxesCollection').getBoundingClientRect(); const rect: Rect = new Rect( Math.abs(rangeElementRect.left - rangeSvgRect.left), Math.abs(rangeElementRect.top - rangeSvgRect.top), rangeSvgRect.width, rangeSvgRect.height ); const currentRange: IVisiblePointer = getPointer(target.id, this.gauge); this.currentAxis = <Axis>this.gauge.axes[currentRange.axisIndex]; this.currentRange = <Range>(this.currentAxis.ranges)[currentRange.pointerIndex]; const rangeAngle: number = getAngleFromValue( (this.currentRange.end - Math.abs((this.currentRange.end - this.currentRange.start) / 2 ) ), this.currentAxis.visibleRange.max, this.currentAxis.visibleRange.min, this.currentAxis.startAngle, this.currentAxis.endAngle, this.currentAxis.direction === 'ClockWise' ) % 360; const rangeTooltipFormat: string = this.gauge.tooltip.rangeSettings.format || this.currentAxis.labelStyle.format; const customLabelFormat: boolean = rangeTooltipFormat && ( rangeTooltipFormat.match('{end}') !== null || rangeTooltipFormat.match('{start}') !== null ); // eslint-disable-next-line @typescript-eslint/no-explicit-any const rangeFormat: any = this.gauge.intl.getNumberFormat({ format: getLabelFormat(rangeTooltipFormat), useGrouping: this.gauge.useGroupingSeparator }); this.tooltipElement(); const roundStartValue: number = this.roundedValue(this.currentRange.start); const roundEndValue: number = this.roundedValue(this.currentRange.end); const startData: string = (this.currentRange.start).toString(); const endData: string = (this.currentRange.end).toString(); const rangeContent: string = customLabelFormat ? rangeTooltipFormat.replace(/{start}/g, startData).replace(/{end}/g, endData) : this.gauge.enableRtl ? 'Start:' + rangeFormat(roundStartValue) + ' <br>End:' + rangeFormat(roundEndValue) + ' ' : 'Start : ' + rangeFormat(roundStartValue) + '<br>' + 'End : ' + rangeFormat(roundEndValue); location = getLocationFromAngle( rangeAngle, this.currentRange.currentRadius, this.gauge.midPoint ); location.x = (this.tooltip.rangeSettings.template && ((rangeAngle >= 150 && rangeAngle <= 250) || (rangeAngle >= 330 && rangeAngle <= 360) || (rangeAngle >= 0 && rangeAngle <= 45))) ? (location.x + 10) : location.x; // eslint-disable-next-line prefer-const let rangeTooltipArgs: ITooltipRenderEventArgs = { name: tooltipRender, cancel: false, content: rangeContent, location: location, axis: this.currentAxis, tooltip: this.tooltip, range: this.currentRange, event: e, gauge: this.gauge, appendInBodyTag: false, type: 'Range' }; const rangeTooltipTextStyle: FontModel = { color: this.gauge.tooltip.rangeSettings.textStyle.color, opacity: this.gauge.tooltip.rangeSettings.textStyle.opacity, fontFamily: this.gauge.tooltip.rangeSettings.textStyle.fontFamily, fontStyle: this.gauge.tooltip.rangeSettings.textStyle.fontStyle, fontWeight: this.gauge.tooltip.rangeSettings.textStyle.fontWeight, size: this.gauge.tooltip.rangeSettings.textStyle.size }; // eslint-disable-next-line @typescript-eslint/no-explicit-any const rangeTooltip: any = (rangeTooltipArgs: ITooltipRenderEventArgs) => { let rangeTemplate: string | Function = rangeTooltipArgs.tooltip.rangeSettings.template; if (rangeTemplate !== null && rangeTemplate.length === 1 && typeof rangeTemplate !== 'function') { rangeTemplate = rangeTemplate[rangeTemplate[0]]; } if (typeof rangeTemplate !== 'function' && rangeTemplate) { rangeTemplate = rangeTemplate.replace(/[$]{start}/g, startData); rangeTemplate = rangeTemplate.replace(/[$]{end}/g , endData); } if (!this.tooltip.rangeSettings.showAtMousePosition) { if (rangeTemplate) { const elementSize: Size = getElementSize(rangeTemplate, this.gauge, this.tooltipEle); this.tooltipRect = Math.abs(rangeAxisRect.left - rangeSvgRect.left) > elementSize.width ? this.findPosition(rect, rangeAngle, rangeTooltipArgs.location, true) : rect; } else { this.findPosition(rect, rangeAngle, rangeTooltipArgs.location, false); } } else { rangeTooltipArgs.location = getMousePosition(pageX, pageY, this.gauge.svgObject); this.tooltipRect = rect; } if (!rangeTooltipArgs.cancel) { rangeTooltipTextStyle.color = rangeTooltipArgs.tooltip.rangeSettings.textStyle.color || this.gauge.themeStyle.tooltipFontColor; rangeTooltipTextStyle.fontFamily = rangeTooltipArgs.tooltip.rangeSettings.textStyle.fontFamily || this.gauge.themeStyle.fontFamily; rangeTooltipTextStyle.fontWeight = rangeTooltipArgs.tooltip.rangeSettings.textStyle.fontWeight || this.gauge.themeStyle.fontWeight; rangeTooltipTextStyle.opacity = rangeTooltipArgs.tooltip.rangeSettings.textStyle.opacity || this.gauge.themeStyle.tooltipTextOpacity; rangeTooltipTextStyle.size = rangeTooltipArgs.tooltip.rangeSettings.textStyle.size || this.gauge.themeStyle.tooltipFontSize; this.svgTooltip = this.svgTooltipCreate (this.svgTooltip, rangeTooltipArgs, rangeTemplate, this.arrowInverted, this.tooltipRect, this.gauge, rangeTooltipArgs.tooltip.rangeSettings.fill, rangeTooltipTextStyle, rangeTooltipArgs.tooltip.rangeSettings.border); this.svgTooltip.opacity = this.gauge.themeStyle.tooltipFillOpacity || this.svgTooltip.opacity; this.svgTooltip.appendTo(this.tooltipEle); if (rangeTemplate && (this.tooltipPosition === 'LeftTop' || this.tooltipPosition === 'LeftBottom')) { this.tooltipEle.style.left = (parseFloat(this.tooltipEle.style.left) - this.tooltipEle.getBoundingClientRect().width - 20) + 'px'; } if (rangeTemplate && Math.abs(pageY - this.tooltipEle.getBoundingClientRect().top) <= 0) { this.tooltipEle.style.top = (parseFloat(this.tooltipEle.style.top) + 20) + 'px'; } } }; this.gauge.trigger(tooltipRender, rangeTooltipArgs, rangeTooltip); // eslint-disable-next-line @typescript-eslint/no-explicit-any (this.gauge as any).renderReactTemplates(); } else if ((this.tooltip.type.indexOf('Annotation') > -1) && this.checkParentAnnotationId(target) && ((!this.gauge.isDrag)) && (this.annotationTargetElement.id.indexOf(this.gaugeId) >= 0)) { isTooltipRender = true; const annotationSvgRect: ClientRect = this.gauge.svgObject.getBoundingClientRect(); const annotationElementRect: ClientRect = this.gauge.element.getBoundingClientRect(); const rect: Rect = new Rect( Math.abs(annotationElementRect.left - annotationSvgRect.left), Math.abs(annotationElementRect.top - annotationSvgRect.top), annotationSvgRect.width, annotationSvgRect.height ); const currentAnnotation: IVisiblePointer = getPointer(this.annotationTargetElement.id, this.gauge); this.currentAxis = <Axis>this.gauge.axes[currentAnnotation.axisIndex]; this.currentAnnotation = <Annotation>(this.currentAxis.annotations)[currentAnnotation.pointerIndex]; const annotationAngle: number = (this.currentAnnotation.angle - 90); this.tooltipElement(); document.getElementById(this.gauge.element.id + '_Secondary_Element').appendChild(this.tooltipEle); const annotationContent: string = (this.gauge.tooltip.annotationSettings.format !== null) ? this.gauge.tooltip.annotationSettings.format : '' ; location = getLocationFromAngle( annotationAngle, stringToNumber(this.currentAnnotation.radius, this.currentAxis.currentRadius), this.gauge.midPoint ); location.x = (this.tooltip.annotationSettings.template && ((annotationAngle >= 150 && annotationAngle <= 250) || (annotationAngle >= 330 && annotationAngle <= 360) || (annotationAngle >= 0 && annotationAngle <= 45))) ? (location.x + 10) : location.x; // eslint-disable-next-line prefer-const let annotationTooltipArgs: ITooltipRenderEventArgs = { name: tooltipRender, cancel: false, content: annotationContent, location: location, axis: this.currentAxis, tooltip: this.tooltip, annotation: this.currentAnnotation, event: e, gauge: this.gauge, appendInBodyTag: false, type: 'Annotation' }; // eslint-disable-next-line @typescript-eslint/no-explicit-any const annotationTooltip: any = (annotationTooltipArgs: ITooltipRenderEventArgs) => { let annotationTemplate: string | Function = annotationTooltipArgs.tooltip.annotationSettings.template; if (annotationTemplate !== null && annotationTemplate.length === 1 && typeof annotationTemplate !== 'function') { annotationTemplate = annotationTemplate[annotationTemplate[0]]; } const elementSizeAn: ClientRect = this.annotationTargetElement.getBoundingClientRect(); this.tooltipPosition = 'RightTop'; this.arrowInverted = true; annotationTooltipArgs.location.x = annotationTooltipArgs.location.x + (elementSizeAn.width / 2); this.tooltipRect = new Rect(rect.x, rect.y, rect.width, rect.height); if (!annotationTooltipArgs.cancel && ( this.gauge.tooltip.annotationSettings.format !== null || this.gauge.tooltip.annotationSettings.template !== null)) { const annotationTextStyle: FontModel = { color: annotationTooltipArgs.tooltip.textStyle.color || this.gauge.themeStyle.tooltipFontColor, fontFamily: annotationTooltipArgs.tooltip.textStyle.fontFamily || this.gauge.themeStyle.fontFamily, fontWeight: annotationTooltipArgs.tooltip.textStyle.fontWeight || this.gauge.themeStyle.fontWeight, opacity: annotationTooltipArgs.tooltip.textStyle.opacity || this.gauge.themeStyle.tooltipTextOpacity, fontStyle: annotationTooltipArgs.tooltip.textStyle.fontStyle, size: annotationTooltipArgs.tooltip.textStyle.size || this.gauge.themeStyle.tooltipFontSize }; this.svgTooltip = this.svgTooltipCreate(this.svgTooltip, annotationTooltipArgs, annotationTemplate, this.arrowInverted, this.tooltipRect, this.gauge, annotationTooltipArgs.tooltip.annotationSettings.fill, annotationTextStyle, annotationTooltipArgs.tooltip.annotationSettings.border); this.svgTooltip.opacity = this.gauge.themeStyle.tooltipFillOpacity || this.svgTooltip.opacity; this.svgTooltip.appendTo(this.tooltipEle); if (annotationTemplate && Math.abs(pageY - this.tooltipEle.getBoundingClientRect().top) <= 0) { this.tooltipEle.style.top = (parseFloat(this.tooltipEle.style.top) + 20) + 'px'; } } }; this.gauge.trigger(tooltipRender, annotationTooltipArgs, annotationTooltip); // eslint-disable-next-line @typescript-eslint/no-explicit-any (this.gauge as any).renderReactTemplates(); } else if ((target.id === (this.gauge.element.id + '_CircularGaugeTitle') || target.id.indexOf('_gauge_legend_') > -1) && ((<HTMLElement>e.target).textContent.indexOf('...') > -1)) { titleTooltip(e, pageX, pageY, this.gauge, false); } else { const isTooltipRemoved: boolean = this.removeTooltip(); if (isTooltipRemoved) { // eslint-disable-next-line @typescript-eslint/no-explicit-any if (((this.gauge as any).isVue || (this.gauge as any).isVue3)) { // eslint-disable-next-line @typescript-eslint/no-explicit-any (this.gauge as any).clearTemplate([this.tooltipEle.children[0].id], [0]); // eslint-disable-next-line @typescript-eslint/no-explicit-any } else if (!(this.gauge as any).isAngular) { // eslint-disable-next-line @typescript-eslint/no-explicit-any (this.gauge as any).clearTemplate(); } } } const gaugeElement: HTMLElement = document.getElementById(this.gaugeId); const gaugeRect: ClientRect = gaugeElement.getBoundingClientRect(); const tooltipRect: ClientRect = isTooltipRender ? this.tooltipEle.getBoundingClientRect() : null; if (isTooltipRender && this.tooltipEle.offsetLeft < 0 && (tooltipRect.left - gaugeRect.left) < 0){ const tooltipLeft: string = this.tooltipEle.style.left.split('px')[0]; this.tooltipEle.style.left = parseInt(tooltipLeft, 10) + (gaugeRect.left - tooltipRect.left) + 'px'; } if (isTooltipRender && tooltipRect.top < 0) { this.tooltipEle.style.top = 0 + 'px'; } } /** * Method to create tooltip svg element. * * @param {Tooltip} svgTooltip - Specifies the tooltip element. * @param {ITooltipRenderEventArgs} tooltipArg - Specifies the tooltip arguments. * @param {string} template - Specifies the tooltip template. * @param {boolean} arrowInverted - Specifies the boolean value. * @param {Rect} tooltipRect - Specifies the rect element. * @param {CircularGauge} gauge - Specifies the gauge instance. * @param {string} fill - Spcifies the fill color of the tooltip. * @param {FontModel} textStyle - Spcifies the text style of the tooltip. * @param {BorderModel} border - Specifies the border of the tooltip. * @returns {Tooltip} - Returns the tooltip. */ private svgTooltipCreate(svgTooltip: Tooltip, tooltipArg: ITooltipRenderEventArgs, template: string | Function, arrowInverted: boolean, tooltipRect: Rect, gauge: CircularGauge, fill: string, textStyle: FontModel, border: BorderModel ): Tooltip { const borderObject: BorderModel = { color: border.color || this.gauge.themeStyle.tooltipBorderColor || '', width: border.width, dashArray: border.dashArray }; svgTooltip = new Tooltip({ theme: gauge.theme as TooltipTheme, enable: true, data: { value: tooltipArg.content }, // eslint-disable-next-line @typescript-eslint/no-explicit-any template: template as any, enableRTL: gauge.enableRtl, enableAnimation: tooltipArg.tooltip.enableAnimation, content: [SanitizeHtmlHelper.sanitize(tooltipArg.content)], location: tooltipArg.location, inverted: arrowInverted, areaBounds: tooltipRect, fill: fill || gauge.themeStyle.tooltipFillColor, textStyle: textStyle, availableSize: gauge.availableSize, border: borderObject, enableShadow: true }); // eslint-disable-next-line @typescript-eslint/no-explicit-any if (((gauge as any).isVue || (gauge as any).isVue3)) { svgTooltip.controlInstance = gauge; } return svgTooltip; } /** * Method to create or modify tolltip element. * * @returns {void} */ private tooltipElement(): void { if (document.getElementById(this.tooltipId)) { this.tooltipEle = document.getElementById(this.tooltipId); } else { this.tooltipEle = createElement('div', { id: this.tooltipId, className: 'EJ2-CircularGauge-Tooltip' }); this.tooltipEle.style.cssText = 'position: absolute;pointer-events:none;'; document.getElementById(this.gauge.element.id + '_Secondary_Element').appendChild(this.tooltipEle); } } /** * Method to get parent annotation element. * * @param {Element} child - Specifies the annotation element. * @returns {boolean} - Returns the boolean value. */ private checkParentAnnotationId(child: Element ): boolean { this.annotationTargetElement = child.parentElement; while ( this.annotationTargetElement != null) { if (( this.annotationTargetElement.id.indexOf('_Annotation_') >= 0)) { child = this.annotationTargetElement; return true; } this.annotationTargetElement = this.annotationTargetElement.parentElement; } return false; } /** * Method to apply label rounding places. * * @param {number} currentValue - Specifies the current value. * @returns {number} - Returns the round number. */ private roundedValue(currentValue: number): number { const roundNumber: number = this.currentAxis.roundingPlaces ? parseFloat(currentValue.toFixed(this.currentAxis.roundingPlaces)) : currentValue; return roundNumber; } /** * Method to find the position of the tooltip anchor for circular gauge. * * @param {Rect} rect - Specifies the rect element. * @param {number} angle - Specifies the angle. * @param {GaugeLocation} location - Specifies the location. * @param {boolean} isTemplate - whether it is template or not . * @returns {Rect} - Returns the rect element. */ private findPosition(rect: Rect, angle: number, location: GaugeLocation, isTemplate: boolean): Rect { let addLeft: number; let addTop: number; let addHeight: number; let addWidth: number; const padding: number = 10; switch (true) { case (angle >= 0 && angle < 45): this.arrowInverted = true; addLeft = (angle >= 15 && angle <= 30) ? location.y : 0; this.tooltipRect = new Rect(rect.x, rect.y + addTop, rect.width, rect.height); this.tooltipPosition = 'RightBottom'; break; case (angle >= 45 && angle < 90): this.arrowInverted = false; this.tooltipRect = new Rect(rect.x, rect.y + location.y, rect.width, rect.height); this.tooltipPosition = 'BottomRight'; break; case (angle >= 90 && angle < 135): this.arrowInverted = false; this.tooltipRect = new Rect(rect.x, rect.y + location.y, rect.width, rect.height); this.tooltipPosition = 'BottomLeft'; break; case (angle >= 135 && angle < 180): this.arrowInverted = isTemplate ? true : isTemplate; addTop = (angle >= 150 && angle <= 160 && isTemplate) ? location.y : 0; this.tooltipRect = new Rect(rect.x, rect.y + addTop, rect.width, rect.height); this.tooltipPosition = 'LeftBottom'; break; case (angle >= 180 && angle < 225): this.arrowInverted = true; addHeight = (angle >= 200 && angle <= 225) ? Math.abs(rect.y - location.y) : rect.height; this.tooltipRect = new Rect(rect.x - location.x, rect.y, rect.width, addHeight); this.tooltipPosition = 'LeftTop'; break; case (angle >= 225 && angle < 270): this.arrowInverted = false; addWidth = (angle >= 250 && angle <= 290) ? rect.width : Math.abs(rect.x - location.x); this.tooltipRect = new Rect(rect.x + padding, rect.y, addWidth, rect.height); this.tooltipPosition = 'TopLeft'; break; case (angle >= 270 && angle < 315): this.arrowInverted = false; addLeft = (angle >= 270 && angle > 290) ? location.x - padding : 0; this.tooltipRect = new Rect(rect.x + addLeft, rect.y, rect.width, rect.height); this.tooltipPosition = 'TopRight'; break; case (angle >= 315 && angle <= 360): this.arrowInverted = true; addHeight = (angle >= 315 && angle <= 340) ? Math.abs(rect.y - location.y) : rect.height; this.tooltipRect = new Rect(rect.x, rect.y, rect.width, addHeight); this.tooltipPosition = 'RightTop'; break; } return this.tooltipRect; } public removeTooltip(): boolean { let isTooltipRemoved: boolean = false; if (document.getElementsByClassName('EJ2-CircularGauge-Tooltip').length > 0) { const tooltip: Element = document.getElementsByClassName('EJ2-CircularGauge-Tooltip')[0]; if (tooltip) { remove(tooltip); isTooltipRemoved = true; } this.pointerEle = null; } return isTooltipRemoved; } public mouseUpHandler(e: PointerEvent): void { this.removeTooltip(); this.renderTooltip(e); clearTimeout(this.clearTimeout); this.clearTimeout = setTimeout(this.removeTooltip.bind(this), 2000); } // eslint-disable-next-line valid-jsdoc /** * To bind events for tooltip module * * @private */ public addEventListener(): void { if (this.gauge.isDestroyed) { return; } this.gauge.on(Browser.touchMoveEvent, this.renderTooltip, this); this.gauge.on(Browser.touchEndEvent, this.mouseUpHandler, this); this.gauge.element.addEventListener('contextmenu', this.removeTooltip); } // eslint-disable-next-line valid-jsdoc /** * To unbind events for tooltip module * * @private */ public removeEventListener(): void { if (this.gauge) { if (this.gauge.isDestroyed) { return; } this.gauge.off(Browser.touchMoveEvent, this.renderTooltip); this.gauge.off(Browser.touchEndEvent, this.mouseUpHandler); this.gauge.element.removeEventListener('contextmenu', this.removeTooltip); } } /** * Get module name. * * @returns {string} - Returns the module name */ protected getModuleName(): string { // Returns te module name return 'Tooltip'; } /** * To destroy the tooltip. * * @returns {void} * @private */ public destroy(): void { this.tooltipEle = null; this.currentAxis = null; this.tooltip = null; this.currentPointer = null; this.currentRange = null; this.currentAnnotation = null; if (!isNullOrUndefined(this.svgTooltip)) { this.svgTooltip.destroy(); this.svgTooltip.controlInstance = null; removeElement(this.tooltipId); } this.svgTooltip = null; this.tooltipRect = null; this.pointerEle = null; this.annotationTargetElement = null; this.gauge = null; } }