@syncfusion/ej2-circulargauge
Version:
Essential JS 2 CircularGauge Components
689 lines (688 loc) • 42.8 kB
JavaScript
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 };