@syncfusion/ej2-charts
Version:
Feature-rich chart control with built-in support for over 25 chart types, technical indictors, trendline, zooming, tooltip, selection, crosshair and trackball.
658 lines (657 loc) • 37.7 kB
JavaScript
import { extend, getValue, isNullOrUndefined } from '@syncfusion/ej2-base';
import { textWrap, appendClipElement, appendChildElement } from '../../common/utils/helper';
import { valueToCoefficient, textTrim, textElement, withInBounds } from '../../common/utils/helper';
import { measureText, TextOption, PathOption, Rect } from '@syncfusion/ej2-svg-base';
import { axisMultiLabelRender, multiLevelLabelClick } from '../../common/model/constants';
/**
* The `MultiLevelLabel` module is used to render multi-level labels in charts.
*/
var MultiLevelLabel = /** @class */ (function () {
/**
* Constructor for the logerithmic module.
*
* @private
* @param {Chart} chart - Specifies the chart.
*/
function MultiLevelLabel(chart) {
/** @private */
this.xAxisPrevHeight = [];
/** @private */
this.xAxisMultiLabelHeight = [];
/** @private */
this.yAxisPrevHeight = [];
/** @private */
this.yAxisMultiLabelHeight = [];
/** @private */
this.multiLevelLabelRectXRegion = [];
/** @private */
this.xLabelCollection = [];
this.chart = chart;
this.addEventListener();
}
/**
* Binding events for multi level module.
*
* @returns {void}
*/
MultiLevelLabel.prototype.addEventListener = function () {
if (this.chart.isDestroyed) {
return;
}
this.chart.on('click', this.click, this);
};
/**
* Gets the height of multilevel labels for the axis.
*
* @private
* @param {Axis} axis - The axis.
* @returns {void}
*/
MultiLevelLabel.prototype.getMultilevelLabelsHeight = function (axis) {
var _this = this;
var value = 0;
var multiLevelLabelsHeight = [];
var prevHeight = [];
var isVertical = axis.orientation === 'Vertical';
var axisValue = isVertical ? axis.rect.height : axis.rect.width;
var labelSize;
var height;
var padding = 10;
var gap;
axis.multiLevelLabels.map(function (multiLevel, index) {
multiLevel.categories.map(function (categoryLabel, i) {
if (categoryLabel.text !== '' && categoryLabel.start !== null && categoryLabel.end !== null) {
labelSize = measureText(categoryLabel.text, multiLevel.textStyle, _this.chart.themeStyle.axisLabelFont);
height = isVertical ? labelSize.width : labelSize.height;
height += 2 * multiLevel.border.width +
(multiLevel.border.type === 'CurlyBrace' ? padding : 0);
gap = (categoryLabel.maximumTextWidth !== null) ? categoryLabel.maximumTextWidth :
(valueToCoefficient(typeof categoryLabel.end === 'string' ? Number(new Date(categoryLabel.end)) :
categoryLabel.end, axis) * axisValue) -
(valueToCoefficient(typeof categoryLabel.start === 'string' ? Number(new Date(categoryLabel.start)) :
categoryLabel.start, axis) * axisValue);
var len = axis.multiLevelLabels[index].categories.length;
gap = ((i === 0 || i === len - 1) && axis.labelPlacement === 'OnTicks' && axis.edgeLabelPlacement === 'Shift') ? gap / 2 : gap;
if ((labelSize.width > gap - padding) && (_this.chart.enableRtl ? gap < 0 : gap > 0) && (multiLevel.overflow === 'Wrap') && !isVertical) {
height = (height * (textWrap(categoryLabel.text, gap - padding, multiLevel.textStyle, _this.chart.enableRtl, null, null, _this.chart.themeStyle.axisLabelFont).length));
}
multiLevelLabelsHeight[index] = !multiLevelLabelsHeight[index] ? height :
((multiLevelLabelsHeight[index] < height) ? height : multiLevelLabelsHeight[index]);
}
});
prevHeight[index] = value;
value += multiLevelLabelsHeight[index] ? (multiLevelLabelsHeight[index] + padding) : 0;
});
axis.multiLevelLabelHeight = value + ((axis.title !== '' || (this.chart.legendModule && this.chart.legendSettings.visible))
? padding / 2 : 0);
if (isVertical) {
this.yAxisMultiLabelHeight = multiLevelLabelsHeight;
this.yAxisPrevHeight = prevHeight;
}
else {
this.xAxisMultiLabelHeight = multiLevelLabelsHeight;
this.xAxisPrevHeight = prevHeight;
}
};
/**
* Renders the multilevel labels for the X-axis.
*
* @private
* @param {Axis} axis - The X-axis.
* @param {number} index - The index of the axis.
* @param {Element} parent - The parent element to render the multilevel labels.
* @param {Rect} axisRect - The axis rectangle.
* @returns {void}
*/
MultiLevelLabel.prototype.renderXAxisMultiLevelLabels = function (axis, index, parent, axisRect) {
var _this = this;
var x;
var y;
var padding = 10;
var startX;
var pointIndex;
var startY = (axis.labelPosition === axis.tickPosition ? axis.majorTickLines.height : 0) +
(axis.maxLabelSize.height) + padding;
var endX;
var pathRect = '';
var start;
var end;
var labelSize;
var isOutside = axis.labelPosition === 'Outside';
var gap;
var anchor;
var isInversed = axis.isAxisInverse;
var argsData;
var opposedPosition = axis.isAxisOpposedPosition;
var len;
var scrollBarHeight = axis.scrollbarSettings.enable || (isOutside && isNullOrUndefined(axis.crossesAt)) ?
axis.scrollBarHeight : 0;
var clipY = ((opposedPosition && !isOutside) || (!opposedPosition && isOutside)) ?
(axisRect.y + startY - axis.majorTickLines.width) : (axisRect.y - startY - axis.multiLevelLabelHeight);
this.createClipRect(axisRect.x - axis.majorTickLines.width, clipY + scrollBarHeight, axis.multiLevelLabelHeight + padding, axisRect.width + 2 * axis.majorTickLines.width, this.chart.element.id + '_XAxis_Clippath_' + index, this.chart.element.id + 'XAxisMultiLevelLabel' + index);
axis.multiLevelLabels.map(function (multiLevel, level) {
pointIndex = 0;
_this.labelElement = _this.chart.renderer.createGroup({ id: _this.chart.element.id + index + '_MultiLevelLabel' + level });
multiLevel.categories.map(function (categoryLabel, i) {
len = multiLevel.categories.length;
pathRect = '';
start = typeof categoryLabel.start === 'string' ? Number(new Date(categoryLabel.start)) : categoryLabel.start;
end = typeof categoryLabel.end === 'string' ? Number(new Date(categoryLabel.end)) : categoryLabel.end;
var labelFontStyle = (extend({}, getValue('properties', multiLevel.textStyle), null, true));
argsData = _this.triggerMultiLabelRender(axis, categoryLabel.text, labelFontStyle, axis.multiLevelLabels[level].alignment, categoryLabel.customAttributes);
if (!argsData.cancel) {
startX = valueToCoefficient(start, axis) * axisRect.width;
endX = valueToCoefficient(end, axis) * axisRect.width;
endX = isInversed ? [startX, startX = endX][0] : endX;
labelSize = measureText(argsData.text, argsData.textStyle, _this.chart.themeStyle.axisLabelFont);
gap = ((categoryLabel.maximumTextWidth === null) ? endX - startX : categoryLabel.maximumTextWidth) - padding;
x = startX + axisRect.x + padding;
y = (((opposedPosition && !isOutside) || (!opposedPosition && isOutside)) ? (startY + axisRect.y +
labelSize.height / 2 + padding + _this.xAxisPrevHeight[level]) :
(axisRect.y - startY + labelSize.height / 2 - _this.xAxisMultiLabelHeight[level] -
_this.xAxisPrevHeight[level])) + scrollBarHeight;
if (argsData.alignment === 'Center') {
x += (endX - startX - padding) / 2;
anchor = 'middle';
}
else if (argsData.alignment === 'Far') {
x = x + (endX - startX - padding) - multiLevel.border.width / 2;
if (axis.labelPlacement === 'OnTicks' && (i === 0 || i === len - 1)) {
x += (endX - startX - padding) / 2;
x = x - labelSize.width / 2;
}
anchor = 'end';
}
else {
anchor = 'start';
x += multiLevel.border.width / 2;
}
y = multiLevel.border.type === 'CurlyBrace' ?
(((!opposedPosition && isOutside) || (opposedPosition && !isOutside)) ? y + padding : y - padding / 2) : y;
var options = new TextOption(_this.chart.element.id + index + '_Axis_MultiLevelLabel_Level_' + level + '_Text_' + i, x, y, anchor, argsData.text);
if (multiLevel.overflow !== 'None') {
if (axis.edgeLabelPlacement && axis.labelPlacement === 'OnTicks') {
switch (axis.edgeLabelPlacement) {
case 'None':
break;
case 'Shift':
if ((i === 0 || (isInversed && i === len - 1))) {
if (argsData.alignment === 'Center' && ((options.x < axisRect.x + padding) || (options.x - labelSize.width / 2)) < axis.rect.x) {
options.x += axisRect.x / 2;
if ((options.x / 2) < axisRect.x) {
options.x = axisRect.x + padding / 2;
options.anchor = 'start';
}
}
else if (argsData.alignment === 'Far' && ((options.x < axisRect.x + padding) || (options.x > axisRect.x + padding))) {
options.x += labelSize.width / 2 - gap / 2;
}
else if (argsData.alignment === 'Near' && ((options.x < axisRect.x + padding) || (options.x > axisRect.x + padding))) {
options.x = axisRect.x + padding;
}
gap = gap / 2;
}
else if ((i === len - 1 || (isInversed && i === 0))) {
if (argsData.alignment === 'Center' && (options.x) > axisRect.x + axisRect.width) {
options.x -= padding;
if (options.x > axisRect.width) {
options.x = axisRect.width + axisRect.x;
options.anchor = 'end';
}
}
else if (argsData.alignment === 'Far') {
options.x = axisRect.width + axisRect.x;
}
gap = gap / 2;
}
break;
}
}
options.text = (multiLevel.overflow === 'Wrap') ?
textWrap(argsData.text, gap, argsData.textStyle, _this.chart.enableRtl, null, null, _this.chart.themeStyle.axisLabelFont) :
textTrim(gap, argsData.text, argsData.textStyle, _this.chart.enableRtl, _this.chart.themeStyle.axisLabelFont);
options.x = options.x - padding / 2;
}
textElement(_this.chart.renderer, options, argsData.textStyle, argsData.textStyle.color ||
_this.chart.themeStyle.axisLabelFont.color, _this.labelElement, false, _this.chart.redraw, true, null, null, null, null, null, _this.chart.enableCanvas, null, _this.chart.themeStyle.axisLabelFont);
if (_this.chart.enableCanvas) {
var textSize = measureText(argsData.text, argsData.textStyle, _this.chart.themeStyle.axisLabelFont);
_this.multiLevelLabelRectXRegion.push(new Rect(options.x, options.y, textSize.width, textSize.height));
_this.xLabelCollection.push(options);
}
if (multiLevel.border.width > 0 && multiLevel.border.type !== 'WithoutBorder') {
pathRect = _this.renderXAxisLabelBorder(level, endX - startX - padding, axis, startX, startY, labelSize, options, axisRect, argsData.alignment, pathRect, isOutside, opposedPosition, pointIndex);
// fix for generating seperate rect
if (pathRect !== '') {
_this.createBorderElement(level, index, axis, pathRect, pointIndex);
pointIndex++;
}
}
if (!_this.chart.enableCanvas) {
_this.multiElements.appendChild(_this.labelElement);
}
}
});
});
if (!this.chart.enableCanvas) {
parent.appendChild(this.multiElements);
}
};
/**
* Renders the border for the X-axis labels.
*
* @private
* @param {number} labelIndex - The index of the label.
* @param {number} gap - The gap between labels.
* @param {Axis} axis - The X-axis.
* @param {number} startX - The starting X-coordinate.
* @param {number} startY - The starting Y-coordinate.
* @param {Size} labelSize - The size of the label.
* @param {TextOption} textOptions - The text options for the label.
* @param {Rect} axisRect - The axis rectangle.
* @param {Alignment} alignment - The alignment of the label.
* @param {string} path - The SVG path.
* @param {boolean} isOutside - Indicates if the label is outside the axis.
* @param {boolean} opposedPosition - Indicates if the axis is in the opposed position.
* @param {number} categoryIndex - The index of the category.
* @returns {string} - The SVG path.
*/
MultiLevelLabel.prototype.renderXAxisLabelBorder = function (labelIndex, gap, axis, startX, startY, labelSize, textOptions, axisRect, alignment, path, isOutside, opposedPosition, categoryIndex) {
var padding = 10;
var padding1;
var padding2;
var value;
var value1;
var groupLabel = axis.multiLevelLabels[labelIndex];
var categoryType = groupLabel.categories[categoryIndex].type;
var width = gap + padding;
var height = isNullOrUndefined(this.xAxisMultiLabelHeight[labelIndex]) ? 0 :
(this.xAxisMultiLabelHeight[labelIndex] + padding);
var scrollBarHeight = axis.labelPosition === 'Outside' ? axis.scrollBarHeight : 0;
var x = startX + axisRect.x;
var y = ((!opposedPosition && isOutside) || (opposedPosition && !isOutside)) ? (startY + axisRect.y +
this.xAxisPrevHeight[labelIndex] + scrollBarHeight) : (axisRect.y - startY -
this.xAxisPrevHeight[labelIndex] - scrollBarHeight);
var borderType = categoryType ? categoryType : groupLabel.border.type;
switch (borderType) {
case 'WithoutTopandBottomBorder':
case 'Rectangle':
case 'WithoutTopBorder': {
var len = axis.multiLevelLabels[labelIndex].categories.length;
var lastX = (categoryIndex === len - 1 && (x + width > axisRect.width)) ? axisRect.width + axisRect.x : x + width;
var initialX = (categoryIndex === 0 &&
axis.multiLevelLabels[labelIndex].categories[0].start <= 0) ? axisRect.x : x;
height = ((!opposedPosition && isOutside) || (opposedPosition && !isOutside)) ? height : -height;
path += 'M ' + initialX + ' ' + y + ' L ' + initialX + ' ' + (y + height) + ' M ' + (lastX) + ' '
+ y + ' L ' + (lastX) + ' ' + (y + height);
path += (borderType !== 'WithoutTopandBottomBorder') ? (' L' + ' ' + (initialX) + ' ' + (y + height) + ' ') : ' ';
path += (borderType === 'Rectangle') ? ('M ' + initialX + ' ' + y + ' L ' + (lastX) + ' ' + y) : ' ';
break;
}
case 'Brace':
if (alignment === 'Near') {
value = textOptions.x;
value1 = textOptions.x + labelSize.width + 2;
}
else if (alignment === 'Center') {
value = textOptions.x - labelSize.width / 2 - 2;
value1 = textOptions.x + labelSize.width / 2 + 2;
}
else {
value = textOptions.x - labelSize.width - 2;
value1 = textOptions.x;
}
height = ((!opposedPosition && isOutside) || (opposedPosition && !isOutside)) ? height : -height;
path += 'M ' + x + ' ' + y + ' L ' + x + ' ' + (y + height / 2) +
' M ' + x + ' ' + (y + height / 2) + ' L ' + (value - 2) + ' ' + (y + height / 2) +
' M ' + (value1) + ' ' + (y + height / 2) + ' L ' + (x + width) + ' ' + (y + height / 2) +
' M ' + (x + width) + ' ' + (y + height / 2) + ' L ' + (x + width) + ' ' + (y);
break;
case 'CurlyBrace':
if ((!opposedPosition && isOutside) || (opposedPosition && !isOutside)) {
padding = 10;
padding1 = 15;
padding2 = 5;
}
else {
padding = -10;
padding1 = -15;
padding2 = -5;
}
if (alignment === 'Center') {
path += 'M ' + x + ' ' + y + ' C ' + x + ' ' + y + ' ' + (x + 5) + ' ' + (y + padding) + ' ' + (x + 10) + ' ' +
(y + padding) + ' L ' + (x + width / 2 - 5) + ' ' + (y + padding) + ' L ' + (x + width / 2) + ' ' + (y + padding1) +
' L ' + (x + width / 2 + 5) + ' ' + (y + padding) + ' L ' + (x + width - 10) + ' ' + (y + padding) + ' C ' +
(x + width - 10) + ' ' + (y + padding) + ' ' + (x + width) + ' ' + (y + padding2) + ' ' + (x + width) + ' ' + (y);
}
else if (alignment === 'Near') {
path += 'M ' + x + ' ' + y + ' C ' + x + ' ' + y + ' ' + (x + 5) + ' ' + (y + padding) + ' ' + (x + 10) + ' ' +
(y + padding) + ' L ' + (x + 15) + ' ' + (y + padding1) + ' L ' + (x + 20) + ' ' + (y + padding) + ' L ' +
(x + width - 10) + ' ' + (y + padding) + ' C ' + (x + width - 10) + ' ' + (y + padding) + ' ' + (x + width) + ' '
+ (y + padding2) + ' ' + (x + width) + ' ' + (y);
}
else {
path += 'M ' + x + ' ' + y + ' C ' + x + ' ' + y + ' ' + (x + 5) + ' ' + (y + padding) + ' ' + (x + 10) + ' ' +
(y + padding) + ' L ' + (x + width - 20) + ' ' + (y + padding) + ' L ' + (x + width - 15) + ' ' + (y + padding1) +
' L ' + (x + width - 10) + ' ' + (y + padding) + ' L ' + (x + width - 10) + ' ' + (y + padding) + ' C '
+ (x + width - 10) + ' ' + (y + padding) + ' ' + (x + width) + ' ' + (y + padding2) + ' ' + (x + width) + ' ' + (y);
}
break;
}
return path;
};
/**
* Renders the multi-level labels for the Y-axis.
*
* @private
* @param {Axis} axis - The Y-axis.
* @param {number} index - The index of the axis.
* @param {Element} parent - The parent element to which the labels are appended.
* @param {Rect} rect - The axis rectangle.
* @returns {void}
*/
MultiLevelLabel.prototype.renderYAxisMultiLevelLabels = function (axis, index, parent, rect) {
var _this = this;
var labelSize;
var isOutside = axis.labelPosition === 'Outside';
var x;
var y;
var padding = 10;
var startX = (axis.tickPosition === axis.labelPosition ? axis.majorTickLines.height : 0) +
(axis.maxLabelSize.width) + padding;
var startY;
var path = '';
var endY;
var argsData;
var pointIndex;
var isInversed = axis.isAxisInverse;
var start;
var end;
var gap;
var anchor = 'middle';
var opposedPosition = axis.isAxisOpposedPosition;
var scrollBarHeight = isOutside && isNullOrUndefined(axis.crossesAt) ? axis.scrollBarHeight : 0;
scrollBarHeight = scrollBarHeight * (opposedPosition ? 1 : -1);
var clipX = ((opposedPosition && !isOutside) || (!opposedPosition && isOutside)) ?
(rect.x - axis.multiLevelLabelHeight - startX - padding) : (rect.x + startX);
this.createClipRect(clipX + scrollBarHeight, rect.y - axis.majorTickLines.width, rect.height + 2 * axis.majorTickLines.width, axis.multiLevelLabelHeight + padding, this.chart.element.id + '_YAxis_Clippath_' + index, this.chart.element.id
+ 'YAxisMultiLevelLabel' + index);
axis.multiLevelLabels.map(function (multiLevel, level) {
_this.labelElement = _this.chart.renderer.createGroup({ id: _this.chart.element.id + index + '_MultiLevelLabel' + level });
pointIndex = 0;
multiLevel.categories.map(function (categoryLabel, i) {
path = '';
end = typeof categoryLabel.end === 'string' ? Number(new Date(categoryLabel.end)) : categoryLabel.end;
start = typeof categoryLabel.start === 'string' ? Number(new Date(categoryLabel.start)) : categoryLabel.start;
startY = valueToCoefficient((start), axis) * (rect.height);
endY = valueToCoefficient((end), axis) * (rect.height);
endY = isInversed ? [startY, startY = endY][0] : endY;
var labelFontStyle = (extend({}, getValue('properties', multiLevel.textStyle), null, true));
argsData = _this.triggerMultiLabelRender(axis, categoryLabel.text, labelFontStyle, multiLevel.alignment, categoryLabel.customAttributes);
if (!argsData.cancel) {
var maximumWidth = ((categoryLabel.maximumTextWidth === null ?
(_this.yAxisMultiLabelHeight[level] / 2) : categoryLabel.maximumTextWidth / 2));
labelSize = measureText(argsData.text, argsData.textStyle, _this.chart.themeStyle.axisLabelFont);
gap = endY - startY;
x = rect.x - startX - _this.yAxisPrevHeight[level] -
(maximumWidth) - padding / 2;
y = rect.height + rect.y - startY - (gap / 2);
if (opposedPosition) {
x = isOutside ? rect.x + startX + padding / 2 + (maximumWidth) +
_this.yAxisPrevHeight[level] + scrollBarHeight : rect.x - startX - (maximumWidth) -
_this.yAxisPrevHeight[level] - padding / 2;
}
else {
x = isOutside ? x + scrollBarHeight : rect.x + startX + padding / 2 + (maximumWidth) +
_this.yAxisPrevHeight[level];
}
if (argsData.alignment === 'Center') {
y += labelSize.height / 4;
}
else if (argsData.alignment === 'Far') {
y += gap / 2 - labelSize.height / 2;
}
else {
y = y - gap / 2 + labelSize.height;
}
x = multiLevel.border.type === 'CurlyBrace' ? (((!opposedPosition && isOutside) ||
(opposedPosition && !isOutside)) ? x - padding : x + padding) : x;
var options = new TextOption(_this.chart.element.id + index + '_Axis_MultiLevelLabel_Level_' + level + '_Text_' + i, x, y, anchor, argsData.text);
options.text = (multiLevel.overflow === 'Trim') ?
textTrim((categoryLabel.maximumTextWidth === null ? _this.yAxisMultiLabelHeight[level] :
categoryLabel.maximumTextWidth), argsData.text, argsData.textStyle, _this.chart.enableRtl, _this.chart.themeStyle.axisLabelFont) : options.text;
options.text = (multiLevel.overflow === 'Wrap') ?
textWrap(argsData.text, (categoryLabel.maximumTextWidth === null ? _this.yAxisMultiLabelHeight[level] :
categoryLabel.maximumTextWidth), argsData.textStyle, _this.chart.enableRtl, null, null, _this.chart.themeStyle.axisLabelFont) : options.text;
if (typeof options.text !== 'string' && options.text.length > 1) {
options.y -= (padding * options.text.length / 2);
}
textElement(_this.chart.renderer, options, argsData.textStyle, argsData.textStyle.color ||
_this.chart.themeStyle.axisLabelFont.color, _this.labelElement, _this.chart.redraw, true, null, null, null, null, null, null, _this.chart.enableCanvas, null, _this.chart.themeStyle.axisLabelFont);
if (multiLevel.border.width > 0 && multiLevel.border.type !== 'WithoutBorder') {
path = _this.renderYAxisLabelBorder(level, gap, axis, endY, startX, startY, labelSize, options, rect, argsData.alignment, path, isOutside, opposedPosition, pointIndex);
if (path !== '') {
_this.createBorderElement(level, index, axis, path, pointIndex);
pointIndex++;
}
}
if (!_this.chart.enableCanvas) {
_this.multiElements.appendChild(_this.labelElement);
}
}
});
});
if (!this.chart.enableCanvas) {
parent.appendChild(this.multiElements);
}
};
/**
* Renders the border for the Y-axis labels.
*
* @param {number} labelIndex - The index of the label.
* @param {number} gap - The gap between labels.
* @param {Axis} axis - The Y-axis.
* @param {number} endY - The end Y-coordinate.
* @param {number} startX - The start X-coordinate.
* @param {number} startY - The start Y-coordinate.
* @param {Size} labelSize - The size of the label.
* @param {TextOption} textOptions - The text options for the label.
* @param {Rect} rect - The axis rectangle.
* @param {Alignment} alignment - The alignment of the label.
* @param {string} path - The path for rendering.
* @param {boolean} isOutside - Indicates whether the label is outside.
* @param {boolean} opposedPosition - Indicates whether the label position is opposed.
* @param {number} categoryIndex - The index of the category.
* @returns {string} - The path for rendering the label border.
*/
MultiLevelLabel.prototype.renderYAxisLabelBorder = function (labelIndex, gap, axis, endY, startX, startY, labelSize, textOptions, rect, alignment, path, isOutside, opposedPosition, categoryIndex) {
var height = endY - startY;
var padding = 10;
var padding1;
var padding2;
var groupLabel = axis.multiLevelLabels[labelIndex];
var categoryType = groupLabel.categories[categoryIndex].type;
var y = rect.y + rect.height - endY;
var scrollBarHeight = isOutside && isNullOrUndefined(axis.crossesAt) ? axis.scrollBarHeight : 0;
scrollBarHeight = scrollBarHeight * (opposedPosition ? 1 : -1);
var width = (groupLabel.categories[categoryIndex].maximumTextWidth === null ?
this.yAxisMultiLabelHeight[labelIndex] :
(groupLabel.categories[categoryIndex].maximumTextWidth)) + padding;
var x = (((!opposedPosition && isOutside) || (opposedPosition && !isOutside)) ? rect.x - startX -
this.yAxisPrevHeight[labelIndex] : rect.x + startX + this.yAxisPrevHeight[labelIndex]) + scrollBarHeight;
var borderType = categoryType ? categoryType : groupLabel.border.type;
switch (borderType) {
case 'WithoutTopandBottomBorder':
case 'Rectangle':
case 'WithoutTopBorder':
width = ((!opposedPosition && isOutside) || (opposedPosition && !isOutside)) ? -width : width;
path += 'M ' + x + ' ' + y + ' L ' + (x + width) + ' ' + y +
' M ' + x + ' ' + (y + height) + ' L ' + (x + width) + ' ' + (y + height);
path += (borderType !== 'WithoutTopandBottomBorder') ? (' L' + ' ' + (x + width) + ' ' + y + ' ') : ' ';
path += (borderType === 'Rectangle') ? ('M ' + (x) + ' ' + (y + height) + 'L' + ' ' + (x) + ' ' + y + ' ') : ' ';
break;
case 'Brace':
width = ((!opposedPosition && isOutside) || (opposedPosition && !isOutside)) ? width : -width;
path += 'M ' + (x) + ' ' + y + ' L ' + (x - width / 2) + ' ' + y + ' L ' + (x - width / 2) + ' ' +
(textOptions.y - labelSize.height / 2 - 4) + ' M ' + (x - width / 2) + ' ' +
(textOptions.y + labelSize.height / 4 + 2) +
' L ' + (x - width / 2) + ' ' + (y + height) + ' L ' + (x) + ' ' + (y + height);
break;
case 'CurlyBrace':
if ((!opposedPosition && isOutside) || (opposedPosition && !isOutside)) {
padding = -10;
padding1 = -15;
padding2 = -5;
}
else {
padding = 10;
padding1 = 15;
padding2 = 5;
}
if (alignment === 'Center') {
path += 'M ' + x + ' ' + y + ' C ' + x + ' ' + y + ' ' + (x + padding) + ' ' + y + ' ' + (x + padding) + ' ' + (y + 10)
+ ' L ' + (x + padding) + ' ' + (y + (height - 10) / 2) + ' L ' + (x + padding1) + ' ' + (y + (height - 10) / 2 + 5)
+ ' L ' + (x + padding) + ' ' + (y + (height - 10) / 2 + 10) + ' L ' + (x + padding) + ' ' + (y + (height - 10)) +
' C ' + (x + padding) + ' ' + (y + (height - 10)) + ' ' + (x + padding2) + ' ' + (y + height) + ' '
+ x + ' ' + (y + height);
}
else if (alignment === 'Far') {
path += 'M ' + x + ' ' + y + ' C ' + x + ' ' + y + ' ' + (x + padding) + ' ' + y + ' ' + (x + padding) + ' ' + (y + 10)
+ ' L ' + (x + padding) + ' ' + (y + height - 20) + ' ' + ' L ' + (x + padding1) + ' ' + (y + (height - 15)) +
' L ' + (x + padding) + ' ' + (y + (height - 10)) + ' L ' + (x + padding) + ' ' + (y + (height - 10)) +
' C ' + (x + padding) + ' ' + (y + (height - 10)) + ' ' + (x + padding) + ' ' + (y + height) + ' ' + x + ' '
+ (y + height);
}
else {
path += 'M ' + x + ' ' + y + ' C ' + x + ' ' + y + ' ' + (x + padding) + ' ' + y + ' ' + (x + padding) + ' ' + (y + 10)
+ ' L ' + (x + padding1) + ' ' + (y + 15) +
' L ' + (x + padding) + ' ' + (y + 20) + ' L ' + (x + padding) + ' ' + (y + (height - 10)) +
' C ' + (x + padding) + ' ' + (y + (height - 10)) + ' ' + (x + padding2) + ' ' + (y + height) + ' ' + x +
' ' + (y + height);
}
break;
}
return path;
};
/**
* create cliprect
*
* @returns {void}
* @private
*/
MultiLevelLabel.prototype.createClipRect = function (x, y, height, width, clipId, axisId) {
this.multiElements = this.chart.renderer.createGroup({
'id': axisId,
'clip-path': 'url(#' + clipId + ')'
});
if (!this.chart.enableCanvas) {
this.multiElements.appendChild(appendClipElement(this.chart.redraw, {
'id': clipId,
'x': x,
'y': y,
'width': width,
'height': height,
'fill': 'white',
'stroke-width': 1, 'stroke': 'Gray'
}, this.chart.renderer));
}
};
/**
* create borer element
*
* @returns {void}
* @private
*/
MultiLevelLabel.prototype.createBorderElement = function (borderIndex, axisIndex, axis, path, pointIndex) {
var direction = path;
var borderElement = this.chart.renderer.drawPath(new PathOption(this.chart.element.id + axisIndex + '_Axis_MultiLevelLabel_Rect_' + borderIndex + '_' + pointIndex, 'Transparent', axis.multiLevelLabels[borderIndex].border.width, axis.multiLevelLabels[borderIndex].border.color || this.chart.themeStyle.axisLine, 1, '', path));
borderElement.style.pointerEvents = 'none';
appendChildElement(this.chart.enableCanvas, this.labelElement, borderElement, this.chart.redraw, true, 'x', 'y', null, direction);
};
/**
* Triggers the event.
*
* @returns {void}
* @private
*/
MultiLevelLabel.prototype.triggerMultiLabelRender = function (axis, text, textStyle, textAlignment, customAttributes) {
var argsData = {
cancel: false, name: axisMultiLabelRender, axis: axis,
text: text, textStyle: textStyle, alignment: textAlignment, customAttributes: customAttributes
};
this.chart.trigger(axisMultiLabelRender, argsData);
return argsData;
};
/**
* Handles the click event for multi-level labels.
*
* @private
* @param {string} labelIndex - The index of the clicked label.
* @param {number} axisIndex - The index of the axis.
* @returns {IMultiLevelLabelClickEventArgs} - The event arguments for multi-level label click.
*/
MultiLevelLabel.prototype.MultiLevelLabelClick = function (labelIndex, axisIndex) {
var level = parseInt(labelIndex.substr(0, 1), 10);
var textElement = parseInt(labelIndex.substr(7), 10);
var chart = this.chart;
var axis = chart.axisCollections[axisIndex];
var categories = axis.multiLevelLabels[level].categories;
var text = categories[textElement].text;
var start = categories[textElement].start;
var end = categories[textElement].end;
var customAttributes = categories[textElement].customAttributes;
var multilevelclickArgs = {
axis: axis, level: level, text: text, customAttributes: customAttributes,
start: start, end: end, name: multiLevelLabelClick, cancel: false
};
this.chart.trigger(multiLevelLabelClick, multilevelclickArgs);
return multilevelclickArgs;
};
/**
* To click the multi level label
*
* @param {Event} event - The click event.
* @returns {void}
* @private
*/
MultiLevelLabel.prototype.click = function (event) {
var targetId = event.target.id;
var multiLevelID = '_Axis_MultiLevelLabel_Level_';
var textId;
var elementId;
var axisIndex;
if (this.chart.enableCanvas) {
for (var i = 0; i < this.multiLevelLabelRectXRegion.length; i++) {
if (withInBounds(event['x'], event['y'], this.multiLevelLabelRectXRegion[i], this.multiLevelLabelRectXRegion[i].width, this.multiLevelLabelRectXRegion[i].height)) {
targetId = this.xLabelCollection[i].id;
}
}
}
if (targetId.indexOf(multiLevelID) > -1) {
textId = targetId.split(multiLevelID)[1];
elementId = targetId.split(multiLevelID)[0];
axisIndex = parseInt(elementId.charAt(elementId.length - 1), 10);
this.MultiLevelLabelClick(textId, axisIndex);
}
};
/**
* To get the module name for `MultiLevelLabel`.
*
* @private
* @returns {string} - Returns the module name.
*/
MultiLevelLabel.prototype.getModuleName = function () {
return 'MultiLevelLabel';
};
/**
* To destroy the `MultiLevelLabel` module.
*
* @private
* @returns {void}
*/
MultiLevelLabel.prototype.destroy = function () {
// destroy peform here
};
return MultiLevelLabel;
}());
export { MultiLevelLabel };