UNPKG

@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,125 lines 93.3 kB
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 __()); }; })(); var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; /** * AccumulationChart file */ import { Property, Component, Complex, Collection, NotifyPropertyChanges, animationMode, SanitizeHtmlHelper } from '@syncfusion/ej2-base'; import { Internationalization, Event, Browser, EventHandler, Touch } from '@syncfusion/ej2-base'; import { remove, extend, isNullOrUndefined, updateBlazorTemplate } from '@syncfusion/ej2-base'; import { Margin, Border, TooltipSettings, CenterLabel, Indexes, Accessibility, TitleStyleSettings } from '../common/model/base'; import { AccumulationSeries, PieCenter } from './model/acc-base'; import { getThemeColor } from '../common/model/theme'; import { load, pointClick } from '../common/model/constants'; import { pointMove, chartDoubleClick, chartMouseClick, chartMouseDown } from '../common/model/constants'; import { chartMouseLeave, chartMouseMove, chartMouseUp, resized, beforeResize } from '../common/model/constants'; import { LegendSettings } from '../common/legend/legend'; import { indexFinder, appendChildElement, redrawElement, blazorTemplatesReset, getTextAnchor, stringToNumber, textWrap, subtractRect } from '../common/utils/helper'; import { RectOption, showTooltip, ImageOption } from '../common/utils/helper'; import { textElement, createSvg, calculateSize, removeElement, firstToLowerCase, withInBounds } from '../common/utils/helper'; import { getElement, titlePositionX } from '../common/utils/helper'; import { Rect, Size, measureText, TextOption } from '@syncfusion/ej2-svg-base'; import { Data } from '../common/model/data'; import { AccumulationBase } from './renderer/accumulation-base'; import { PieSeries } from './renderer/pie-series'; import { AccumulationAnnotationSettings } from './model/acc-base'; import { getTitle, AccPointData } from '../common/utils/helper'; import { Animation } from '@syncfusion/ej2-base'; import { PrintUtils } from '../common/utils/print'; import { createTemplate } from '../common/utils/helper'; import { createElement } from '@syncfusion/ej2-base'; /** * Represents the AccumulationChart control. * ```html * <div id="accumulation"/> * <script> * var accObj = new AccumulationChart({}); * accObj.appendTo("#accumulation"); * </script> * ``` * * @public */ var AccumulationChart = /** @class */ (function (_super) { __extends(AccumulationChart, _super); /** * Constructor for creating the AccumulationChart widget. * * @private * @param {AccumulationChartModel} options - Specifies the accumulation chart model. * @param {string | HTMLElement} element - Specifies the element for the accumulation chart. */ function AccumulationChart(options, element) { var _this = _super.call(this, options, element) || this; /** @private */ _this.animateselected = false; /** @private */ _this.explodeDistance = 0; /** @private */ _this.currentLegendIndex = 0; /** @private */ _this.currentPointIndex = 0; /** @private */ _this.previousTargetId = ''; /** @private */ _this.isLegendClicked = false; _this.chartid = 57724; return _this; } /** * Animate the series bounds on data change. * * @private * @param {number} duration - The duration of the animation. * @returns {void} */ AccumulationChart.prototype.animate = function (duration) { this.duration = (duration === 0 && animationMode === 'Enable') ? 700 : duration; this.animateselected = true; this.animateSeries = false; var temIndex = 0; var tempcolor = []; var tempindex = []; var tempindex1 = []; var currentSeries = this.visibleSeries[0]; var datasource = []; datasource = currentSeries.dataSource; currentSeries.sumOfPoints = 0; if (currentSeries.points.length < Object.keys(currentSeries.dataSource).length) { this.refresh(); } else if (currentSeries.points.length > Object.keys(currentSeries.dataSource).length) { var currentSeries_1 = this.visibleSeries[0]; currentSeries_1.points = currentSeries_1.points.filter(function (entry1) { entry1.visible = false; tempindex.push(entry1.index); tempcolor.push(entry1.color); return (datasource).some(function (entry2) { var accPoint = entry2; if (entry1.x === accPoint.x) { entry1.visible = true; tempindex1.push(entry1.index); entry1.index = temIndex; temIndex++; } return entry1.x === accPoint.x; }); }); var missing = tempindex.filter(function (item) { return tempindex1.indexOf(item) < 0; }); var interval = tempindex.length - missing.length; for (var i = (tempindex.length - 1); i >= interval; i--) { removeElement('container_Series_0_Point_' + tempindex[i]); } for (var i = 0; i < currentSeries_1.points.length; i++) { currentSeries_1.points[i].y = currentSeries_1.dataSource[i].y; currentSeries_1.points[i].color = tempcolor[i]; currentSeries_1.sumOfPoints += currentSeries_1.dataSource[i].y; } this.redraw = this.enableAnimation; this.animateSeries = false; this.calculateBounds(); this.renderElements(); } else { for (var i = 0; i < currentSeries.points.length; i++) { currentSeries.points[i].y = currentSeries.dataSource[i][currentSeries.yName]; currentSeries.points[i].color = currentSeries.dataSource[i][currentSeries.pointColorMapping] != null ? currentSeries.dataSource[i][currentSeries.pointColorMapping] : currentSeries.points[i].color; currentSeries.sumOfPoints += currentSeries.dataSource[i][currentSeries.yName]; } this.redraw = this.enableAnimation; this.animateSeries = false; this.removeSvg(); this.refreshPoints(currentSeries.points); this.renderElements(); } }; Object.defineProperty(AccumulationChart.prototype, "type", { /** * Gets the type of accumulation chart. * * @returns {AccumulationType} - The type of accumulation chart. * @private * */ get: function () { if (this.series && this.series.length) { return this.series[0].type; } return 'Pie'; }, enumerable: true, configurable: true }); // accumulation chart methods. /** * To create svg object, renderer and binding events for the container. * * @returns {void} */ AccumulationChart.prototype.preRender = function () { var blazor = 'Blazor'; this.isBlazor = window[blazor]; this.allowServerDataBinding = false; this.unWireEvents(); this.setCulture(); this.animateSeries = true; if (this.element.id === '') { var collection = document.getElementsByClassName('e-accumulationchart').length; var elementid = 'acc_chart_' + this.chartid + '_' + collection; while (document.getElementById(elementid)) { collection++; elementid = 'acc_chart_' + this.chartid + '_' + collection; } this.element.id = 'acc_chart_' + this.chartid + '_' + collection; } this.wireEvents(); this.element.setAttribute('dir', this.enableRtl ? 'rtl' : 'ltr'); this.element.style.outline = 'none'; }; /** * Themeing for chart goes here. * * @returns {void} */ AccumulationChart.prototype.setTheme = function () { /** Set theme for accumulation chart */ this.themeStyle = getThemeColor(this.theme, false, this); }; /** * To render the accumulation chart elements. * * @returns {void} */ AccumulationChart.prototype.render = function () { var _this = this; if (this.element.className.indexOf('e-accumulationchart') === -1) { this.element.classList.add('e-accumulationchart'); } this.element.setAttribute('role', this.accessibility.accessibilityRole ? this.accessibility.accessibilityRole : 'region'); this.element.setAttribute('tabindex', this.accessibility.focusable ? String(this.accessibility.tabIndex) : '-1'); this.element.setAttribute('aria-label', this.accessibility.accessibilityDescription ? this.accessibility.accessibilityDescription : this.title + '. Syncfusion interactive chart.'); this.element.setAttribute('class', this.element.getAttribute('class') + ' e-accumulationchart-focused'); var loadEventData = { chart: this.isBlazor ? {} : this, accumulation: this.isBlazor ? {} : this, theme: this.theme, name: load, cancel: false }; this.trigger(load, loadEventData, function () { _this.theme = _this.isBlazor ? loadEventData.theme : _this.theme; _this.setTheme(); _this.accBaseModule = new AccumulationBase(_this); _this.pieSeriesModule = new PieSeries(_this); _this.calculateVisibleSeries(); _this.processData(); _this.renderComplete(); _this.allowServerDataBinding = true; }); }; /** * Method to unbind events for accumulation chart. * * @returns {void} */ AccumulationChart.prototype.unWireEvents = function () { /** Find the Events type */ var isIE11Pointer = Browser.isPointer; var start = Browser.touchStartEvent; var move = Browser.touchMoveEvent; var stop = Browser.touchEndEvent; var cancel = isIE11Pointer ? 'pointerleave' : 'mouseleave'; /** UnBind the Event handler */ EventHandler.remove(this.element, move, this.accumulationMouseMove); EventHandler.remove(this.element, stop, this.accumulationMouseEnd); EventHandler.remove(this.element, start, this.accumulationMouseStart); EventHandler.remove(this.element, 'click', this.accumulationOnMouseClick); EventHandler.remove(this.element, 'dblclick', this.accumulationOnDoubleClick); EventHandler.remove(this.element, 'contextmenu', this.accumulationRightClick); EventHandler.remove(this.element, cancel, this.accumulationMouseLeave); EventHandler.remove(this.element, 'keydown', this.accumulationChartKeyDown); EventHandler.remove(document.body, 'keydown', this.documentKeyHandler); EventHandler.remove(this.element, 'keyup', this.accumulationChartKeyUp); window.removeEventListener((Browser.isTouch && ('orientation' in window && 'onorientationchange' in window)) ? 'orientationchange' : 'resize', this.accumulationResizeBound); }; /** * Method to bind events for the accumulation chart. * * @returns {void} */ AccumulationChart.prototype.wireEvents = function () { /** * To fix react timeout destroy issue. */ if (!this.element) { return; } /** Find the Events type */ var isIE11Pointer = Browser.isPointer; var start = Browser.touchStartEvent; var stop = Browser.touchEndEvent; var move = Browser.touchMoveEvent; var cancel = isIE11Pointer ? 'pointerleave' : 'mouseleave'; /** Bind the Event handler */ EventHandler.add(this.element, move, this.accumulationMouseMove, this); EventHandler.add(this.element, stop, this.accumulationMouseEnd, this); EventHandler.add(this.element, start, this.accumulationMouseStart, this); EventHandler.add(this.element, 'click', this.accumulationOnMouseClick, this); EventHandler.add(this.element, 'dblclick', this.accumulationOnDoubleClick, this); EventHandler.add(this.element, 'contextmenu', this.accumulationRightClick, this); EventHandler.add(this.element, cancel, this.accumulationMouseLeave, this); EventHandler.add(this.element, 'keydown', this.accumulationChartKeyDown, this); EventHandler.add(document.body, 'keydown', this.documentKeyHandler, this); EventHandler.add(this.element, 'keyup', this.accumulationChartKeyUp, this); this.accumulationResizeBound = this.accumulationResize.bind(this); window.addEventListener((Browser.isTouch && ('orientation' in window && 'onorientationchange' in window)) ? 'orientationchange' : 'resize', this.accumulationResizeBound); new Touch(this.element); // To avoid geasture blocking for browser /** Apply the style for chart */ this.setStyle(this.element); }; /** * Method to set mouse x, y from events. * * @param {PointerEvent} e - The pointer event containing mouse coordinates. * @returns {void} */ AccumulationChart.prototype.setMouseXY = function (e) { var pageX; var pageY; var svgRectElement = getElement(this.element.id + '_svg'); if (svgRectElement && this.element) { var svgRect = svgRectElement.getBoundingClientRect(); var rect = this.element.getBoundingClientRect(); if (e.type.indexOf('touch') > -1) { this.isTouch = true; var touchArg = e; pageY = touchArg.changedTouches[0].clientY; pageX = touchArg.changedTouches[0].clientX; } else { this.isTouch = e.pointerType === 'touch' || e.pointerType === '2'; pageX = e.clientX; pageY = e.clientY; } this.mouseY = (pageY - rect.top) - Math.max(svgRect.top - rect.top, 0); this.mouseX = (pageX - rect.left) - Math.max(svgRect.left - rect.left, 0); } }; /** * Handles the mouse end. * * @param {PointerEvent} e - The pointer event containing mouse coordinates. * @returns {boolean} - Mouse end of accumulation chart. * @private */ AccumulationChart.prototype.accumulationMouseEnd = function (e) { this.setMouseXY(e); this.trigger(chartMouseUp, { target: e.target.id, x: this.mouseX, y: this.mouseY }); if (this.isTouch) { this.titleTooltip(e, this.mouseX, this.mouseY, this.isTouch); if (this.accumulationDataLabelModule && this.visibleSeries[0].dataLabel.visible) { this.accumulationDataLabelModule.move(e, this.mouseX, this.mouseY, this.isTouch); } if (this.accumulationLegendModule && this.legendSettings.visible) { this.accumulationLegendModule.move(e); } } if (this.centerLabel.hoverTextFormat) { this.updateCenterLabel(e); } this.notify(Browser.touchEndEvent, e); return false; }; /*public removeSvgOffset(x: number, y: number): ChartLocation { let rect: ClientRect = this.element.getBoundingClientRect(); let svgRect: ClientRect = getElement(this.element.id + '_svg').getBoundingClientRect(); return { x: (x - rect.left) - Math.max(svgRect.left - rect.left, 0), y: (y - rect.top) - Math.max(svgRect.top - rect.top, 0)}; }*/ /** * Handles the mouse start. * * @param {PointerEvent} e - The pointer event containing mouse coordinates. * @returns {boolean} - Mouse start of accumulation chart. * @private */ AccumulationChart.prototype.accumulationMouseStart = function (e) { this.setMouseXY(e); this.trigger(chartMouseDown, { target: e.target.id, x: this.mouseX, y: this.mouseY }); return false; }; /** * Handles the accumulation chart resize. * * @returns {boolean} - Resize method of accumulation chart. * @private */ AccumulationChart.prototype.accumulationResize = function () { var _this = this; this.animateSeries = false; var args = { accumulation: this.isBlazor ? {} : this, previousSize: new Size(this.availableSize.width, this.availableSize.height), name: resized, currentSize: new Size(0, 0), chart: this.isBlazor ? {} : this }; var beforeResizeArgs = { name: 'beforeResize', cancelResizedEvent: false }; if (this.resizeTo) { clearTimeout(this.resizeTo); } this.trigger(beforeResize, beforeResizeArgs); if (!beforeResizeArgs.cancelResizedEvent) { this.resizeTo = +setTimeout(function () { if (_this.isDestroyed) { clearTimeout(_this.resizeTo); return; } calculateSize(_this); args.currentSize = _this.availableSize; _this.trigger(resized, args); _this.refreshSeries(); _this.refreshChart(); }, 500); } return false; }; /** * Handles the print method for accumulation chart control. * * @param {string[] | string | Element} id - The id of the accumulation chart to be printed on the page. * @returns {void} */ AccumulationChart.prototype.print = function (id) { // To handle the print funtion in IE and Edge browsers var clippath = document.getElementById(this.element.id + '_Series_0').style.clipPath; document.getElementById(this.element.id + '_Series_0').style.clipPath = ''; var exportChart = new PrintUtils(this); exportChart.print(id); document.getElementById(this.element.id + '_Series_0').style.clipPath = clippath; }; /** * Export method for the chart. * * @param {ExportType} type - The type of export. * @param {string} fileName - The name of the file for export. * @returns {void} */ AccumulationChart.prototype.export = function (type, fileName) { if (this.exportModule) { this.exportModule.export(type, fileName); if (this.afterExport) { this.exportModule.getDataUrl(this); } } }; /** * Applying styles for accumulation chart element. * * @param {HTMLElement} element - Specifies the element. * @returns {void} */ AccumulationChart.prototype.setStyle = function (element) { element.style.touchAction = 'element'; element.style.msTouchAction = 'element'; element.style.msContentZooming = 'none'; element.style.msUserSelect = 'none'; element.style.webkitUserSelect = 'none'; element.style.position = 'relative'; element.style.display = 'block'; element.style.height = (element.style.height || (this.height && this.height.indexOf('%') === -1)) ? element.style.height : 'inherit'; var tabColor = ''; switch (this.theme) { case 'HighContrastLight': case 'HighContrast': tabColor = '#969696'; break; case 'MaterialDark': case 'FabricDark': case 'Bootstrap': case 'Bootstrap4': tabColor = '#66afe9'; break; case 'Tailwind': case 'TailwindDark': tabColor = '#4f46e5'; break; case 'Bootstrap5': case 'Bootstrap5Dark': tabColor = '#0d6efd'; break; case 'Fluent': case 'FluentDark': tabColor = '#9e9e9e'; break; case 'Fluent2': case 'Fluent2Dark': case 'Fluent2HighContrast': tabColor = '#0078D4'; break; default: tabColor = '#9e9e9e'; break; } }; /** * Method to set the annotation content dynamically for accumulation. * * @param {number} annotationIndex - The index of the annotation. * @param {string} content - The content to set for the annotation. * @returns {void} */ AccumulationChart.prototype.setAnnotationValue = function (annotationIndex, content) { var annotation = this.annotations[annotationIndex]; var element; var parentNode = getElement(this.element.id + '_Annotation_Collections'); if (content) { annotation.content = content; if (parentNode) { element = this.createElement('div'); removeElement(this.element.id + '_Annotation_' + annotationIndex); this.annotationModule.processAnnotation(annotation, annotationIndex, element); parentNode.appendChild(element.children[0]); } else { this.annotationModule.renderAnnotations(getElement(this.element.id + '_Secondary_Element')); } } }; /** * Handles the mouse move on accumulation chart. * * @param {PointerEvent} e - The pointer event containing mouse coordinates. * @returns {boolean} - Mouse move of accumulation chart. * @private */ AccumulationChart.prototype.accumulationMouseMove = function (e) { if (!getElement(this.element.id + '_svg')) { return false; } this.setMouseXY(e); this.trigger(chartMouseMove, { target: e.target.id, x: this.mouseX, y: this.mouseY }); if (this.pointMove) { this.triggerPointEvent(pointMove, e.target, e); } if (this.accumulationLegendModule && this.legendSettings.visible) { this.accumulationLegendModule.move(e); } if (this.accumulationDataLabelModule && this.visibleSeries[0] && this.visibleSeries[0].dataLabel.visible) { this.accumulationDataLabelModule.move(e, this.mouseX, this.mouseY); } if (this.centerLabel.hoverTextFormat) { this.updateCenterLabel(e); } if (!this.isTouch) { this.titleTooltip(e, this.mouseX, this.mouseY); } if (this.enableBorderOnMouseMove && this.type === 'Pie' && this.pieSeriesModule && withInBounds(this.mouseX, this.mouseY, this.initialClipRect)) { this.pieSeriesModule.findSeries(e, this.series[0].borderRadius); } this.notify(Browser.touchMoveEvent, e); return false; }; AccumulationChart.prototype.titleTooltip = function (event, x, y, isTouch) { var targetId = event.target.id; var id = (targetId === (this.element.id + '_title') || targetId === (this.element.id + '_subTitle') || targetId === (this.element.id + '_chart_legend_title')); if ((event.target.textContent.indexOf('...') > -1) && id) { var title = (targetId === (this.element.id + '_title')) ? this.title : (targetId === (this.element.id + '_subTitle')) ? this.subTitle : this.legendSettings.title; showTooltip(title, x, y, this.element.offsetWidth, this.element.id + '_EJ2_Title_Tooltip', getElement(this.element.id + '_Secondary_Element'), isTouch); } else { removeElement(this.element.id + '_EJ2_Title_Tooltip'); } }; /** * Handles the keyboard onkeydown on chart. * * @param {KeyboardEvent} e - The keyboard event. * @returns {boolean} - false * @private */ AccumulationChart.prototype.accumulationChartKeyDown = function (e) { var actionKey = ''; if (this.tooltip.enable && ((e.code === 'Tab' && this.previousTargetId.indexOf('Series') > -1) || e.code === 'Escape')) { actionKey = 'ESC'; } if (e.code.indexOf('Arrow') > -1) { e.preventDefault(); } if (e.ctrlKey && (e.key === 'p')) { e.preventDefault(); actionKey = 'CtrlP'; } if (actionKey !== '') { this.chartKeyboardNavigations(e, e.target.id, actionKey); } if (e.code === 'Tab') { this.removeNavigationStyle(); } return false; }; /** * Handles the keyboard onkeydown on chart. * * @param {KeyboardEvent} e - The keyboard event. * @returns {boolean} - false * @private */ AccumulationChart.prototype.accumulationChartKeyUp = function (e) { var actionKey = ''; var targetId = e.target['id']; var legendElement = getElement(this.element.id + '_chart_legend_translate_g'); var pagingElement = getElement(this.element.id + '_chart_legend_pageup'); if (legendElement) { var firstChild = legendElement.firstElementChild; var className = firstChild.getAttribute('class'); if (className && className.indexOf('e-accumulationchart-focused') === -1) { className = className + ' e-accumulationchart-focused'; } else if (!className) { className = 'e-accumulationchart-focused'; } firstChild.setAttribute('class', className); } if (pagingElement) { pagingElement.setAttribute('class', 'e-accumulationchart-focused'); } this.removeNavigationStyle(); if (e.code === 'Tab') { if (this.previousTargetId !== '') { if (this.previousTargetId.indexOf('_Point_') > -1 && targetId.indexOf('_Point_') === -1) { var groupElement = document.getElementById(this.previousTargetId).parentElement; this.setTabIndex(groupElement.children[this.currentPointIndex], groupElement.firstElementChild); this.currentPointIndex = 0; } else if (this.previousTargetId.indexOf('_chart_legend_page') > -1 && targetId.indexOf('_chart_legend_page') === -1 && targetId.indexOf('_chart_legend_g_') === -1) { this.setTabIndex(e.target, pagingElement); } else if (this.previousTargetId.indexOf('_chart_legend_g_') > -1 && targetId.indexOf('chart_legend_g_') === -1 && legendElement) { this.setTabIndex(legendElement.children[this.currentLegendIndex], legendElement.firstElementChild); } } this.previousTargetId = targetId; if (targetId.indexOf('_chart_legend_g_') > -1 && this.highlightMode !== 'None') { targetId = e.target['lastElementChild'].id; actionKey = 'Tab'; } else if (targetId.indexOf('_Point_') > -1 && (this.highlightMode !== 'None' || this.tooltip.enable)) { actionKey = 'Tab'; } } else if (e.code.indexOf('Arrow') > -1) { e.preventDefault(); if (targetId.indexOf('_chart_legend_page') > -1) { e.target.removeAttribute('tabindex'); this.previousTargetId = targetId = this.element.id + '_chart_legend_page' + (e.code === 'ArrowRight' ? 'up' : 'down'); this.focusTarget(getElement(targetId)); } else if ((targetId.indexOf('_chart_legend_') > -1) && legendElement) { e.target.removeAttribute('tabindex'); this.currentLegendIndex += (e.code === 'ArrowUp' || e.code === 'ArrowRight') ? +1 : -1; this.currentLegendIndex = this.getActualIndex(this.currentLegendIndex, legendElement.children.length); var currentLegend = legendElement.children[this.currentLegendIndex]; this.focusTarget(currentLegend); this.removeNavigationStyle(); this.setNavigationStyle(currentLegend.id); this.previousTargetId = targetId = currentLegend.lastElementChild.id; actionKey = this.highlightMode !== 'None' ? 'ArrowMove' : ''; } else if (targetId.indexOf('_Point_') > -1) { e.target.setAttribute('tabindex', '-1'); this.currentPointIndex += (e.code === 'ArrowUp' || e.code === 'ArrowRight') ? +1 : -1; var totalLength = 0; for (var i = 0; i < e.target['parentElement'].children.length; i++) { totalLength = e.target['parentElement'].children[i].id.indexOf('_Point_') > -1 ? totalLength + 1 : totalLength; } this.currentPointIndex = this.getActualIndex(this.currentPointIndex, totalLength); targetId = this.element.id + '_Series_0_Point_' + this.currentPointIndex; this.focusTarget(getElement(targetId)); this.removeNavigationStyle(); this.setNavigationStyle(targetId); actionKey = this.tooltip.enable ? 'ArrowMove' : ''; } } else if ((e.code === 'Enter' || e.code === 'Space') && ((targetId.indexOf('_chart_legend_') > -1) || (targetId.indexOf('_Point_') > -1))) { targetId = (targetId.indexOf('_chart_legend_g') > -1) ? e.target['lastElementChild'].id : targetId; actionKey = 'Enter'; } if (actionKey !== '') { this.chartKeyboardNavigations(e, targetId, actionKey); } if (e.code === 'Tab') { this.setNavigationStyle(targetId); } return false; }; AccumulationChart.prototype.setTabIndex = function (previousElement, currentElement) { if (previousElement) { previousElement.removeAttribute('tabindex'); } if (currentElement) { currentElement.setAttribute('tabindex', '0'); } }; AccumulationChart.prototype.getActualIndex = function (index, totalLength) { return index > totalLength - 1 ? 0 : (index < 0 ? totalLength - 1 : index); }; AccumulationChart.prototype.focusTarget = function (element) { var className = element.getAttribute('class'); element.setAttribute('tabindex', '0'); if (className && className.indexOf('e-accumulationchart-focused') === -1) { className = className + ' e-accumulationchart-focused'; } else if (!className) { className = 'e-accumulationchart-focused'; } element.setAttribute('tabindex', '0'); element.setAttribute('class', className); element.focus(); return element.id; }; /** * Handles the document onkey. * * @param {KeyboardEvent} e - The keyboard event. * @returns {void} * @private */ AccumulationChart.prototype.documentKeyHandler = function (e) { // 74 - J if (e.altKey && e.keyCode === 74 && !isNullOrUndefined(this.element)) { this.element.focus(); } }; /** * Handles to set style for key event on the document. * * @param {target} target - element which currently focused. * @returns {void} * @private */ AccumulationChart.prototype.setNavigationStyle = function (target) { var currentElement = document.getElementById(target); if (currentElement) { currentElement.style.setProperty('outline', this.focusBorderWidth + "px solid " + (this.focusBorderColor || this.themeStyle.tabColor)); currentElement.style.setProperty('margin', this.focusBorderMargin + "px"); } }; /** * Handles to remove style for key event on the document. * * @returns {void} * @private */ AccumulationChart.prototype.removeNavigationStyle = function () { var currentElement = document.querySelectorAll("path[id*=_Series_0_Point_], [id*=" + this.element.id + "], [id*=_ChartBorder], text[id*=_title],g[id*=_chart_legend]"); if (currentElement) { currentElement.forEach(function (element) { if (element instanceof HTMLElement || element instanceof SVGElement) { element.style.setProperty('outline', 'none'); element.style.setProperty('margin', ''); } }); } }; AccumulationChart.prototype.chartKeyboardNavigations = function (e, targetId, actionKey) { this.isLegendClicked = false; switch (actionKey) { case 'Tab': case 'ArrowMove': if (this.accumulationHighlightModule) { // this.accumulationHighlightModule.removeHighlightElements(); } if (targetId.indexOf('_Point_') > -1) { var seriesIndex = +(targetId.split('_Series_')[1].split('_Point_')[0]); var pointIndex = +(targetId.split('_Series_')[1].replace('_Symbol', '').split('_Point_')[1]); var pointRegion = this.visibleSeries[seriesIndex].points[pointIndex].symbolLocation; this.mouseX = pointRegion.x + this.initialClipRect.x; this.mouseY = pointRegion.y + this.initialClipRect.y; if (this.accumulationHighlightModule) { var targetElement = getElement(targetId); if (!isNullOrUndefined(targetElement)) { if (targetElement.id.indexOf('text') > 1) { targetElement = getElement(targetElement.id.replace('text', 'shape')); } if ((targetElement).hasAttribute('class') && (targetElement).getAttribute('class').indexOf('highlight') > -1) { return; } this.accumulationHighlightModule.calculateSelectedElements(this, targetElement, 'mousemove'); return; } } if (this.accumulationTooltipModule) { var series = this.visibleSeries[seriesIndex]; var data = void 0; if (series.enableTooltip) { data = new AccPointData(series.points[pointIndex], series); } this.accumulationTooltipModule.renderSeriesTooltip(this, data); } } if (this.accumulationHighlightModule && this.highlightMode !== 'None') { targetId = targetId.indexOf('_chart_legend_g_') > -1 ? document.getElementById(targetId).firstChild['id'] : targetId; var legendID = this.element.id + '_chart_legend'; var legendItemsId = [legendID + '_text_', legendID + '_shape_marker_', legendID + '_shape_']; for (var i = 0; i < legendItemsId.length; i++) { var id = legendItemsId[i]; if (targetId.indexOf(id) > -1) { document.getElementById(targetId).setAttribute('class', ''); this.accumulationHighlightModule.legendSelection(this, 0, parseInt(targetId.split(id)[1], 10), getElement(targetId), 'mousemove'); break; } } } break; case 'Enter': case 'Space': if (targetId.indexOf('_chart_legend_') > -1 && this.accumulationLegendModule) { this.isLegendClicked = true; this.accumulationLegendModule.click(e); this.focusChild(document.getElementById(targetId).parentElement); this.setNavigationStyle(document.getElementById(targetId).parentElement.id); } else { if (this.accumulationSelectionModule) { this.accumulationSelectionModule.calculateSelectedElements(this, document.getElementById(targetId), 'click'); } this.setNavigationStyle(targetId); } break; case 'CtrlP': this.print(); break; case 'ESC': if (this.accumulationTooltipModule) { this.accumulationTooltipModule.removeTooltip(1); } break; } }; AccumulationChart.prototype.focusChild = function (element) { element.setAttribute('tabindex', '0'); var className = element.getAttribute('class'); element.setAttribute('tabindex', '0'); if (className && className.indexOf('e-accumulationchart-focused') === -1) { className = 'e-accumulationchart-focused ' + className; } else if (!className) { className = 'e-accumulationchart-focused'; } element.setAttribute('class', className); element.focus(); return element.id; }; /** * Handles the mouse double click on accumulation chart. * * @param {PointerEvent} e - The pointer event. * @returns {boolean} - Mouse double click of accumulation chart. * @private */ AccumulationChart.prototype.accumulationOnDoubleClick = function (e) { this.trigger(chartDoubleClick, { target: e.target.id, x: this.mouseX, y: this.mouseY }); return false; }; /** * Handles the mouse click on accumulation chart. * * @param {PointerEvent} e - The pointer event. * @returns {boolean} - Mouse click of accumulation chart. * @private */ AccumulationChart.prototype.accumulationOnMouseClick = function (e) { this.setMouseXY(e); if (this.accumulationLegendModule && this.legendSettings.visible) { this.accumulationLegendModule.click(e); } if (this.selectionMode !== 'None' && this.accumulationSelectionModule) { this.accumulationSelectionModule.calculateSelectedElements(this, e.target, e.type); } if (this.visibleSeries[0].explode) { this.accBaseModule.processExplode(e); } if (this.enableBorderOnMouseMove && this.pieSeriesModule && this.type === 'Pie') { this.pieSeriesModule.findSeries(e, this.series[0].borderRadius); } this.trigger(chartMouseClick, { target: e.target.id, x: this.mouseX, y: this.mouseY }); if (this.pointClick) { this.triggerPointEvent(pointClick, e.target, e); } this.removeNavigationStyle(); return false; }; AccumulationChart.prototype.triggerPointEvent = function (event, element, e) { var evt = e; var indexes = indexFinder(element.id, true); if (indexes.series >= 0 && indexes.point >= 0) { this.trigger(event, { series: this.isBlazor ? {} : this.series[indexes.series], point: this.series[indexes.series].points[indexes.point], seriesIndex: indexes.series, pointIndex: indexes.point, x: this.mouseX, y: this.mouseY, pageX: evt.pageX, pageY: evt.pageY }); } }; /** * Handles the mouse right click on accumulation chart. * * @param {MouseEvent | PointerEvent} event - The mouse event or pointer event. * @returns {boolean} - Right click of accumulation chart. * @private */ AccumulationChart.prototype.accumulationRightClick = function (event) { if (event.buttons === 2 && event.pointerType === 'touch') { event.preventDefault(); event.stopPropagation(); return false; } return true; }; /** * Handles the mouse leave on accumulation chart. * * @param {PointerEvent} e - The pointer event. * @returns {boolean} - Mouse leave of accumulation chart. * @private */ AccumulationChart.prototype.accumulationMouseLeave = function (e) { this.setMouseXY(e); this.trigger(chartMouseLeave, { target: e.target.id, x: this.mouseX, y: this.mouseY }); this.notify(Browser.isPointer ? 'pointerleave' : 'mouseleave', e); var borderElement = document.getElementById(this.element.id + 'PointHover_Border'); if (borderElement) { this.pieSeriesModule.removeBorder(borderElement, 1000); borderElement = null; } return false; }; /** * Method to set culture for chart. * * @returns {void} */ AccumulationChart.prototype.setCulture = function () { this.intl = new Internationalization(); }; /** * Method to create SVG element for accumulation chart. * * @returns {void} */ AccumulationChart.prototype.createPieSvg = function () { this.removeSvg(); createSvg(this); }; /** * To Remove the SVG from accumulation chart. * * @returns {boolean} - Remove svg. * @private */ AccumulationChart.prototype.removeSvg = function () { if (this.redraw) { return null; } blazorTemplatesReset(this); removeElement(this.element.id + '_Secondary_Element'); if (this.svgObject) { while (this.svgObject.childNodes.length > 0) { this.svgObject.removeChild(this.svgObject.firstChild); } if (!this.svgObject.hasChildNodes() && this.svgObject.parentNode) { remove(this.svgObject); } } removeElement('EJ2_legend_tooltip'); removeElement('EJ2_datalabel_tooltip'); removeElement(this.element.id + 'PointHover_Border'); }; /** * Method to create the secondary element for tooltip, datalabel and annotaitons. * * @returns {void} */ AccumulationChart.prototype.createSecondaryElement = function () { var element = redrawElement(this.redraw, this.element.id + '_Secondary_Element') || this.createElement('div', { id: this.element.id + '_Secondary_Element', styles: 'position: relative' }); appendChildElement(false, this.element, element, this.redraw); }; /** * Method to find visible series based on series types. * * @returns {void} */ AccumulationChart.prototype.calculateVisibleSeries = function () { this.visibleSeries = []; for (var i = 0, length_1 = this.series.length; i < length_1; i++) { this.series[i].index = i; if (this.series[i].type === this.type && this.visibleSeries.length === 0) { this.visibleSeries.push(this.series[i]); break; } } }; /** * To find points from dataSource. * * @param {boolean} render - Indicates whether to render the points (default: true). * @returns {void} */ AccumulationChart.prototype.processData = function (render) { if (render === void 0) { render = true; } this.seriesCounts = 0; for (var _i = 0, _a = this.visibleSeries; _i < _a.length; _i++) { var series = _a[_i]; series.dataModule = new Data(series.dataSource || this.dataSource, series.query); series.refreshDataManager(this, render); } }; /** * To refresh the accumulation chart. * * @private * @returns {void} */ AccumulationChart.prototype.refreshChart = function () { this.doGrouppingProcess(); this.createPieSvg(); this.calculateBounds(); this.renderElements(); removeElement('chartmeasuretext'); }; /** * Method to find groupped points. * * @returns {void} */ AccumulationChart.prototype.doGrouppingProcess = function () { var series = this.visibleSeries[0]; if (!isNullOrUndefined(series.resultData) && ((!isNullOrUndefined(series.lastGroupTo) && series.lastGroupTo !== series.groupTo))) { series.getPoints(series.resultData, this); } }; /** * Method to calculate bounds for accumulation chart. * * @returns {void} */ AccumulationChart.prototype.calculateBounds = function () { this.initialClipRect = new Rect(this.margin.left, this.margin.top, this.availableSize.width, this.availableSize.height); this.titleCollection = []; this.subTitleCollection = []; var titleHeight = 0; var subTitleHeight = 0; var maxWidth = 0; var titleWidth = 0; if (this.title) { this.titleCollection = getTitle(this.title, this.titleStyle, this.initialClipRect.width, this.enableRtl, this.themeStyle.chartTitleFont); } titleHeight = this.title ? measureText(this.title, this.titleStyle, this.themeStyle.chartTitleFont).height * this.titleCollection.length : titleHeight; if (this.subTitle) { for (var _i = 0, _a = this.titleCollection; _i < _a.length; _i++) { var titleText = _a[_i]; titleWidth = measureText(titleText, this.titleStyle, this.themeStyle.chartSubTitleFont).width; maxWidth = titleWidth > maxWidth ? titleWidth : maxWidth; } this.subTitleCollection = getTitle(this.subTitle, this.subTitleStyle, this.initialClipRect.width, this.enableRtl, this.themeStyle.chartSubTitleFont); subTitleHeight = (measureText(this.subTitle, this.subTitleStyle, this.themeStyle.chartSubTitleFont).height * this.subTitleCollection.length); } var left = this.margin.left + this.border.width; var width = this.availableSize.width - left - this.margin.right - this.border.width; var top = this.margin.top + this.border.width; var height = this.availableSize.height - top - this.border.width - this.margin.bottom; var marginTotal = subTitleHeight + titleHeight; switch (this.titleStyle.position) { case 'Top': left = 0; top = subTitleHeight + titleHeight; width = this.margin.right + this.margin.left; height = this.margin.bottom + this.margin.top; break; case 'Bottom': height -= (marginTotal + this.margin.bottom * 2); break; case 'Left': left += marginTotal; width -= marginTotal; break; case 'Right': width -= marginTotal; break; } if (this.titleStyle.position !== 'Top') { this.initialClipRect = new Rect(left, top, width, height); } else { this.initialClipRect = subtractRect(this.initialClipRect, new Rect(left, top, width, height)); } this.calculateLegendBounds(); }; /** * Method to calculate legend bounds for accumulation chart. * * @returns {void} */ AccumulationChart.prototype.calculateLegendBounds = function () { if (!this.accumulationLegendModule || !this.legendSettings.visible) { return null; } this.accumulationLegendModule.getLegendOptions(this, this.visibleSeries); this.accumulationLegendModule.calculateLegendBounds(this.initialClipRect, this.availableSize, null); }; /** * To render elements for accumulation chart. * * @private * @returns {void} */ AccumulationChart.prototype.renderElements = function () { this.renderBorder(); this.createSecondaryElement(); this.renderSeries(); this.renderTitle(); this.renderCenterLabel(true); this.renderLegend(); appendChildElement(false, this.element, this.svgObject, this.redraw); this.processSelection(); this.processExplode(); this.renderAnnotation(); this.setSecondaryElementPosition(); var isAllSeriesEmpty = this.series.every(function (s) { var dataSource = s.dataSource || []; return dataSource.length === 0; }); if (isAllSeriesEmpty && !isNullOrUndefined(this.noDataTemplate)) { this.renderNoDataTemplate(true); } updateBlazorTemplate(this.element.id + '_DataLabel', 'Template', this.series[0].dataLabel); this.trigger('loaded', { accumulation: this.isBlazor ? {} : this, chart: this.isBlazor ? {} : this }); this.animateSeries = false; }; /** * To set the left and top