UNPKG

@syncfusion/ej2-circulargauge

Version:
689 lines (688 loc) 42.8 kB
import { stringToNumber, toPixel, textElement, appendPath, getAngleFromValue, getLocationFromAngle, getPathArc, getRoundedPathArc, getDegree, isCompleteAngle, PathOption, TextOption } from '../utils/helper-common'; import { getRangeColor } from '../utils/helper-axis-renderer'; import { getRangePalette } from '../model/theme'; import { isNullOrUndefined } from '@syncfusion/ej2-base'; /** * Specifies the Axis rendering for circular gauge */ var AxisRenderer = /** @class */ (function () { /** * Constructor for axis renderer. * * @param {CircularGauge} gauge - Specifies the instance of the gauge * @private. */ function AxisRenderer(gauge) { this.gauge = gauge; } /** * Method to render the axis element of the circular gauge. * * @param {Axis} axis - Specifies the axis. * @param {number} index - Specifies the index. * @param {Element} element - Specifies the element. * @param {CircularGauge} gauge - Specifies the gauge. * @returns {void} * @private */ AxisRenderer.prototype.drawAxisOuterLine = function (axis, index, element, gauge) { var background = axis.background; this.setRangeColor(axis); if (background !== null) { appendPath(new PathOption(gauge.element.id + '_AxisOuterLine_' + index, background, 0, 'transparent', null, '0', getPathArc(gauge.midPoint, 0, 360, (Math.min(axis.rect.width, axis.rect.height) / 2)), '', 'pointer-events:none;'), element, gauge); } }; /** * Method to check the angles. * * @param {Axis} axis - Specifies the axis. * @returns {void} * @private */ AxisRenderer.prototype.checkAngles = function (axis) { axis.startAngle = axis.startAngle >= 360 ? 360 : axis.startAngle <= -360 ? -360 : axis.startAngle; axis.endAngle = axis.endAngle >= 360 ? 360 : axis.endAngle <= -360 ? -360 : axis.endAngle; }; /** * Method to render the axis line of the circular gauge. * * @param {Axis} axis - Specifies the axis. * @param {number} index - Specifies the index. * @param {Element} element - Specifies the element. * @param {CircularGauge} gauge - Specifies the gauge. * @returns {void} * @private */ AxisRenderer.prototype.drawAxisLine = function (axis, index, element, gauge) { var startAngle = axis.startAngle; var endAngle = axis.endAngle; var color = axis.lineStyle.color || this.gauge.themeStyle.lineColor; if (axis.lineStyle.width > 0 && this.gauge.allowComponentRender) { startAngle = !isCompleteAngle(startAngle, endAngle) ? startAngle : [0, endAngle = 360][0]; appendPath(new PathOption(gauge.element.id + '_AxisLine_' + index, 'transparent', axis.lineStyle.width, color, null, axis.lineStyle.dashArray, getPathArc(gauge.midPoint, startAngle - 90, endAngle - 90, axis.currentRadius), '', gauge.allowLoadingAnimation ? 'visibility: hidden; pointer-events:none;' : 'pointer-events:none;'), element, gauge); } }; /** * Method to render the axis labels of the circular gauge. * * @param {Axis} axis - Specifies the axis. * @param {number} index - Specifies the index. * @param {Element} element - Specifies the element. * @param {CircularGauge} gauge - Specifies the gauge. * @returns {void} * @private */ AxisRenderer.prototype.drawAxisLabels = function (axis, index, element, gauge) { var labelElement = gauge.renderer.createGroup({ id: gauge.element.id + '_Axis_Labels_' + index, style: gauge.allowLoadingAnimation ? 'visibility: hidden;' : 'pointer-events:auto;' }); var min = axis.visibleRange.min; var max = axis.visibleRange.max; var labelCollection = axis.visibleLabels; var location; var textWidth; var textHeight; var labelsVisible = true; var currentTextWidth; var currentTextHeight; var previousLocation; var currentLocation; var lastLabelLocation; var lastLabelAngle; var lastLabelAnchor; var lastTextWidth; var lastTextHeight; var style = axis.labelStyle; var anchor; var angle; var label; var radius = axis.currentRadius; var checkLabelOpposed = 0; checkLabelOpposed = (style.position === 'Inside' && axis.majorTicks.position === 'Outside' && axis.minorTicks.position === 'Outside') || (style.position === 'Outside' && axis.minorTicks.position === 'Inside' && axis.majorTicks.position === 'Inside') ? axis.lineStyle.width + axis.currentRadius / 20 : (style.position === axis.majorTicks.position ? axis.currentRadius / 20 : axis.currentRadius / 40); var labelPadding = axis.labelStyle.shouldMaintainPadding ? 10 : checkLabelOpposed; var color = style.font.color || this.gauge.themeStyle.labelColor; if (style.position === 'Outside') { radius += (axis.nearSize - (axis.maxLabelSize.height + axis.lineStyle.width / 2)) + (labelPadding / 2); } else if (style.position === 'Cross') { radius = radius - (axis.maxLabelSize.height / 4) - axis.labelStyle.offset; } else { radius -= (axis.farSize - (axis.maxLabelSize.height + axis.lineStyle.width / 2) + (style.autoAngle ? labelPadding : 0)); } //To get and store lastlabelposition if (axis.hideIntersectingLabel) { lastLabelAngle = Math.round(getAngleFromValue(labelCollection[labelCollection.length - 1].value, max, min, axis.startAngle, axis.endAngle, axis.direction === 'ClockWise')); lastLabelLocation = getLocationFromAngle(lastLabelAngle, radius, gauge.midPoint); lastLabelAnchor = this.findAnchor(lastLabelLocation, style, lastLabelAngle, labelCollection[labelCollection.length - 1]); lastTextWidth = (!axis.showLastLabel && (isCompleteAngle(axis.startAngle, axis.endAngle)) && (style.hiddenLabel !== 'First')) ? labelCollection[0].size.width : labelCollection[labelCollection.length - 1].size.width; lastTextHeight = (!axis.showLastLabel && (isCompleteAngle(axis.startAngle, axis.endAngle)) && (style.hiddenLabel !== 'First')) ? (!style.autoAngle ? labelCollection[0].size.height : labelCollection[0].size.width) : (!style.autoAngle ? labelCollection[labelCollection.length - 1].size.height : labelCollection[labelCollection.length - 1].size.width); lastTextHeight = lastTextHeight - this.offsetAxisLabelsize(lastLabelAngle, lastTextHeight); lastLabelLocation = this.getAxisLabelStartPosition(lastLabelLocation, lastTextWidth, lastLabelAnchor); } for (var i = 0, length_1 = labelCollection.length; i < length_1; i++) { label = labelCollection[i]; angle = Math.round(getAngleFromValue(label.value, max, min, axis.startAngle, axis.endAngle, axis.direction === 'ClockWise')); location = getLocationFromAngle(angle, radius, gauge.midPoint); anchor = this.findAnchor(location, style, angle, label); //To get the current label and previous label position for initial stage if (axis.hideIntersectingLabel) { currentLocation = getLocationFromAngle(angle, radius, gauge.midPoint); currentTextWidth = label.size.width; currentTextHeight = !style.autoAngle ? label.size.height : currentTextWidth; currentTextHeight = currentTextHeight - this.offsetAxisLabelsize(angle, currentTextHeight); currentLocation = this.getAxisLabelStartPosition(currentLocation, currentTextWidth, anchor); if (i === 0) { previousLocation = getLocationFromAngle(angle, radius, gauge.midPoint); textWidth = label.size.width; textHeight = !style.autoAngle ? label.size.height : textWidth; textHeight = textHeight - this.offsetAxisLabelsize(angle, textHeight); previousLocation = this.getAxisLabelStartPosition(previousLocation, textWidth, anchor); } } if ((i === 0 && style.hiddenLabel === 'First') || (i === (length_1 - 1) && style.hiddenLabel === 'Last')) { continue; } var textFont = { size: style.font.size || this.gauge.themeStyle.fontSize, color: style.font.color, fontFamily: style.font.fontFamily || this.gauge.themeStyle.labelFontFamily, fontWeight: style.font.fontWeight || this.gauge.themeStyle.fontWeight, fontStyle: style.font.fontStyle, opacity: style.font.opacity }; if (axis.hideIntersectingLabel && (i !== 0)) { //To remove the labels which is intersecting with last label. var lastlabel = ((i !== (labelCollection.length - 1)) && ((isCompleteAngle(axis.startAngle, axis.endAngle) || axis.showLastLabel))) ? this.FindAxisLabelCollision(lastLabelLocation, lastTextWidth, lastTextHeight, currentLocation, currentTextWidth, currentTextHeight) : true; //Checking wether the axis label is intersecting with previous label or not. labelsVisible = (this.FindAxisLabelCollision(previousLocation, textWidth, textHeight, currentLocation, currentTextWidth, currentTextHeight) && lastlabel); } else { labelsVisible = true; } if (labelsVisible || (i === labelCollection.length - 1)) { //To hide first and last label based on requirement label.text = (!axis.showLastLabel && ((isCompleteAngle(axis.startAngle, axis.endAngle) && style.hiddenLabel !== 'First') || !labelsVisible) && axis.hideIntersectingLabel && (i === (length_1 - 1))) ? '' : label.text; label.text = (axis.showLastLabel && axis.hideIntersectingLabel && isCompleteAngle(axis.startAngle, axis.endAngle) && (i === 0)) ? '' : label.text; var labelTextElement = textElement(new TextOption(gauge.element.id + '_Axis_' + index + '_Label_' + i, location.x, location.y, anchor, label.text, style.autoAngle ? 'rotate(' + (angle + 90) + ',' + (location.x) + ',' + location.y + ')' : '', 'auto'), textFont, style.useRangeColor ? getRangeColor(label.value, axis.ranges, color) : color, labelElement, 'pointer-events:auto;'); labelTextElement.setAttribute('aria-label', label.text); labelTextElement.setAttribute('role', 'region'); if (axis.hideIntersectingLabel) { textWidth = label.size.width; textHeight = !style.autoAngle ? label.size.height : textWidth; textHeight = textHeight - this.offsetAxisLabelsize(angle, textHeight); previousLocation.x = currentLocation.x; previousLocation.y = currentLocation.y; } } } element.appendChild(labelElement); }; /** * Method to find the anchor of the axis label. * * @param {GaugeLocation} location - Specifies the location. * @param {Label} style - Specifies the label style. * @param {number} angle - Specifies the angle. * @param {VisibleLabels} label - Specifies the labels. * @returns {string} - Returns the anchor. * @private */ AxisRenderer.prototype.findAnchor = function (location, style, angle, label) { if (style.autoAngle) { return 'middle'; } var anchor = style.position === 'Inside' ? ((angle > 120 && angle < 240) ? 'start' : ((300 < angle || angle < 60) ? 'end' : 'middle')) : ((angle > 120 && angle < 240) ? 'end' : ((300 < angle || angle < 60) ? 'start' : 'middle')); location.y += style.position === 'Inside' ? ((angle >= 240 && angle <= 300) ? (label.size.height / 2) : (angle >= 60 && angle <= 120) ? 0 : label.size.height / 4) : ((angle >= 240 && angle <= 300) ? 0 : (angle >= 60 && angle <= 120) ? label.size.height / 2 : label.size.height / 4); return anchor; }; /** * Methode to check whether the labels are intersecting or not. * * @param {GaugeLocation} previousLocation - Specifies the previous location. * @param {number} previousWidth - Specifies the previous width. * @param {number} previousHeight - Specifies the previous height. * @param {GaugeLocation} currentLocation - Specifies the current location. * @param {number} currentWidth - Specifies the current width. * @param {number} currentHeight - Specifies the current height. * @returns {boolean} - Returns the boolean value. * @private */ AxisRenderer.prototype.FindAxisLabelCollision = function (previousLocation, previousWidth, previousHeight, currentLocation, currentWidth, currentHeight) { var labelVisisble = ((previousLocation.x > (currentLocation.x + (currentWidth))) || ((previousLocation.x + (previousWidth)) < (currentLocation.x)) || ((previousLocation.y + (previousHeight)) < (currentLocation.y)) || ((previousLocation.y) > (currentLocation.y + (currentHeight)))); return labelVisisble; }; /** * Methode to get anchor position of label as start. * * @param {GaugeLocation} actualLocation - Specifies the actual location. * @param {number} textWidth - Specifies the text width. * @param {string} anchorPosition - Specifies the anchor position. * @returns {GaugeLocation} - Returns the gauge location. * @private */ AxisRenderer.prototype.getAxisLabelStartPosition = function (actualLocation, textWidth, anchorPosition) { if (anchorPosition === 'end') { actualLocation.x = actualLocation.x - textWidth; } else if (anchorPosition === 'middle') { actualLocation.x = actualLocation.x - (textWidth / 2); } return actualLocation; }; /** * Methode to offset label height and width based on angle. * * @param {number} angle - Specifies the angle. * @param {number} size - Specifies the size. * @returns {number} - Returns the fineal size. * @private */ AxisRenderer.prototype.offsetAxisLabelsize = function (angle, size) { var finalSize = ((angle >= 20 && angle <= 60) || (angle >= 120 && angle <= 160) || (angle >= 200 && angle <= 240) || (angle >= 300 && angle <= 340)) ? size / 5 : 0; return finalSize; }; /** * Method to render the axis minor tick lines of the circular gauge. * * @param {Axis} axis - Specifies the axis. * @param {number} index - Specifies the index. * @param {Element} element - Specifies the element. * @param {CircularGauge} gauge - Specifies the gauge. * @returns {void} * @private */ AxisRenderer.prototype.drawMinorTickLines = function (axis, index, element, gauge) { var minorTickElements = gauge.renderer.createGroup({ id: gauge.element.id + '_Axis_MinorTickLines_' + index }); var minorLineStyle = axis.minorTicks; var minorInterval = minorLineStyle.interval !== null ? minorLineStyle.interval : (axis.visibleRange.interval / 2); var isRangeColor = minorLineStyle.useRangeColor; var color = minorLineStyle.color || this.gauge.themeStyle.minorTickColor; if (minorLineStyle.width && minorLineStyle.height && minorInterval) { var j = 0; for (var i = axis.visibleRange.min, max = axis.visibleRange.max; i <= max; i += minorInterval) { if (this.majorValues.indexOf(+i.toFixed(3)) < 0) { var tickElement = appendPath(new PathOption(gauge.element.id + '_Axis_Minor_TickLine_' + index + '_' + j++, 'transparent', minorLineStyle.width, isRangeColor ? getRangeColor(i, axis.ranges, color) : color, null, minorLineStyle.dashArray, this.calculateTicks(i, minorLineStyle, axis), '', gauge.allowLoadingAnimation ? 'visibility: hidden;pointer-events: auto;' : 'pointer-events:auto;'), minorTickElements, gauge); tickElement.setAttribute('data-interval', i.toString()); } } element.appendChild(minorTickElements); } }; /** * Method to render the axis major tick lines of the circular gauge. * * @param {Axis} axis - Specifies the axis. * @param {number} index - Specifies the index. * @param {Element} element - Specifies the element. * @param {CircularGauge} gauge - Specifies the gauge. * @returns {void} * @private */ AxisRenderer.prototype.drawMajorTickLines = function (axis, index, element, gauge) { var majorTickElements = gauge.renderer.createGroup({ id: gauge.element.id + '_Axis_MajorTickLines_' + index }); var majorLineStyle = axis.majorTicks; var isRangeColor = majorLineStyle.useRangeColor; this.majorValues = []; var color = majorLineStyle.color || this.gauge.themeStyle.majorTickColor; if (majorLineStyle.width && majorLineStyle.height && axis.visibleRange.interval) { var j = 0; for (var i = axis.visibleRange.min, max = axis.visibleRange.max, interval = axis.visibleRange.interval; i <= max; i += interval) { this.majorValues.push(+i.toFixed(3)); var tickElement = appendPath(new PathOption(gauge.element.id + '_Axis_Major_TickLine_' + index + '_' + j, 'transparent', majorLineStyle.width, isRangeColor ? getRangeColor(i, axis.ranges, color) : color, null, majorLineStyle.dashArray, this.calculateTicks(i, majorLineStyle, axis), '', gauge.allowLoadingAnimation ? 'visibility: hidden;pointer-events:auto;' : 'pointer-events:auto;'), majorTickElements, gauge); tickElement.setAttribute('data-interval', i.toString()); j++; } element.appendChild(majorTickElements); } }; /** * Method to calcualte the tick elements for the circular gauge. * * @param {number} value - Specifies the value. * @param {Tick} options - Specifies the options. * @param {Axis} axis - Specifies the axis. * @returns {string} - Returns the string. * @private */ AxisRenderer.prototype.calculateTicks = function (value, options, axis) { var axisLineWidth = (axis.lineStyle.width / 2) + options.offset; var angle = getAngleFromValue(value, axis.visibleRange.max, axis.visibleRange.min, axis.startAngle, axis.endAngle, axis.direction === 'ClockWise'); var start = getLocationFromAngle(angle, axis.currentRadius + (options.position === 'Outside' ? axisLineWidth : options.position === 'Cross' ? options.height / 2 - options.offset : -axisLineWidth), this.gauge.midPoint); var end = getLocationFromAngle(angle, axis.currentRadius + (options.position === 'Outside' ? axisLineWidth : options.position === 'Cross' ? options.height / 2 - options.offset : -axisLineWidth) + (options.position === 'Outside' ? options.height : -options.height), this.gauge.midPoint); return 'M ' + start.x + ' ' + start.y + ' L ' + end.x + ' ' + end.y + ' '; }; /** * Method to render the range path of the circular gauge. * * @param {Axis} axis - Specifies the axis. * @param {Range} range - Specifies the range. * @param {number} startWidth - Specifies the startwidth for the range. * @param {number} endWidth - Specifies the endwidth for the range. * @param {number} rangeIndex - Specifies the index of the range. * @param {number} index - Specifies the index of the axis. * @param {Element} rangeElement - Specifies the element. * @param {number} colorIndex - Specifies the index of the lineargradient colorstop. * @returns {void} * @private */ AxisRenderer.prototype.drawRangePath = function (axis, range, startWidth, endWidth, rangeIndex, index, rangeElement, colorIndex) { var startValue; var direction; var endValue; var location = this.gauge.midPoint; var startAngle; var endAngle; var isClockWise = axis.direction === 'ClockWise'; var min = axis.visibleRange.min; var max = axis.visibleRange.max; var roundedStartAngle; var roundedEndAngle; var oldStart; var oldEnd; var gradientRangeColor; if (range.isLinearCircularGradient) { var rangeSplitValue = ((range.end - range.start) / range.linearGradient.colorStop.length); var rangeStart = range.linearGradient.colorStop.length > 1 ? (range.start + (rangeSplitValue * (colorIndex))) : range.start; var rangeEnd = range.linearGradient.colorStop.length > 1 ? (rangeStart + rangeSplitValue) : range.end; startValue = Math.min(Math.max(rangeStart, min), rangeEnd); endValue = Math.min(Math.max(rangeStart, rangeEnd), max); } else { startValue = Math.min(Math.max(range.start, min), range.end); endValue = Math.min(Math.max(range.start, range.end), max); } startAngle = getAngleFromValue(startValue, max, min, axis.startAngle, axis.endAngle, isClockWise); endAngle = getAngleFromValue(endValue, max, min, axis.startAngle, axis.endAngle, isClockWise); var isAngleCross360 = (startAngle > endAngle); if (axis.rangeGap != null && axis.rangeGap > 0 && range.start !== range.end || (!isNullOrUndefined(range.linearGradient) && !range.isLinearCircularGradient && (colorIndex === (!isNullOrUndefined(range.linearGradient.colorStop) && range.linearGradient.colorStop.length - 1)))) { startAngle = (rangeIndex === 0 && !axis.startAndEndRangeGap) ? startAngle : colorIndex === 0 && range.isLinearCircularGradient ? axis.direction === 'AntiClockWise' ? startAngle - (axis.rangeGap / Math.PI) : startAngle + (axis.rangeGap / Math.PI) : !range.isLinearCircularGradient ? (axis.direction === 'AntiClockWise' ? startAngle - (axis.rangeGap / Math.PI) : startAngle + (axis.rangeGap / Math.PI)) : startAngle; endAngle = (rangeIndex === axis.ranges.length - 1 && !axis.startAndEndRangeGap) ? endAngle : !isNullOrUndefined(range.linearGradient) && colorIndex === range.linearGradient.colorStop.length - 1 && range.isLinearCircularGradient ? axis.direction === 'AntiClockWise' ? endAngle + (axis.rangeGap / Math.PI) : endAngle - (axis.rangeGap / Math.PI) : !range.isLinearCircularGradient ? (axis.direction === 'AntiClockWise' ? endAngle + (axis.rangeGap / Math.PI) : endAngle - (axis.rangeGap / Math.PI)) : endAngle; } if (this.gauge.allowComponentRender) { if ((startValue !== endValue) && (isAngleCross360 ? startAngle < (endAngle + 360) : (startAngle < endAngle)) && ((range.start >= min && range.end <= max) || (range.end >= min && range.start <= max))) { endAngle = isClockWise ? endAngle : [startAngle, startAngle = endAngle][0]; endWidth = isClockWise ? endWidth : [startWidth, startWidth = endWidth][0]; var radius = typeof range.roundedCornerRadius === 'string' ? parseFloat(range.roundedCornerRadius) : range.roundedCornerRadius; var process = (radius * 0.25); var degreeValue = getDegree(startAngle, endAngle); oldStart = ((((range.currentRadius - (startWidth / 2)) * ((startAngle * Math.PI) / 180) - (radius / process)) / (range.currentRadius - (startWidth / 2))) * 180) / Math.PI; oldEnd = ((((range.currentRadius - (endWidth / 2)) * ((endAngle * Math.PI) / 180) + (radius / process)) / (range.currentRadius - (endWidth / 2))) * 180) / Math.PI; roundedStartAngle = ((((range.currentRadius) * ((startAngle * Math.PI) / 180) + (degreeValue < (range.roundedCornerRadius / 2) && range.isLinearCircularGradient ? degreeValue <= 1 ? 0 : (radius / 4) : radius)) / (range.currentRadius)) * 180) / Math.PI; roundedEndAngle = ((((range.currentRadius) * ((endAngle * Math.PI) / 180) - (degreeValue < (range.roundedCornerRadius / 2) && range.isLinearCircularGradient ? degreeValue <= 1 ? 0 : (radius / 4) : radius)) / (range.currentRadius)) * 180) / Math.PI; if (roundedStartAngle > roundedEndAngle && (roundedStartAngle - roundedEndAngle) <= radius) { roundedStartAngle = startAngle; roundedEndAngle = endAngle; } if (this.gauge.gradientModule && ((!isNullOrUndefined(range.linearGradient) && !isNullOrUndefined(range.linearGradient.colorStop)) || (!isNullOrUndefined(range.radialGradient) && !isNullOrUndefined(range.radialGradient.colorStop)))) { if (range.isLinearCircularGradient) { endAngle -= isCompleteAngle(startAngle, endAngle) ? 0.0001 : 0; var degree = getDegree(startAngle, endAngle); var rangeColorLength = range.linearGradient.colorStop.length; var degreeRange = ((axis.startAngle === axis.endAngle ? (axis.startAngle === 0 && axis.endAngle === 0 ? 360 : axis.startAngle) : (axis.endAngle - axis.startAngle)) - degree * (rangeColorLength - 1)); var degreeRangeValue = void 0; if (degreeRange <= 360 && degreeRange >= 270) { degreeRangeValue = 270; } else if (degreeRange <= 270 && degreeRange >= 180) { degreeRangeValue = 180; } else if (degreeRange <= 180 && degreeRange >= 90) { degreeRangeValue = 90; } else if (degreeRange <= 90 && degreeRange >= 0) { degreeRangeValue = 0; } var gradientDegree = axis.direction === 'AntiClockWise' ? (axis.startAngle === axis.endAngle ? 0 : axis.startAngle) + degree * ((rangeColorLength - 1) - colorIndex) : axis.startAngle + degree * (colorIndex); var gradientAngle = axis.startAngle < axis.endAngle ? axis.direction === 'AntiClockWise' ? axis.ranges.length > 1 ? rangeIndex === 0 ? (360 - (axis.startAngle + (degree * (colorIndex)))) : (axis.startAngle + (degree * (colorIndex + 1))) : axis.startAngle + (degreeRangeValue + degree * ((rangeColorLength - 1) - colorIndex)) : axis.startAngle + (degree * (colorIndex)) : axis.endAngle === 360 || axis.startAngle === axis.endAngle ? axis.direction === 'AntiClockWise' ? axis.startAngle === axis.endAngle ? (axis.startAngle === 0 && axis.endAngle === 0 ? 0 : 360) - axis.startAngle + degreeRangeValue + (degree * ((rangeColorLength - 1) - colorIndex)) : degree * ((rangeColorLength - 1) - colorIndex) : degree * (colorIndex) : gradientDegree < 360 ? gradientDegree : gradientDegree - 360; range.gradientAngle = rangeIndex === 0 ? axis.rangeGap ? gradientAngle + axis.rangeGap : gradientAngle : axis.rangeGap > 0 ? axis.ranges[rangeIndex - 1]['gradientAngle'] + axis.rangeGap : axis.ranges[rangeIndex - 1]['gradientAngle']; if (axis.direction === 'AntiClockWise' && (axis.ranges.length > 1 ? colorIndex === rangeColorLength - 1 : colorIndex === 0)) { range.gradientAntiAngle = gradientAngle; } if (rangeIndex !== 0) { gradientAngle = axis.direction === 'AntiClockWise' ? axis.ranges.length > 1 ? axis.ranges[rangeIndex - 1]['gradientAntiAngle'] - gradientAngle + axis.startAngle : axis.ranges[rangeIndex - 1]['gradientAntiAngle'] + gradientAngle : range.gradientAngle + gradientAngle - axis.startAngle; range.gradientAngle = axis.rangeGap != null && axis.rangeGap > 0 ? colorIndex === rangeColorLength - 1 ? gradientAngle + axis.ranges[rangeIndex - 1]['gradientAngle'] : gradientAngle : gradientAngle; if (axis.direction === 'AntiClockWise' && (axis.ranges.length > 1 ? colorIndex === rangeColorLength - 1 : colorIndex === 0)) { range.gradientAntiAngle = gradientAngle; } } if (gradientAngle > 45 && gradientAngle <= 115 || (gradientAngle >= 0 && gradientAngle <= 45 && (rangeColorLength - 1) <= 2)) { direction = axis.direction === 'AntiClockWise' ? 'bottom' : 'top'; } else if (gradientAngle > 115 && gradientAngle < 170) { direction = axis.direction === 'AntiClockWise' ? 'left' : 'right'; } else if (gradientAngle >= 170 && gradientAngle <= 280) { direction = axis.direction === 'AntiClockWise' ? 'top' : 'bottom'; } else if (gradientAngle > 280 && gradientAngle <= 360 || (gradientAngle >= 0 && gradientAngle <= 45 && (rangeColorLength - 1) >= 2)) { direction = axis.direction === 'AntiClockWise' ? 'right' : 'left'; } } gradientRangeColor = this.gauge.gradientModule.getGradientColorString(range, colorIndex, direction, rangeIndex); } range.rangeColor = gradientRangeColor ? gradientRangeColor : range.rangeColor; if (range.roundedCornerRadius) { if (range.isLinearCircularGradient && range.linearGradient.colorStop.length > 1) { if (colorIndex === 0 || colorIndex === range.linearGradient.colorStop.length - 1) { if (axis.direction === 'ClockWise') { this.roundedRangeAppendPathCalculation(range, rangeIndex, index, startWidth, endWidth, rangeElement, (colorIndex === range.linearGradient.colorStop.length - 1 ? Math.floor(startAngle) : Math.floor(roundedStartAngle)), (colorIndex !== 0 ? Math.ceil(roundedEndAngle) : Math.ceil(endAngle)), ((colorIndex === range.linearGradient.colorStop.length - 1) ? startAngle : oldStart), (colorIndex !== 0 ? oldEnd : endAngle), location, colorIndex); } else { this.roundedRangeAppendPathCalculation(range, rangeIndex, index, startWidth, endWidth, rangeElement, (colorIndex === 0 ? Math.floor(startAngle) : Math.floor(roundedStartAngle)), (colorIndex === range.linearGradient.colorStop.length - 1 ? Math.ceil(endAngle) : Math.ceil(roundedEndAngle)), ((colorIndex === 0) ? startAngle : oldStart), (colorIndex === range.linearGradient.colorStop.length - 1 ? endAngle : oldEnd), location, colorIndex); } } else { this.rangeAppendPathCalculation(range, rangeIndex, index, startWidth, endWidth, rangeElement, Math.floor(startAngle), Math.ceil(endAngle), colorIndex); } } else { this.roundedRangeAppendPathCalculation(range, rangeIndex, index, startWidth, endWidth, rangeElement, Math.floor(roundedStartAngle), Math.ceil(roundedEndAngle), oldStart, oldEnd, location, colorIndex); } } else { this.rangeAppendPathCalculation(range, rangeIndex, index, startWidth, endWidth, rangeElement, Math.floor(startAngle), Math.ceil(endAngle), colorIndex); } } else if ((range.start === range.end) && ((range.start >= min && range.end <= max) || (range.end >= min && range.start <= max))) { this.rangeAppendPathCalculation(range, rangeIndex, index, startWidth, endWidth, rangeElement, Math.floor(startAngle), Math.ceil(endAngle), colorIndex); } } }; /** * Method to render the rounded range path of the circular gauge. * * @param {Range} range - Specifies the range. * @param {number} rangeIndex - Specifies the index of the range. * @param {number} index - Specifies the index of the axis. * @param {number} startWidth - Specifies the startwidth for the range. * @param {number} endWidth - Specifies the endwidth for the range. * @param {Element} rangeElement - Specifies the element. * @param {number} roundedStartAngle - Specifies the rounded path of the start angle. * @param {number} roundedEndAngle - Specifies the rounded path of the end angle. * @param {number} oldStart - Specifies the rounded path of the old start value. * @param {number} oldEnd - Specifies the rounded path of the old end value.. * @param {GaugeLocation} location - Specifies the location. * @param {number} colorIndex - Specifies the index of the lineargradient colorstop. * @returns {void} * @private */ AxisRenderer.prototype.roundedRangeAppendPathCalculation = function (range, rangeIndex, index, startWidth, endWidth, rangeElement, roundedStartAngle, roundedEndAngle, oldStart, oldEnd, location, colorIndex) { range.pathElement.push(appendPath(new PathOption((!range.isLinearCircularGradient ? this.gauge.element.id + '_Axis_' + index + '_Range_' + rangeIndex : this.gauge.element.id + '_Axis_' + index + '_Range_' + rangeIndex + '_Circular_' + colorIndex), range.rangeColor, 0, range.rangeColor, range.opacity, '0', getRoundedPathArc(location, Math.floor(roundedStartAngle), Math.ceil(roundedEndAngle), oldStart, oldEnd, range.currentRadius, startWidth, endWidth, range, this.gauge.axes[index]), '', ''), rangeElement, this.gauge)); }; /** * Method to render the rounded range path of the circular gauge. * * @param {Range} range - Specifies the range. * @param {number} rangeIndex - Specifies the index of the range. * @param {number} index - Specifies the index of the axis. * @param {number} startWidth - Specifies the startwidth for the range. * @param {number} endWidth - Specifies the endwidth for the range. * @param {Element} rangeElement - Specifies the element. * @param {number} startAngle - Specifies the rounded path of the start angle. * @param {number} endAngle - Specifies the rounded path of the end angle. * @param {number} colorIndex - Specifies the index of the lineargradient colorstop. * @returns {void} * @private */ AxisRenderer.prototype.rangeAppendPathCalculation = function (range, rangeIndex, index, startWidth, endWidth, rangeElement, startAngle, endAngle, colorIndex) { range.pathElement.push(appendPath(new PathOption(!range.isLinearCircularGradient ? this.gauge.element.id + '_Axis_' + index + '_Range_' + rangeIndex : this.gauge.element.id + '_Axis_' + index + '_Range_' + rangeIndex + '_Circular_' + colorIndex, range.rangeColor, 0, range.rangeColor, range.opacity, '0', getPathArc(this.gauge.midPoint, Math.floor(startAngle), Math.ceil(endAngle), range.currentRadius, startWidth, endWidth, range, this.gauge.axes[index]), '', ''), rangeElement, this.gauge)); }; /** * Method to render the axis range of the circular gauge. * * @param {Axis} axis - Specifies the axis. * @param {number} index - Specifies the index. * @param {Element} element - Specifies the element. * @returns {void} * @private */ AxisRenderer.prototype.drawAxisRange = function (axis, index, element) { var _this = this; var ele = (document.getElementById(this.gauge.element.id + '_Axis_Ranges_ ' + index)); var rangeElement = (ele) ? document.getElementById(this.gauge.element.id + '_Axis_Ranges_ ' + index) : this.gauge.renderer.createGroup({ id: this.gauge.element.id + '_Axis_Ranges_' + index, style: this.gauge.allowLoadingAnimation ? 'opacity: 0;' : '' }); var startWidth; var startEndDifference; var endWidth; var previousEndWidth; var previousStartWidth; axis.ranges.map(function (range, rangeIndex) { range.isLinearCircularGradient = !isNullOrUndefined(_this.gauge.gradientModule) && !isNullOrUndefined(range.linearGradient) && isNullOrUndefined(range.linearGradient.startValue) && isNullOrUndefined(range.linearGradient.endValue) && !isNullOrUndefined(range.linearGradient.colorStop); range.pathElement = []; if (!isNullOrUndefined(range.offset) && range.offset.length > 0) { range.currentDistanceFromScale = stringToNumber(range.offset, axis.currentRadius); } else { range.currentDistanceFromScale = range.offset; } _this.calculateRangeRadius(axis, range); if (!isNullOrUndefined(range.startWidth) && range.startWidth.length > 0) { startWidth = toPixel(range.startWidth, range.currentRadius); } else { startWidth = range.startWidth; } if (!isNullOrUndefined(range.endWidth) && range.endWidth.length > 0) { endWidth = toPixel(range.endWidth, range.currentRadius); } else { endWidth = range.endWidth; } range.currentRadius = _this.calculateRangeRadiusWithPosition(axis, range, startWidth); if (range.isLinearCircularGradient) { for (var i = 0; i < range.linearGradient.colorStop.length; i++) { if (i <= (range.linearGradient.colorStop.length - 1)) { previousEndWidth = i === 0 ? endWidth : previousEndWidth; previousStartWidth = i === 0 ? startWidth : previousStartWidth; startEndDifference = (Math.abs(previousStartWidth - previousEndWidth) / (range.linearGradient.colorStop.length)); if (i > 0) { startWidth = endWidth; endWidth = previousStartWidth > previousEndWidth ? startWidth - startEndDifference : startWidth + startEndDifference; } else { endWidth = previousStartWidth > previousEndWidth ? startWidth - startEndDifference : startWidth + startEndDifference; } } else { startWidth = previousStartWidth > previousEndWidth ? startWidth - startEndDifference : startWidth + startEndDifference; endWidth = (previousEndWidth); } _this.drawRangePath(axis, range, startWidth, endWidth, rangeIndex, index, rangeElement, i); } } else { if (!(range.start === range.end && axis.direction === 'AntiClockWise' && axis.startAngle === axis.endAngle)) { _this.drawRangePath(axis, range, startWidth, endWidth, rangeIndex, index, rangeElement, null); } } }); element.appendChild(rangeElement); }; /** * Method to calculate the radius of the axis range. * * @return {void} */ AxisRenderer.prototype.calculateRangeRadius = function (axis, range) { var radius = range.radius !== null ? range.radius : '100%'; range.currentRadius = stringToNumber(radius, axis.currentRadius); }; AxisRenderer.prototype.calculateRangeRadiusWithPosition = function (axis, range, startWidth) { var actualRadius = !isNullOrUndefined(range.position) && range.position !== 'Auto' && isNullOrUndefined(range.radius) ? (range.position === 'Outside' ? (range.currentRadius + axis.lineStyle.width / 2 + range.currentDistanceFromScale) : range.position === 'Inside' ? (range.currentRadius - axis.lineStyle.width / 2 - range.currentDistanceFromScale) : (range.currentRadius + startWidth / 2 - range.currentDistanceFromScale)) : range.currentRadius; return actualRadius; }; /** * Method to get the range color of the circular gauge. * * @param {Axis} axis - Specifies the axis * @returns {void} * @private */ AxisRenderer.prototype.setRangeColor = function (axis) { var rangeColors = getRangePalette(this.gauge.theme); axis.ranges.map(function (range, index) { range.rangeColor = range.color ? range.color : rangeColors[index % rangeColors.length]; }); }; /** * * @returns {void} * @private */ AxisRenderer.prototype.destroy = function () { this.gauge = null; this.majorValues = []; }; return AxisRenderer; }()); export { AxisRenderer };