@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.
1,010 lines • 53.1 kB
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
/**
* Selection source file
*/
import { Browser } from '@syncfusion/ej2-base';
import { extend, isNullOrUndefined } from '@syncfusion/ej2-base';
import { getElement } from '../../common/utils/helper';
import { Index } from '../../common/model/base';
import { selectionComplete } from '../../common/model/constants';
import { BaseSelection } from '../../common/user-interaction/selection';
/**
* The `Selection` module handles the selection for chart.
*
* @private
*/
var Selection3D = /** @class */ (function (_super) {
__extends(Selection3D, _super);
/**
* Constructor for selection module.
*
* @param {Chart3D} chart - Chart3D instance.
* @private
*/
function Selection3D(chart) {
var _this = _super.call(this, chart) || this;
_this.seriesIndex = 0;
_this.chart = chart;
_this.addEventListener();
return _this;
}
/**
* Binding events for selection module.
*
* @returns {void}
*/
Selection3D.prototype.addEventListener = function () {
if (this.chart.isDestroyed) {
return;
}
var cancelEvent = Browser.isPointer ? 'pointerleave' : 'mouseleave';
this.chart.on(Browser.touchMoveEvent, this.mouseMove, this);
this.chart.on(cancelEvent, this.mouseLeave, this);
this.chart.on('click', this.mouseClick, this);
this.chart.on(Browser.touchStartEvent, this.mousedown, this);
this.chart.on(Browser.touchEndEvent, this.mouseLeave, this);
};
/**
* Handles the mouse down event.
*
* @returns {void}
*/
Selection3D.prototype.mousedown = function () {
var chart = this.chart;
if (chart.isPointMouseDown || chart.selectionMode === 'Point') {
return;
}
};
/**
* Unbinding events for selection module.
*
* @returns {void}
*/
Selection3D.prototype.removeEventListener = function () {
if (this.chart.isDestroyed) {
return;
}
this.chart.off(Browser.touchMoveEvent, this.mouseMove);
this.chart.off('pointerleave' || 'mouseleave', this.mouseLeave);
this.chart.off('click', this.mouseClick);
this.chart.off(Browser.touchStartEvent, this.mousedown);
this.chart.off(Browser.touchEndEvent, this.mouseLeave);
};
/**
* To find private variable values
*
* @param {Chart3D} chart - Chart3D instance.
* @returns {void}
*/
Selection3D.prototype.initPrivateVariables = function (chart) {
this.styleId = chart.element.id + '_ej2_chart_selection';
this.unselected = chart.element.id + '_ej2_deselected';
this.selectedDataIndexes = [];
this.isSeriesMode = chart.selectionMode === 'Series';
};
/**
* Method to select the point and series.
*
* @param {Chart3D} chart - Chart3D instance
* @returns {void}
*/
Selection3D.prototype.invokeSelection = function (chart) {
this.initPrivateVariables(chart);
this.series = extend({}, chart.visibleSeries, null, true);
this.seriesStyles();
this.currentMode = chart.selectionMode;
this.selectDataIndex(chart, this.concatIndexes(chart.selectedDataIndexes, this.selectedDataIndexes));
};
/**
* Generates the style for the series.
*
* @param {Chart3DSeriesModel} series - The series for which the style is generated.
* @returns {string} - The generated style string.
*/
Selection3D.prototype.generateStyle = function (series) {
if (series) {
return (this.styleId + '_series_' + series.index);
}
return 'undefined';
};
/**
* Selects the specified data indexes in the Chart3D.
* This method is responsible for handling the selection of specific data indexes in the Chart3D.
*
* @param {Chart3D} chart - The Chart3D instance in which the data indexes are selected.
* @param {Index[]} indexes - An array of Index objects representing the data indexes to be selected.
* @returns {void}
*/
Selection3D.prototype.selectDataIndex = function (chart, indexes) {
for (var _i = 0, indexes_1 = indexes; _i < indexes_1.length; _i++) {
var index = indexes_1[_i];
this.performSelection(index, chart, this.getElementByIndex(chart, index)[0]);
}
};
/**
* Retrieves the elements in the Chart3D associated with the specified data index.
*
* This method is responsible for obtaining the elements in the Chart3D related to the specified data index.
*
* @param {Chart3D} chart - The Chart3D instance containing the elements.
* @param {Index} index - An Index object representing the data index.
* @returns {Element[]} An array of Element objects representing the elements associated with the specified data index.
*/
Selection3D.prototype.getElementByIndex = function (chart, index) {
var pointElements = [];
var elements = document.querySelectorAll('[id*="-region-series-' + index.series + '-point-' + index.point + '"]');
elements.forEach(function (pointElement) {
pointElements.push(pointElement);
});
return pointElements;
};
/**
* This method is responsible for obtaining the clustered elements in the Chart3D related to the specified data index.
* Clustering typically involves obtaining a group of related elements for a specific data index.
*
* @param {Chart3D} chart - The Chart3D instance containing the clustered elements.
* @param {Index} index - An Index object representing the data index.
* @returns {Element[]} An array of Element objects representing the clustered elements associated with the specified data index.
*/
Selection3D.prototype.getClusterElements = function (chart, index) {
var clusters = [];
for (var _i = 0, _a = chart.visibleSeries; _i < _a.length; _i++) {
var series = _a[_i];
if (series.visible) {
index = new Index(series.index, index.point);
var pointElements = this.getElementByIndex(chart, index);
for (var i = 0; i < pointElements.length; i++) {
clusters.push(pointElements[i]);
}
}
}
return clusters;
};
/**
* Method to get the selected element.
*
* @param {Chart3D} chart - The Chart3D instance to which the series belongs.
* @param {Chart3DSeriesModel} series - The series in which the data point is located.
* @param {Index} index - The index or position of the data point within the series.
* @returns {Element[]} An array of elements associated with the specified data point in the Chart3D.
* @private
*/
Selection3D.prototype.findElements = function (chart, series, index) {
if (this.isSeriesMode) {
return this.getSeriesElements(series);
}
else if (this.currentMode === 'Cluster') {
return this.getClusterElements(chart, index);
}
else {
return this.getElementByIndex(chart, index);
}
};
/**
* Checks whether the specified element is already selected in the Chart3D.
*
* @param {Element} targetElem - The target element to check for selection status.
* @param {string} eventType - The type of event triggering the selection check (e.g., 'click', 'hover').
* @param {Index} [index] - Optional. The index or position of the data point within the series.
* @returns {boolean} A boolean indicating whether the specified element is already selected.
*/
Selection3D.prototype.isAlreadySelected = function (targetElem, eventType, index) {
if (eventType === 'click') {
this.currentMode = this.chart.selectionMode;
this.styleId = this.chart.element.id + '_ej2_chart_selection';
}
else if (eventType === 'mousemove' || eventType === 'pointermove') {
this.currentMode = this.chart.highlightMode;
this.highlightDataIndexes = [];
this.styleId = this.chart.element.id + '_ej2_chart_highlight';
}
if (this.chart.highlightMode !== 'None' && this.chart.selectionMode === 'None') {
if (eventType === 'click') {
return false;
}
}
if (((this.chart.highlightMode !== 'None' || this.chart.legendSettings.enableHighlight) && this.previousSelectedEle && this.previousSelectedEle[0])) {
var isElement = void 0;
var nodeName = targetElem.nodeName;
if (targetElem.parentNode) {
isElement = ((nodeName === 'path' || nodeName === 'shape') && targetElem.id.indexOf('region') > 1) ? true : false;
}
var _loop_1 = function (i) {
if (this_1.previousSelectedEle[i].hasAttribute('class')) {
if (this_1.previousSelectedEle[i].getAttribute('class').indexOf('highlight') > -1 &&
(isElement || eventType === 'click')) {
var selectionClass_1;
this_1.previousSelectedEle[i].classList.forEach(function (className) {
if (className.indexOf('selection') > -1) {
selectionClass_1 = className;
}
});
this_1.previousSelectedEle[i].removeAttribute('class');
if (selectionClass_1) {
this_1.addSvgClass(this_1.previousSelectedEle[i], selectionClass_1);
}
this_1.previousSelectedEle[i].classList.remove(this_1.styleId + '_series_' + index.series);
if (this_1.chart.highlightColor !== '' && !isNullOrUndefined(this_1.chart.highlightColor) && this_1.chart.highlightPattern === 'None') {
this_1.previousSelectedEle[i].setAttribute('fill', this_1.control.visibleSeries[this_1.indexFinder(this_1.previousSelectedEle[i].id).series].interior);
}
this_1.addOrRemoveIndex(this_1.highlightDataIndexes, this_1.indexFinder(this_1.previousSelectedEle[i].id));
}
else if (!isElement && this_1.previousSelectedEle[i].getAttribute('class').indexOf('highlight') > -1) {
this_1.performSelection(this_1.indexFinder(this_1.previousSelectedEle[i].id), this_1.chart, this_1.previousSelectedEle[i]);
}
}
};
var this_1 = this;
for (var i = 0; i < this.previousSelectedEle.length; i++) {
_loop_1(i);
}
}
return true;
};
/**
* Handles the mouse click event in the Chart3D, triggering the calculation of selected elements.
*
* @param {Event} event - The mouse click event object.
* @returns {void}
*/
Selection3D.prototype.mouseClick = function (event) {
if (!this.chart.rotateActivate) {
this.calculateSelectedElements(event.target, event.type);
}
};
/**
* Calculates the selected elements based on the provided target element and event type.
*
* @param {HTMLElement} targetElement - The target HTML element that triggered the selection.
* @param {string} eventType - The type of the event that triggered the selection (e.g., mouse click).
* @returns {void}
*/
Selection3D.prototype.calculateSelectedElements = function (targetElement, eventType) {
if (isNullOrUndefined(targetElement)) {
return;
}
if ((this.chart.selectionMode === 'None' && this.chart.highlightMode === 'None') ||
targetElement.id && targetElement.id.indexOf(this.chart.element.id + '-') === -1) {
return;
}
if (eventType === 'mousemove' || eventType === 'pointermove') {
if (targetElement.hasAttribute('class') && (targetElement.getAttribute('class').indexOf('highlight') > -1 ||
targetElement.getAttribute('class').indexOf('selection') > -1)) {
return;
}
}
this.isAlreadySelected(targetElement, eventType, this.indexFinder(targetElement.id));
if (targetElement.id && targetElement.id.indexOf('-series-') > -1 && targetElement.id.indexOf('_Text_') === -1) {
var element = void 0;
this.performSelection(this.indexFinder(targetElement.id), this.chart, element || targetElement);
}
};
/**
* Performs selection based on the provided index, chart, and optional element.
*
* @param {Index} index - The index or indices specifying the data points or elements to be selected.
* @param {Chart3D} chart - The Chart3D instance where the selection is being performed.
* @param {Element} [element] - Optional. The specific HTML element that triggered the selection.
* @returns {void}
*/
Selection3D.prototype.performSelection = function (index, chart, element) {
this.isSeriesMode = this.currentMode === 'Series';
switch (this.currentMode) {
case 'Series':
this.selection(chart, index, this.getSeriesElements(chart.series[index.series]));
this.selectionComplete(chart, index, this.currentMode);
this.blurEffect(chart.element.id, chart.visibleSeries);
break;
case 'Point':
if (!isNaN(index.point) && element) {
this.selection(chart, index, this.getElementByIndex(chart, index));
this.selectionComplete(chart, index, this.currentMode);
this.blurEffect(chart.element.id, chart.visibleSeries);
}
break;
case 'Cluster':
if (!isNaN(index.point)) {
this.clusterSelection(chart, index);
this.selectionComplete(chart, index, this.currentMode);
this.blurEffect(chart.element.id, chart.visibleSeries);
}
break;
}
};
/**
* Handles the completion of a selection process in the Chart3D.
*
* @param {Chart3D} chart - The Chart3D instance where the selection process is completed.
* @param {Index} index - The selected index or indices representing the data points or elements.
* @param {Chart3DSelectionMode | HighlightMode} selectionMode - The mode of selection, either SelectionMode or HighlightMode.
* @returns {void}
*/
Selection3D.prototype.selectionComplete = function (chart, index, selectionMode) {
var points;
var pointIndex;
var seriesIndex;
var selectedPointValues = [];
var yValue;
var selectedPointX;
if (selectionMode === 'Cluster') {
for (var _i = 0, _a = chart.visibleSeries; _i < _a.length; _i++) {
var series = _a[_i];
if (series.visible) {
for (var i = 0; i < this.selectedDataIndexes.length; i++) {
pointIndex = chart.isMultiSelect ? this.selectedDataIndexes[i].point : index.point;
seriesIndex = series.index;
points = series.points;
if (!isNaN(pointIndex)) {
yValue = points[pointIndex].yValue;
selectedPointX = points[pointIndex].xValue;
if (chart.primaryXAxis.valueType === 'Category') {
selectedPointX = points[pointIndex].x.toLocaleString();
}
else if (chart.primaryXAxis.valueType === 'DateTime') {
selectedPointX = new Date(points[pointIndex].xValue);
}
selectedPointValues.push({
x: selectedPointX, y: yValue, seriesIndex: seriesIndex,
pointIndex: pointIndex
});
}
}
}
}
}
else if (selectionMode === 'Series') {
if (chart.isMultiSelect) {
for (var i = 0; i < this.selectedDataIndexes.length; i++) {
seriesIndex = this.selectedDataIndexes[i].series;
if (this.selectedDataIndexes.length > 0) {
selectedPointValues.push({
seriesIndex: seriesIndex
});
}
}
}
else {
seriesIndex = (this.selectedDataIndexes.length > 0) ? this.selectedDataIndexes[0].series :
(this.highlightDataIndexes && this.highlightDataIndexes.length > 0) ? this.highlightDataIndexes[0].series : 0;
if (this.selectedDataIndexes.length > 0 || (this.highlightDataIndexes && this.highlightDataIndexes.length > 0)) {
selectedPointValues.push({
seriesIndex: seriesIndex
});
}
}
}
else if (selectionMode === 'Point') {
var selectedData = [];
if (this.styleId.indexOf('highlight') > -1) {
selectedData = this.highlightDataIndexes;
}
else {
selectedData = this.selectedDataIndexes;
}
for (var i = 0; i < selectedData.length; i++) {
pointIndex = selectedData[i].point;
seriesIndex = selectedData[i].series;
var series = chart.series[seriesIndex];
points = series.points;
if (!isNaN(pointIndex)) {
selectedPointX = points[pointIndex].xValue;
yValue = points[pointIndex].yValue;
if (chart.primaryXAxis.valueType === 'Category') {
selectedPointX = points[pointIndex].x.toLocaleString();
}
else if (chart.primaryXAxis.valueType === 'DateTime') {
selectedPointX = new Date(points[pointIndex].xValue);
}
selectedPointValues.push({
x: selectedPointX, y: yValue, seriesIndex: seriesIndex,
pointIndex: pointIndex
});
}
}
}
var args = {
selectedDataValues: selectedPointValues,
cancel: false,
chart: chart
};
chart.trigger(selectionComplete, args);
};
/**
* Handles the selection process in the Chart3D.
*
* @param {Chart3D} chart - The Chart3D instance where the selection is taking place.
* @param {Index} index - The selected index or indices representing the data points or elements.
* @param {Element[]} selectedElements - The corresponding elements that are selected during the process.
* @returns {void}
*/
Selection3D.prototype.selection = function (chart, index, selectedElements) {
if (!chart.isMultiSelect && (this.styleId.indexOf('highlight') === -1 &&
chart.selectionMode !== 'None')) {
this.removeMultiSelectElements(chart, this.selectedDataIndexes, index, chart.series);
}
var indexValue = index.series;
if (!isNullOrUndefined(selectedElements[0])) {
if (chart.visibleSeries[indexValue].isRectSeries) {
if (selectedElements[0].id) {
if (document.getElementById(selectedElements[0].id + '_Symbol')) {
selectedElements.push(getElement(selectedElements[0].id + '_Symbol'));
}
}
}
var isAdd = void 0;
var className = selectedElements[0] && (selectedElements[0].getAttribute('class') || '');
if (selectedElements[0] && className.indexOf(this.getSelectionClass(selectedElements[0].id)) > -1) {
this.removeStyles(selectedElements);
}
else {
this.previousSelectedEle = (chart.highlightMode !== 'None' || chart.legendSettings.enableHighlight) ? selectedElements : [];
if (this.chart.selection3DModule) {
this.chart.selection3DModule.previousSelectedEle = selectedElements;
}
this.applyStyles(selectedElements);
isAdd = true;
}
if (this.styleId.indexOf('highlight') > 0 && (chart.highlightMode !== 'None' || chart.legendSettings.enableHighlight)) {
this.addOrRemoveIndex(this.highlightDataIndexes, index, isAdd);
}
else {
this.addOrRemoveIndex(this.selectedDataIndexes, index, isAdd);
}
}
};
/**
* Handles the cluster selection process in the Chart3D.
*
* @param {Chart3D} chart - The Chart3D instance where the cluster selection is taking place.
* @param {Index} index - The selected index or indices representing the cluster.
* @returns {void}
*/
Selection3D.prototype.clusterSelection = function (chart, index) {
this.selection(chart, index, this.getClusterElements(chart, new Index(index.series, index.point)));
};
/**
* Removes the selected elements during a multi-select operation in the Chart3D.
*
* @param {Chart3D} chart - The Chart3D instance where the multi-select operation is taking place.
* @param {Index[]} index - An array of selected indices to be removed.
* @param {Index} currentIndex - The current index representing the selection.
* @param {Chart3DSeriesModel[]} seriesCollection - The collection of series in the Chart3D.
* @returns {void}
*/
Selection3D.prototype.removeMultiSelectElements = function (chart, index, currentIndex, seriesCollection) {
var series;
for (var i = 0; i < index.length; i++) {
series = seriesCollection[index[i].series];
if ((this.isSeriesMode && !this.toEquals(index[i], currentIndex, this.isSeriesMode)) ||
(this.currentMode === 'Cluster' && !this.toEquals(index[i], currentIndex, false)) ||
(!this.isSeriesMode && this.toEquals(index[i], currentIndex, true) &&
!this.toEquals(index[i], currentIndex, false))) {
this.removeStyles(this.findElements(chart, series, index[i]));
index.splice(i, 1);
i--;
}
}
};
/**
* Applies a blur effect to the specified chart elements for visual emphasis.
*
* @param {string} chartId - The unique identifier of the target chart where the blur effect is applied.
* @param {Chart3DSeries[]} visibleSeries - An array of visible series in the chart.
* @returns {void}
*/
Selection3D.prototype.blurEffect = function (chartId, visibleSeries) {
var visibility = (this.checkVisibility(this.highlightDataIndexes, this.chart) ||
this.checkVisibility(this.selectedDataIndexes, this.chart));
var _loop_2 = function (series) {
var legendIndex = series.index;
var legendStrokeColor = this_2.chart.visibleSeries[series.index].interior;
var pointElements = [];
if (series.visible) {
var elements = document.querySelectorAll("[id*=\"region-series-" + series.index + "\"]");
elements.forEach(function (el) {
pointElements.push(el);
});
this_2.checkSelectionElements(pointElements, this_2.generateStyle(series), visibility, legendIndex, legendStrokeColor);
if (!isNullOrUndefined(getElement(chartId + 'SymbolGroup' + series.index))) {
this_2.checkSelectionElements(pointElements, this_2.generateStyle(series), visibility, legendIndex, legendStrokeColor);
}
}
};
var this_2 = this;
for (var _i = 0, visibleSeries_1 = visibleSeries; _i < visibleSeries_1.length; _i++) {
var series = visibleSeries_1[_i];
_loop_2(series);
}
};
/**
* Checks the selection status of specified chart elements and updates their appearance.
*
* @param {Element[] | Element} element - The chart elements or a single element to be checked for selection.
* @param {string} className - The CSS class name used to identify selected elements.
* @param {boolean} visibility - A boolean indicating whether the elements should be visible or hidden based on selection.
* @param {number} [series=0] - The index of the series if the specified elements are series.
* @param {string} [legendStrokeColor='#D3D3D3'] - The stroke color used for legends when they are selected.
* @returns {void}
*/
Selection3D.prototype.checkSelectionElements = function (element, className, visibility, series, legendStrokeColor) {
if (series === void 0) { series = 0; }
if (legendStrokeColor === void 0) { legendStrokeColor = '#D3D3D3'; }
var children = (this.isSeriesMode ? element || [element] : element);
if (this.chart.selectionMode !== 'None' && (this.chart.highlightMode !== 'None' || this.chart.legendSettings.enableHighlight)) {
children = element;
}
var elementClassName;
var parentClassName;
var legendShape;
var selectElement = element;
for (var i = 0; i < children.length; i++) {
elementClassName = children[i].getAttribute('class') || '';
parentClassName = children[i].parentNode.getAttribute('class') || '';
if (this.chart.selectionMode !== 'None' && (this.chart.highlightMode !== 'None' || this.chart.legendSettings.enableHighlight)) {
className = elementClassName.indexOf('selection') > 0 ||
elementClassName.indexOf('highlight') > 0 ? elementClassName : className;
}
if (elementClassName.indexOf(className) === -1 &&
parentClassName.indexOf(className) === -1 && visibility) {
this.addSvgClass(children[i], this.unselected);
}
else {
selectElement = children[i];
if (elementClassName.indexOf(this.unselected) !== -1 && this.chart.tooltip3DModule && className.indexOf('highlight') > 0) {
this.chart.highlightAnimation(children[i], series, 700, 0.3);
}
this.removeSvgClass(children[i], this.unselected);
this.removeSvgClass(children[i].parentNode, this.unselected);
}
}
if (this.control.legend3DModule && this.control.legendSettings.visible) {
legendShape = getElement(this.control.element.id + '_chart_legend_shape_' + series);
if (legendShape) {
if (legendShape.hasAttribute('class')) {
this.removeSvgClass(legendShape, legendShape.getAttribute('class'));
if (!isNullOrUndefined(this.chart.highlightColor && this.chart.highlightColor !== '') && !this.chart.legendSettings.enableHighlight) {
legendShape.setAttribute('stroke', legendStrokeColor);
if (this.chart.highlightPattern === 'None') {
legendShape.setAttribute('fill', legendStrokeColor);
}
}
}
if (selectElement.length > 0) {
elementClassName = selectElement[0].getAttribute('class');
parentClassName = selectElement[0].parentNode.getAttribute('class') || '';
}
else if (selectElement) {
elementClassName = selectElement.getAttribute('class') || '';
parentClassName = selectElement.parentNode.getAttribute('class') || '';
}
if (elementClassName.indexOf(className) === -1 && parentClassName.indexOf(className) === -1 && visibility) {
this.addSvgClass(legendShape, (this.chart.highlightMode === 'None' && this.chart.legendSettings.enableHighlight) ? className : this.unselected);
this.removeSvgClass(legendShape, className);
if (this.chart.highlightColor !== '' && !isNullOrUndefined(this.chart.highlightColor)) {
legendShape.setAttribute('stroke', this.control.visibleSeries[series].interior);
if (this.chart.highlightPattern === 'None') {
legendShape.setAttribute('fill', this.control.visibleSeries[series].interior);
}
}
}
else {
this.removeSvgClass(legendShape, this.unselected);
if (!isNullOrUndefined(this.chart.highlightColor) && this.chart.highlightColor !== '') {
legendShape.setAttribute('stroke', this.control.visibleSeries[series].interior);
if (this.chart.highlightPattern === 'None') {
legendShape.setAttribute('fill', this.control.visibleSeries[series].interior);
}
}
if ((elementClassName === '' && parentClassName === '') || elementClassName.trim() === 'EJ2-Trackball') {
this.removeSvgClass(legendShape, className);
}
else {
this.addSvgClass(legendShape, className);
if (className.indexOf('highlight') > 0 && this.chart.highlightColor !== '' && this.chart.highlightColor !== 'transparent' && !isNullOrUndefined(this.chart.highlightColor)) {
legendShape.setAttribute('stroke', this.chart.highlightColor);
if (this.styleId.indexOf('highlight') > 0 && this.chart.highlightPattern === 'None') {
legendShape.setAttribute('fill', this.chart.highlightColor);
}
}
}
}
}
}
};
/**
* Applies custom styles to the specified chart elements.
*
* @param {Element[]} elements - An array of chart elements to which custom styles will be applied.
* @returns {void}
*/
Selection3D.prototype.applyStyles = function (elements) {
for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {
var element = elements_1[_i];
if (element) {
this.removeSvgClass(element.parentNode, this.unselected);
this.removeSvgClass(element, this.unselected);
if (this.chart.series[0].pointColorMapping === 'fill') {
var className = this.getSelectionClass(element.id);
var index = className.indexOf('highlight') > -1 ? parseInt(className.split(this.chart.element.id + '_ej2_chart_highlight_series_')[1], 10) : parseInt(className.split(this.chart.element.id + '_ej2_chart_selection_series_')[1], 10);
var patternName = this.styleId.indexOf('highlight') > 0 ? this.chart.highlightPattern : this.chart.selectionPattern;
var pattern = void 0;
if (className.indexOf('highlight') > -1 || className.indexOf('selection') > -1) {
pattern = document.getElementById(this.chart.element.id + '_' + patternName + '_' + 'Selection' + '_' + index);
}
if (element.id.indexOf('legend') === -1 && element.id.indexOf('Group') === -1 && pattern != null) {
for (var i = 1; i < pattern.children.length; i++) {
pattern.children[i].setAttribute('fill', element.getAttribute('fill'));
pattern.children[i].setAttribute('stroke', element.getAttribute('fill'));
}
}
}
this.addSvgClass(element, this.getSelectionClass(element.id));
if (this.chart.tooltip3DModule && this.getSelectionClass(element.id).indexOf('highlight') > 0) {
var index = parseFloat(element.id.split('-series-')[1].split('-point-')[0]);
this.chart.stopElementAnimation(element, index);
}
if (this.styleId.indexOf('highlight') > 0 && this.chart.highlightColor !== '' && !isNullOrUndefined(this.chart.highlightColor) && this.chart.highlightPattern === 'None' && this.chart.highlightColor !== 'transparent') {
element.setAttribute('fill', this.chart.highlightColor);
}
}
}
};
/**
* Gets the CSS class name associated with the selection for a specific chart element.
*
* @param {string} id - A unique identifier for the selected element.
* @returns {string} The CSS class name associated with the selection for the selected element.
*/
Selection3D.prototype.getSelectionClass = function (id) {
return this.generateStyle(this.control.visibleSeries[this.indexFinder(id).series]);
};
/**
* Removes styles associated with the selection from the selected elements.
*
*
* @param {Element[]} elements - An array of chart elements from which selection styles should be removed.
* @returns {void}
*/
Selection3D.prototype.removeStyles = function (elements) {
for (var _i = 0, elements_2 = elements; _i < elements_2.length; _i++) {
var element = elements_2[_i];
if (element) {
this.removeSvgClass(element, this.getSelectionClass(element.id));
if (this.chart.highlightPattern === 'None' && this.chart.highlightColor !== '' && !isNullOrUndefined(this.chart.highlightColor) && this.chart.highlightColor !== 'transparent') {
var color = this.control.visibleSeries[this.indexFinder(element.id).series].interior;
if (element.getAttribute('name') === 'ZLight') {
color = this.chart.polygon.applyZLight(color, this.control);
}
if (element.getAttribute('name') === 'XLight') {
color = this.chart.polygon.applyXLight(color, this.control);
}
element.setAttribute('fill', color);
}
}
}
};
/**
* Adds or removes an index from the specified array based on the provided condition.
*
* @param {Index[]} indexes - The array of indexes to be modified.
* @param {Index} index - The index to be added or removed.
* @param {boolean} [isAdd=true] - A boolean flag indicating whether to add or remove the index.
* @returns {void}
* @private
*/
Selection3D.prototype.addOrRemoveIndex = function (indexes, index, isAdd) {
for (var i = 0; i < indexes.length; i++) {
if (this.toEquals(indexes[i], index, this.isSeriesMode)) {
indexes.splice(i, 1);
i--;
}
}
if (isAdd) {
indexes.push(index);
}
};
/**
* Compares two Index objects for equality.
*
* @param {Index} first - The first Index object to compare.
* @param {Index} second - The second Index object to compare.
* @param {boolean} [checkSeriesOnly=false] - A boolean flag indicating whether to
* @returns {boolean} - True if the Index objects are equal; otherwise, false.
*/
Selection3D.prototype.toEquals = function (first, second, checkSeriesOnly) {
return ((first.series === second.series || (this.currentMode === 'Cluster' && !checkSeriesOnly))
&& (checkSeriesOnly || (first.point === second.point)));
};
/**
* Redraws the selection in the 3D chart.
*
* @param {Chart3D} chart - The 3D chart instance where the selection needs to be redrawn.
* @param {Chart3DSelectionMode | HighlightMode} oldMode - The previous selection mode ('Series', 'Point', etc.).
* @param {boolean} [chartRedraw=false] - A boolean flag indicating whether to trigger a chart redraw.
* @returns {void}
*/
Selection3D.prototype.redrawSelection = function (chart, oldMode, chartRedraw) {
this.isSeriesMode = oldMode === 'Series';
if (!isNullOrUndefined(oldMode)) {
if (chartRedraw) {
chart.isRedrawSelection = false;
}
else {
chart.isRedrawSelection = true;
}
}
var selectedDataIndexes = extend([], this.selectedDataIndexes, null, true);
var highlightDataIndexes = extend([], this.highlightDataIndexes, null, true);
if (this.styleId.indexOf('highlight') > 0 && highlightDataIndexes.length > 0) {
this.removeSelectedElements(chart, this.highlightDataIndexes, chart.series);
selectedDataIndexes = highlightDataIndexes;
}
else {
this.removeSelectedElements(chart, this.selectedDataIndexes, chart.series);
}
this.blurEffect(chart.element.id, chart.visibleSeries);
this.selectDataIndex(chart, selectedDataIndexes);
};
/**
* Handles the selection in the legend for the 3D chart.
*
* @param {Chart3D} chart - The 3D chart instance associated with the legend.
* @param {number} series - The index of the series in the legend.
* @param {Element} targetElement - The HTML element that triggered the selection event.
* @param {string} eventType - The type of event that triggered the selection.
* @returns {void}
*/
Selection3D.prototype.legendSelection = function (chart, series, targetElement, eventType) {
if (eventType === 'mousemove') {
if (targetElement.id.indexOf('text') > 1) {
targetElement = getElement(targetElement.id.replace('text', 'shape'));
}
if (targetElement.id.indexOf('marker') > 1) {
targetElement = getElement(targetElement.id.replace('_marker', ''));
}
if (targetElement.id.indexOf('g') > 1) {
targetElement = getElement(targetElement.id.replace('_g_', '_shape_'));
}
if (targetElement.hasAttribute('class') && (targetElement.getAttribute('class').indexOf('highlight') > -1 ||
targetElement.getAttribute('class').indexOf('selection') > -1)) {
return;
}
this.currentMode = this.chart.highlightMode;
}
else if (eventType === 'click') {
if (targetElement.id.indexOf('text') > 1) {
targetElement = getElement(targetElement.id.replace('text', 'shape'));
}
if (targetElement.id.indexOf('g') > 1) {
targetElement = getElement(targetElement.id.replace('_g_', '_shape_'));
}
}
var index = this.indexFinder(targetElement.id);
var isPreSelected = this.isAlreadySelected(targetElement, eventType, index);
if (isPreSelected) {
var seriesStyle = this.generateStyle(chart.visibleSeries[series]);
var selectedElements = (document.querySelectorAll('.' + seriesStyle));
this.isSeriesMode = this.currentMode === 'Series';
var isBlurEffectNeeded = true;
if (selectedElements.length > 0) {
this.removeSelection(chart, series, selectedElements, seriesStyle, isBlurEffectNeeded);
}
else {
for (var _i = 0, _a = chart.visibleSeries; _i < _a.length; _i++) {
var element = _a[_i];
if (element.index !== series && !chart.isMultiSelect) {
seriesStyle = this.generateStyle(chart.visibleSeries[element.index]);
selectedElements = document.querySelectorAll('.' + seriesStyle);
this.removeSelection(chart, series, selectedElements, seriesStyle, isBlurEffectNeeded);
}
}
var seriesElements = [];
if (this.chart.legendSettings.mode === 'Point') {
seriesElements = this.getElementByIndex(chart, index);
}
else {
seriesElements = this.getSeriesElements(chart.visibleSeries[series]);
}
if (seriesElements.length > 0) {
this.checkSelectionElements(seriesElements, seriesStyle, false, series, '');
this.isSeriesMode = true;
this.selection(chart, new Index(index.series, NaN), seriesElements);
this.isSeriesMode = chart.selectionMode === 'Series';
this.blurEffect(chart.element.id, chart.visibleSeries);
}
}
}
};
/**
* Handles the removal of selection in the 3D chart.
*
* @param {Chart3D} chart - The 3D chart instance where the selection needs to be removed.
* @param {number} series - The index of the series for which the selection is being removed.
* @param {NodeListOf<HTMLElement>} selectedElements - The HTML elements representing the selected items.
* @param {string} seriesStyle - The style to be applied to the series after the removal of selection.
* @param {boolean} isBlurEffectNeeded - A flag indicating whether a blur effect is needed after the removal of selection.
* @returns {void}
*/
Selection3D.prototype.removeSelection = function (chart, series, selectedElements, seriesStyle, isBlurEffectNeeded) {
if (selectedElements.length > 0) {
var elements = [];
for (var i = 0; i < selectedElements.length; i++) {
elements.push(selectedElements[i]);
}
this.removeStyles(elements);
this.isSeriesMode = true;
this.addOrRemoveIndex(this.selectedDataIndexes, new Index(series, NaN));
for (var _i = 0, _a = chart.visibleSeries; _i < _a.length; _i++) {
var value = _a[_i];
seriesStyle = this.generateStyle(value);
if (document.querySelectorAll('.' + seriesStyle).length > 0) {
for (var _b = 0, elements_3 = elements; _b < elements_3.length; _b++) {
var element = elements_3[_b];
this.checkSelectionElements(element, seriesStyle, true, series, '');
}
isBlurEffectNeeded = false;
break;
}
}
if (isBlurEffectNeeded) {
this.isSeriesMode = chart.selectionMode === 'Series';
this.blurEffect(chart.element.id, chart.visibleSeries);
}
}
};
/**
* Retrieves the HTML elements associated with a specific 3D chart series.
*
* @param {Chart3DSeriesModel | Chart3DSeries} series - The 3D chart series for which HTML elements are to be retrieved.
* @returns {Element[]} An array of HTML elements representing the graphical elements of the specified 3D chart series.
* @private
*/
Selection3D.prototype.getSeriesElements = function (series) {
var seriesElements = [];
if (series.visible) {
var elements = document.querySelectorAll("[id*=\"region-series-" + series.index + "\"]");
elements.forEach(function (seriesElement) {
seriesElements.push(seriesElement);
});
}
return seriesElements;
};
/**
* Finds and returns the index associated with the specified identifier.
*
* @param {string} id - The identifier used to find the associated index.
* @returns {Index} The index associated with the specified identifier.
* @private
*/
Selection3D.prototype.indexFinder = function (id) {
var ids = ['NaN', 'NaN'];
if (id.indexOf('-point-') > -1) {
ids = id.split('-series-')[1].split('-point-');
}
else if (id.indexOf('-border-') > -1) {
ids[0] = id.split('-border-')[1];
}
else if (id.indexOf('-series-') > -1) {
ids[0] = id.split('-series-')[1];
}
else if (id.indexOf('_chart_legend_shape_') > -1) {
ids = id.split('_chart_legend_shape_');
ids[0] = ids[1];
}
return new Index(parseInt(ids[0], 10), parseInt(ids[1], 10));
};
/**
* Removes the selected elements from the chart based on the specified indices.
*
* @param {Chart3D} chart - The 3D chart instance.
* @param {Index[]} index - The array of indices representing the selected elements to be removed.
* @param {Chart3DSeriesModel[]} seriesCollection - The collection of series models.
* @returns {void}
* @private
*/
Selection3D.prototype.removeSelectedElements = function (chart, index, seriesCollection) {
index = chart.isRedrawSelection ? index : index.splice(0, index.length);
var seriesElements;
for (var _i = 0, seriesCollection_1 = seriesCollection; _i < seriesCollection_1.length; _i++) {
var series = seriesCollection_1[_i];
if (series.visible) {
seriesElements = this.getSeriesElements(series);
this.removeStyles(seriesElements);
for (var _a = 0, seriesElements_1 = seriesElements; _a < seriesElements_1.length; _a++) {
var seriesElement = seriesElements_1[_a];
this.removeStyles(this.getChildren(seriesElement));
}
}
}
};
/**
* Handles the mouse leave event for the 3D chart.
*
* @returns {void}
* @private
*/
Selection3D.prototype.mouseLeave = function () {
this.completeSelection();
};
/**
* Completes the selection process based on the specified target element and event type.
*
* @returns {void}
* @private
*/
Selection3D.prototype.completeSelection = function () {
var chart = this.chart;
if (chart.selectionMode === 'None') {
return;
}
this.currentMode = chart.selectionMode;
};
/**
* Handles the mouse move event, typically used for tracking the movement of the mouse pointer.
* This method is marked as private to indicate that it should not be used externally.
*
* @param {PointerEvent | TouchEvent} event - The event object representing the mouse move or touch event.
* @returns {void}
* @private
*/
Selection3D.prototype.mouseMove = function (event) {
var chart = this.chart;
var target = event.target;
var eventType = event.type;
this.highlightChart(target, eventType);
if (chart.selectionMode === 'None') {
return;
}
if (eventType === 'touchmove' && (Browser.isIos || Browser.isIos7) && event.preventDefault) {
event.preventDefault();
}
};
/**
* Highlights the series elements based on the specified target element and event type.
*
* @param {Element} target - The target element on which the highlight action is performed.
* @param {string} eventType - The type of the event.
* @returns {void}
*/
Selection3D.prototype.highlightChart = function (target, eventType) {
if (!this.chart.rotateActivate && (this.chart.highlightMode !== 'None' || this.chart.legendSettings.enableHighlight)) {
if (!isNullOrUndefined(target)) {
if (target.id.indexOf('_legend_text') > 1) {
target = getElement(target.id.replace('text', 'shape'));
}
if ((target).hasAttribute('class') && ((target).getAttribute('class').indexOf('highlight') > -1 ||
target.getAttribute('class').indexOf('selection') > -1)) {
return;
}
this.calculateSelectedElements(target, eventType);
if (this.chart.highlight3DModule.highlightDataIndexes && this.chart.highlight3DModule.highlightDataIndexes.length > 0 &&
target.id.indexOf('_chart_legend_') === -1 && target.id.indexOf('-series-') === -1) {
this.removeLegendHighlightStyles();
}
}
return;
}
};
/**
* remove highlighted legend when not focused.
*
* @returns {void}
* @private
*/
Selection3D.prototype.removeLegendHighlightStyles = function () {
this.chart.highlight3DModule.highlightDataIndexes = [];
var elementCollection;
for (var i = 0; i < this.chart.visibleSeries.length; i++) {
elementCollection