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,007 lines (1,006 loc) 47 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 base file */ import { Property, ChildProperty, Complex, createElement, Browser, animationMode, extend } from '@syncfusion/ej2-base'; import { isNullOrUndefined, getValue } from '@syncfusion/ej2-base'; import { DataManager } from '@syncfusion/ej2-data'; import { Border, Font, Animation, EmptyPointSettings, Connector, Accessibility } from '../../common/model/base'; import { Rect, PathOption, measureText } from '@syncfusion/ej2-svg-base'; import { stringToNumber, appendChildElement, subtractRect } from '../../common/utils/helper'; import { seriesRender, pointRender } from '../../common/model/constants'; import { getSeriesColor } from '../../common/model/theme'; import { getElement, firstToLowerCase } from '../../common/utils/helper'; import { BaseSelection } from '../../common/user-interaction/selection'; import { LegendOptions } from '../../common/legend/legend'; /** * Configures the annotation settings for an accumulation chart. * Annotations are used to highlight or provide additional information about specific points or regions in the accumulation chart. */ var AccumulationAnnotationSettings = /** @class */ (function (_super) { __extends(AccumulationAnnotationSettings, _super); function AccumulationAnnotationSettings() { return _super !== null && _super.apply(this, arguments) || this; } __decorate([ Property(null) ], AccumulationAnnotationSettings.prototype, "content", void 0); __decorate([ Property('0') ], AccumulationAnnotationSettings.prototype, "x", void 0); __decorate([ Property('0') ], AccumulationAnnotationSettings.prototype, "y", void 0); __decorate([ Property('Pixel') ], AccumulationAnnotationSettings.prototype, "coordinateUnits", void 0); __decorate([ Property('Chart') ], AccumulationAnnotationSettings.prototype, "region", void 0); __decorate([ Property('Middle') ], AccumulationAnnotationSettings.prototype, "verticalAlignment", void 0); __decorate([ Property('Center') ], AccumulationAnnotationSettings.prototype, "horizontalAlignment", void 0); __decorate([ Property(null) ], AccumulationAnnotationSettings.prototype, "description", void 0); return AccumulationAnnotationSettings; }(ChildProperty)); export { AccumulationAnnotationSettings }; /** * This class provides options to customize the appearance and behavior of data labels within a series. */ var AccumulationDataLabelSettings = /** @class */ (function (_super) { __extends(AccumulationDataLabelSettings, _super); function AccumulationDataLabelSettings() { return _super !== null && _super.apply(this, arguments) || this; } __decorate([ Property(false) ], AccumulationDataLabelSettings.prototype, "visible", void 0); __decorate([ Property(true) ], AccumulationDataLabelSettings.prototype, "showZero", void 0); __decorate([ Property(null) ], AccumulationDataLabelSettings.prototype, "name", void 0); __decorate([ Property('transparent') ], AccumulationDataLabelSettings.prototype, "fill", void 0); __decorate([ Property('Inside') ], AccumulationDataLabelSettings.prototype, "position", void 0); __decorate([ Property(5) ], AccumulationDataLabelSettings.prototype, "rx", void 0); __decorate([ Property(5) ], AccumulationDataLabelSettings.prototype, "ry", void 0); __decorate([ Property(0) ], AccumulationDataLabelSettings.prototype, "angle", void 0); __decorate([ Property(false) ], AccumulationDataLabelSettings.prototype, "enableRotation", void 0); __decorate([ Complex({ width: null, color: null }, Border) ], AccumulationDataLabelSettings.prototype, "border", void 0); __decorate([ Complex({ fontFamily: null, size: null, fontStyle: null, fontWeight: null, color: null }, Font) ], AccumulationDataLabelSettings.prototype, "font", void 0); __decorate([ Complex({}, Connector) ], AccumulationDataLabelSettings.prototype, "connectorStyle", void 0); __decorate([ Property(null) ], AccumulationDataLabelSettings.prototype, "template", void 0); __decorate([ Property('') ], AccumulationDataLabelSettings.prototype, "format", void 0); __decorate([ Property(null) ], AccumulationDataLabelSettings.prototype, "maxWidth", void 0); __decorate([ Property('Ellipsis') ], AccumulationDataLabelSettings.prototype, "textOverflow", void 0); __decorate([ Property('Normal') ], AccumulationDataLabelSettings.prototype, "textWrap", void 0); return AccumulationDataLabelSettings; }(ChildProperty)); export { AccumulationDataLabelSettings }; /** * The `PieCenter` class provides options to set the center position for the Pie series in a chart. */ var PieCenter = /** @class */ (function (_super) { __extends(PieCenter, _super); function PieCenter() { return _super !== null && _super.apply(this, arguments) || this; } __decorate([ Property('50%') ], PieCenter.prototype, "x", void 0); __decorate([ Property('50%') ], PieCenter.prototype, "y", void 0); return PieCenter; }(ChildProperty)); export { PieCenter }; /** * The `AccPoints` class is used to define and manage the data points within a series of accumulation charts. * * @public */ var AccPoints = /** @class */ (function () { function AccPoints() { /** Accumulation point visibility. */ this.visible = true; /** Accumulation point symbol location. */ this.symbolLocation = null; /** @private */ this.region = null; /** @private */ this.labelRegion = null; /** @private */ this.labelVisible = true; this.regions = null; /** @private */ this.isExplode = false; /** @private */ this.isClubbed = false; /** @private */ this.isSliced = false; /** @private */ this.argsData = null; /** @private */ this.isLabelUpdated = null; /** @private */ this.initialLabelRegion = null; } return AccPoints; }()); export { AccPoints }; /** * Configures the series in the accumulation chart. */ var AccumulationSeries = /** @class */ (function (_super) { __extends(AccumulationSeries, _super); function AccumulationSeries() { /** * Specifies the data source for the series. It can be an array of JSON objects, or an instance of DataManager. * ```html * <div id='Pie'></div> * ``` * ```typescript * let dataManager: DataManager = new DataManager({ * url: 'https://services.syncfusion.com/js/production/api/orders' * }); * let query: Query = new Query().take(5); * let pie: AccumulationChart = new AccumulationChart({ * ... * series: [{ * dataSource: dataManager, * xName: 'CustomerID', * yName: 'Freight', * query: query * }], * ... * }); * pie.appendTo('#Pie'); * ``` * * @default '' */ var _this = _super !== null && _super.apply(this, arguments) || this; /** @private */ _this.points = []; /** @private */ _this.clubbedPoints = []; /** @private */ _this.sumOfPoints = 0; /** @private */ _this.isRectSeries = true; /** @private */ _this.clipRect = new Rect(0, 0, 0, 0); /** @private */ _this.category = 'Series'; /** @private */ _this.rightSidePoints = []; /** @private */ _this.leftSidePoints = []; return _this; } /** * To refresh the Datamanager for series. * * @private * @param {AccumulationChart} accumulation - The accumulation chart control. * @param {boolean} render - Specifies whether to render the accumulation chart after refreshing the DataManager. * @returns {void} */ AccumulationSeries.prototype.refreshDataManager = function (accumulation, render) { var _this = this; this.accumulation = accumulation; this.radius = this.radius ? this.radius : (Browser.isDevice && this.dataLabel.position === 'Outside') ? '40%' : '80%'; var dateSource = this.dataSource || accumulation.dataSource; if (!(dateSource instanceof DataManager) && isNullOrUndefined(this.query)) { this.dataManagerSuccess({ result: dateSource, count: dateSource.length }, accumulation, render); return; } var dataManager = this.dataModule.getData(this.dataModule.generateQuery().requiresCount()); dataManager.then(function (e) { return _this.dataManagerSuccess(e, accumulation); }); }; /** * To get points on dataManager is success. * * @private * @param {Object} e - The data manager result object. * @param {Object} e.result - The result of the data manager process. * @param {number} e.count - The count of items in the result. * @param {AccumulationChart} accumulation - The accumulation chart control. * @param {boolean} render - Specifies whether to render the accumulation chart after retrieving the points. * @returns {void} */ AccumulationSeries.prototype.dataManagerSuccess = function (e, accumulation, render) { if (render === void 0) { render = true; } var argsData = { name: seriesRender, series: this, data: e.result }; accumulation.allowServerDataBinding = false; accumulation.trigger(seriesRender, argsData); this.resultData = e.result !== '' ? e.result : []; if (!render) { this.getPoints(this.resultData, accumulation); // To update datasource using onPropertyChanged method. incident id: 290690 } if ((++accumulation.seriesCounts === accumulation.visibleSeries.length && render)) { this.getPoints(this.resultData, accumulation); accumulation.refreshChart(); } }; /** * To find points from result data. * * @private * @param {Object} result - The result of the process. * @param {AccumulationChart} accumulation - The accumulation chart control. * @returns {void} */ AccumulationSeries.prototype.getPoints = function (result, accumulation) { var length = Object.keys(result).length; this.sumOfPoints = 0; if (length === 0) { // fix for Pie datalabels are not removed for empty datasource this.points = []; return null; } if (this.groupTo) { this.findSumOfPoints(result); } this.points = []; this.clubbedPoints = []; this.sumOfClub = 0; var point; var colors = this.palettes.length ? this.palettes : getSeriesColor(accumulation.theme); var clubValue = stringToNumber(this.groupTo, this.sumOfPoints); for (var i = 0; i < length; i++) { point = this.setPoints(result, i, colors, accumulation); if (!this.isClub(point, clubValue, i)) { if (isNullOrUndefined(point.y)) { point.visible = false; } this.pushPoints(point, colors); } else { point.index = this.clubbedPoints.length; point.isExplode = true; this.clubbedPoints.push(point); point.isSliced = true; } } if (!this.groupTo) { this.findSumOfPoints(result); } this.lastGroupTo = this.groupTo; if (this.sumOfClub > 0) { var clubPoint_1 = this.generateClubPoint(); this.pushPoints(clubPoint_1, colors); var pointsLength_1 = this.points.length - 1; this.clubbedPoints.map(function (point) { point.index += pointsLength_1; point.color = clubPoint_1.color; }); } if (this.clubbedPoints.length && this.explode && this.type === 'Pie' && (this.explodeAll || this.points[this.points.length - 1].index === this.explodeIndex)) { this.points.splice(this.points.length - 1, 1); this.points = this.points.concat(this.clubbedPoints); } }; AccumulationSeries.prototype.generateClubPoint = function () { var clubPoint = new AccPoints(); clubPoint.isClubbed = true; clubPoint.x = 'Others'; clubPoint.y = this.sumOfClub; clubPoint.text = clubPoint.originalText = clubPoint.x + ': ' + this.sumOfClub; clubPoint.sliceRadius = '80%'; return clubPoint; }; /** * Method to set point index and color. * * @param {AccPoints} point - The point data. * @param {string[]} colors - The array of colors used in the accumulation chart. * @returns {void} */ AccumulationSeries.prototype.pushPoints = function (point, colors) { point.index = this.points.length; point.isExplode = this.explodeAll || (point.index === this.explodeIndex); point.color = point.color || colors[point.index % colors.length]; this.points.push(point); }; /** * Method to find club point. * * @param {AccPoints} point - The point data. * @param {number} clubValue - The club value for accumulation chart. * @param {number} index - The index of the point in the data set. * @returns {boolean} - false */ AccumulationSeries.prototype.isClub = function (point, clubValue, index) { if (!isNullOrUndefined(clubValue)) { if (this.groupMode === 'Value' && Math.abs(point.y) <= clubValue) { this.sumOfClub += Math.abs(point.y); return true; } else if (this.groupMode === 'Point' && index >= clubValue) { this.sumOfClub += Math.abs(point.y); return true; } } return false; }; /** * Method to find sum of points in the series. * * @param {Object} result - The result of the process. * @returns {void} */ AccumulationSeries.prototype.findSumOfPoints = function (result) { var length = Object.keys(result).length; for (var i = 0; i < length; i++) { if (!isNullOrUndefined(result[i]) && !isNullOrUndefined(result[i][this.yName]) && !isNaN(result[i][this.yName]) && (this.points.length && this.points[i] && this.points[i].visible && !isNullOrUndefined(this.points[i].y) || this.groupTo)) { this.sumOfPoints += Math.abs(result[i][this.yName]); } } }; /** * Method to set points x, y and text from data source. * * @param {Object} data - The data containing information for the points. * @param {number} i - The index of the current point in the data set. * @param {string[]} colors - The array of colors used in the accumulation chart. * @param {AccumulationChart} accumulation - The accumulation chart control. * @returns {AccPoints} - The point data retrieved from the specified index. */ AccumulationSeries.prototype.setPoints = function (data, i, colors, accumulation) { var point = new AccPoints(); point.x = getValue(this.xName, data[i]); point.y = getValue(this.yName, data[i]); point.legendImageUrl = getValue(this.legendImageUrl, data[i]); point.color = getValue(this.pointColorMapping, data[i]); point.text = point.originalText = getValue(this.dataLabel.name || '', data[i]); point.tooltip = getValue(this.tooltipMappingName || '', data[i]); point.sliceRadius = getValue(this.radius, data[i]); point.sliceRadius = isNullOrUndefined(point.sliceRadius) ? '80%' : point.sliceRadius; point.separatorY = accumulation.intl.formatNumber(point.y, { useGrouping: accumulation.useGroupingSeparator }); this.setVisibility(point, i); this.setAccEmptyPoint(point, i, data); return point; }; /** * Method render the series elements for accumulation chart. * * @private * @param {AccumulationChart} accumulation - The AccumulationChart control. * @param {boolean} redraw - Specifies whether to redraw the points. * @returns {void} */ AccumulationSeries.prototype.renderSeries = function (accumulation, redraw) { var seriesGroup = redraw ? getElement(accumulation.element.id + '_Series_' + this.index) : accumulation.renderer.createGroup({ id: accumulation.element.id + '_Series_' + this.index }); this.renderPoints(accumulation, seriesGroup, redraw); var datalabelGroup; if (accumulation.accumulationDataLabelModule && this.dataLabel.visible) { datalabelGroup = accumulation.renderer.createGroup({ id: accumulation.element.id + '_datalabel_Series_' + this.index }); datalabelGroup.style.visibility = (((this.animation.enable && animationMode !== 'Disable') || animationMode === 'Enable') && accumulation.animateSeries && this.type === 'Pie') ? 'hidden' : 'visible'; this.renderDataLabel(accumulation, datalabelGroup, redraw); } if (this.type === 'Pie') { if (!accumulation.redraw) { this.findMaxBounds(this.labelBound, this.accumulationBound); } accumulation.pieSeriesModule.animateSeries(accumulation, this.animation, this, seriesGroup, this.borderRadius, this.points); } if (!accumulation.redraw && accumulation.accumulationLegendModule) { this.labelBound.x -= accumulation.explodeDistance; this.labelBound.y -= accumulation.explodeDistance; this.labelBound.height += (accumulation.explodeDistance - this.labelBound.y); this.labelBound.width += (accumulation.explodeDistance - this.labelBound.x); } }; /** * Method render the points elements for accumulation chart series. * * @param {AccumulationChart} accumulation - The AccumulationChart control. * @param {Element} seriesGroup - The group element to contain the point elements. * @param {boolean} redraw - Specifies whether to redraw the points. * @param {boolean} previouRadius - Specifies the previous radius of the pie when animating the individual series point. * @param {boolean} previousCenter - Specifies the previous center of the pie when animating the individual series point. * @param {boolean} pointAnimation - Specifies whether the point based animation is enabled. * @returns {void} */ AccumulationSeries.prototype.renderPoints = function (accumulation, seriesGroup, redraw, previouRadius, previousCenter, pointAnimation) { var pointId = accumulation.element.id + '_Series_' + this.index + '_Point_'; var option; var patternFill; var options = []; var visiblePoints = []; var patterns = ['Chessboard', 'Dots', 'DiagonalForward', 'Crosshatch', 'Pacman', 'DiagonalBackward', 'Grid', 'Turquoise', 'Star', 'Triangle', 'Circle', 'Tile', 'HorizontalDash', 'VerticalDash', 'Rectangle', 'Box', 'VerticalStripe', 'HorizontalStripe', 'Bubble']; for (var _i = 0, _a = this.points; _i < _a.length; _i++) { var point = _a[_i]; point.percentage = (+(point.y / this.sumOfPoints * 100).toFixed(2)); var argsData = { cancel: false, name: pointRender, series: this, point: point, fill: point.color, border: this.isEmpty(point) ? { width: this.emptyPointSettings.border.width, color: this.emptyPointSettings.border.color } : { width: this.border.width, color: this.border.color }, pattern: this.applyPattern ? patterns[point.index % patterns.length] : 'None' }; accumulation.trigger(pointRender, argsData); point.color = argsData.fill; patternFill = point.color; if (this.applyPattern) { var selection = new BaseSelection(accumulation); patternFill = selection.pattern(accumulation, point.color, point.index, argsData.pattern, this.opacity); } option = new PathOption(pointId + point.index, patternFill, argsData.border.width || 1, argsData.border.color || point.color, this.opacity, argsData.series.dashArray, ''); if (this.funnelMode === 'Trapezoidal' && this.type === 'Funnel') { options.push(option); if (point.visible) { visiblePoints.push(point); } } else { accumulation[(firstToLowerCase(this.type) + 'SeriesModule')]. renderPoint(point, this, accumulation, option, seriesGroup, redraw, previouRadius, previousCenter, pointAnimation); } } if (this.funnelMode === 'Trapezoidal' && this.type === 'Funnel') { accumulation[(firstToLowerCase(this.type) + 'SeriesModule')]. renderTrapezoidalFunnel(this, visiblePoints, accumulation, options, seriesGroup, redraw); } else { appendChildElement(false, accumulation.getSeriesElement(), seriesGroup, redraw); } }; /** * Method render the datalabel elements for accumulation chart. * * @param {AccumulationChart} accumulation - The AccumulationChart control. * @param {Element} datalabelGroup - The group element to contain the data label elements. * @param {boolean} redraw - Specifies whether to redraw the data labels. * @returns {void} */ AccumulationSeries.prototype.renderDataLabel = function (accumulation, datalabelGroup, redraw) { accumulation.accumulationDataLabelModule.findAreaRect(); var element = createElement('div', { id: accumulation.element.id + '_Series_0' + '_DataLabelCollections' }); this.leftSidePoints = []; this.rightSidePoints = []; var firstQuarter = []; var secondQuarter = []; for (var _i = 0, _a = this.points; _i < _a.length; _i++) { var point = _a[_i]; if (point.visible) { if (this.dataLabel.showZero || (!this.dataLabel.showZero && ((point.y !== 0) || (point.y === 0 && this.emptyPointSettings.mode === 'Zero')))) { accumulation.accumulationDataLabelModule.renderDataLabel(point, this.dataLabel, datalabelGroup, this.points, this.index, element, redraw); } } if (point.midAngle >= 90 && point.midAngle <= 270) { this.leftSidePoints.push(point); } else { if (point.midAngle >= 0 && point.midAngle <= 90) { secondQuarter.push(point); } else { firstQuarter.push(point); } } } firstQuarter.sort(function (a, b) { return a.midAngle - b.midAngle; }); secondQuarter.sort(function (a, b) { return a.midAngle - b.midAngle; }); this.leftSidePoints.sort(function (a, b) { return a.midAngle - b.midAngle; }); this.rightSidePoints = firstQuarter.concat(secondQuarter); accumulation.accumulationDataLabelModule.drawDataLabels(this, this.dataLabel, datalabelGroup, element, redraw); if (this.dataLabel.template !== null && element.childElementCount) { var dataLabelCallBack = accumulation.accumulationDataLabelModule.drawDataLabels.bind(accumulation.accumulationDataLabelModule, this, this.dataLabel, datalabelGroup, element, redraw); if (accumulation.isReact) { accumulation.renderReactTemplates(dataLabelCallBack); } appendChildElement(false, getElement(accumulation.element.id + '_Secondary_Element'), element, redraw); } appendChildElement(false, accumulation.getSeriesElement(), datalabelGroup, redraw); }; /** * To find maximum bounds for smart legend placing. * * @private * @param {Rect} totalbound - The total bounding rect. * @param {Rect} bound - The bounding rect to be compared. * @returns {void} */ AccumulationSeries.prototype.findMaxBounds = function (totalbound, bound) { totalbound.x = bound.x < totalbound.x ? bound.x : totalbound.x; totalbound.y = bound.y < totalbound.y ? bound.y : totalbound.y; totalbound.height = (bound.y + bound.height) > totalbound.height ? (bound.y + bound.height) : totalbound.height; totalbound.width = (bound.x + bound.width) > totalbound.width ? (bound.x + bound.width) : totalbound.width; }; /** * Finds the maximum width of the labels for legend placement. * * @private * @returns {number} The maximum label width. */ AccumulationSeries.prototype.findMaxLabelWidth = function () { var max; for (var i = 0; i < this.points.length; i++) { max = this.points[0].textSize.width; if (max < this.points[i].textSize.width) { max = this.points[i].textSize.width; } } return max; }; /** * To set empty point value for null points. * * @private * @param {AccPoints} point - The point to set as empty. * @param {number} i - The index of the point in the data set. * @param {Object} data - The data object. * @returns {void} */ AccumulationSeries.prototype.setAccEmptyPoint = function (point, i, data) { if (!(isNullOrUndefined(point.y) || isNaN(point.y))) { return null; } point.color = this.emptyPointSettings.fill || point.color; switch (this.emptyPointSettings.mode) { case 'Zero': point.y = 0; point.visible = true; break; case 'Average': { var previous = data[i - 1] ? (data[i - 1][this.yName] || 0) : 0; var next = data[i + 1] ? (data[i + 1][this.yName] || 0) : 0; point.y = (Math.abs(previous) + Math.abs(next)) / 2; this.sumOfPoints += point.y; point.visible = true; break; } default: point.visible = false; break; } }; /** * To set visiblity for the point. * * @private * @param {AccPoints} point - The point to set visibility. * @param {number} i - The index of the point in the data set. * * @returns {void} */ AccumulationSeries.prototype.setVisibility = function (point, i) { if (this.accumulation.accumulationLegendModule && this.accumulation.accumulationLegendModule.legendCollections && this.accumulation.accumulationLegendModule.legendCollections[i] && !this.accumulation.accumulationLegendModule.legendCollections[i].visible) { point.visible = false; } }; /** * Updates the data source for the series. * * @function setData * @param {Object} data – Updated data source for the series. * @param {number} duration – The duration for the animation. * @returns {void} */ AccumulationSeries.prototype.setData = function (data, duration) { if (!data) { return null; } var samePoints = false; if (this.dataSource.length === data.length) { samePoints = true; for (var i = 0; i < data.length; i++) { if (this.dataSource[i][this.xName] === data[i][this.xName]) { var point = this.points[i]; var existingPoint = this.dataSource[i]; if ((existingPoint[this.yName] !== data[i][this.yName])) { point.y = data[i][this.yName]; this.dataSource[i] = data[i]; } } else { samePoints = false; break; } } } if (!samePoints) { this.dataSource = data; } else { this.sumOfPoints = 0; var visiblePoints = []; for (var i = 0; i < this.resultData.length; i++) { if (this.points[i] && this.points[i].visible) { visiblePoints.push(this.resultData[i]); } } this.findSumOfPoints(visiblePoints); this.accumulation.redraw = this.borderRadius ? false : this.accumulation.enableAnimation; this.accumulation.animateSeries = false; var chartDuration = this.accumulation.duration; this.accumulation.duration = isNullOrUndefined(duration) ? 500 : duration; this.accumulation[(firstToLowerCase(this.type) + 'SeriesModule')].initProperties(this.accumulation, this); this.renderPoints(this.accumulation, getElement(this.accumulation.element.id + '_Series_' + this.index), this.accumulation.redraw, null, null, true); if (this.accumulation.centerLabel.text) { this.accumulation.renderCenterLabel(true, true); } if (this.accumulation.annotationModule) { this.accumulation.annotationModule.renderAnnotations(getElement(this.accumulation.element.id + '_Secondary_Element')); } if (this.accumulation.accumulationDataLabelModule && this.dataLabel.visible) { this.renderDataLabel(this.accumulation, getElement(this.accumulation.element.id + '_datalabel_Series_' + this.index), this.accumulation.redraw); } this.accumulation.redraw = false; this.accumulation.duration = chartDuration; } }; /** * Adds a data point to the data source for the series. * * @function addPoint * @param {Object} dataPoint - The data point to be added. * @param {number} duration – The duration for the animation. * @returns {void} */ AccumulationSeries.prototype.addPoint = function (dataPoint, duration) { var maxWidth; if (this.accumulation.series[0].dataLabel.visible) { maxWidth = this.findMaxLabelWidth(); } this.dataSource.push(dataPoint); this.resultData = this.dataSource; this.sumOfPoints = 0; var visiblepoints = []; for (var i = 0; i < this.resultData.length; i++) { if (this.points[i] && this.points[i].visible) { visiblepoints.push(this.resultData[i]); } else if (i === this.resultData.length - 1) { visiblepoints.push(this.resultData[i]); } } var pointIndex = this.points.length === 0 ? 0 : this.points[this.points.length - 1].index + 1; var colors = this.palettes.length ? this.palettes : getSeriesColor(this.accumulation.theme); var point = this.setPoints(this.dataSource, pointIndex, colors, this.accumulation); this.pushPoints(point, colors); this.findSumOfPoints(visiblepoints); this.accumulation.redraw = this.borderRadius ? false : this.accumulation.enableAnimation; var chartDuration = this.accumulation.duration; this.accumulation.duration = isNullOrUndefined(duration) ? 500 : duration; this.updateSeries(getElement(this.accumulation.element.id + '_Series_' + this.index), maxWidth, 'addPoint'); this.accumulation.redraw = false; this.accumulation.duration = chartDuration; }; /** * Removes a data point from the series data source at the specified index. * * @function removePoint * @param {number} index – The index of the data point to be removed from the series. * @param {number} duration – The duration for the animation. * @returns {void} */ AccumulationSeries.prototype.removePoint = function (index, duration) { var dataSource = extend([], this.dataSource, null, true); var chartDuration = this.accumulation.duration; if (dataSource.length > 0 && index >= 0 && index < dataSource.length) { this.sumOfPoints = 0; var removepoints = []; for (var i = 0; i < this.dataSource.length; i++) { if (i !== index && this.points[i] && this.points[i].visible) { removepoints.push(this.dataSource[i]); } } dataSource.splice(index, 1); this.dataSource.splice(index, 1); this.accumulation.redraw = this.borderRadius ? false : this.accumulation.enableAnimation; this.accumulation.duration = isNullOrUndefined(duration) ? 500 : duration; this.points.splice(index, 1); for (var i = index; i < this.points.length; i++) { var point = this.points[i]; point.index = i; point.y = this.points[i].y; } this.findSumOfPoints(removepoints); var element = getElement(this.accumulation.element.id + '_Series_0_Point_' + (this.points.length)); if (element) { element.parentNode.removeChild(element); } this.updateSeries(getElement(this.accumulation.element.id + '_Series_' + this.index), undefined, 'removePoint', index); this.accumulation.redraw = false; this.accumulation.duration = chartDuration; } }; /** * Update the series based on addPoint and removePoint function. * * @param {Element} seriesGroup - Series group needs to be update. * @param {number} maxLabelWidth - Specifies the maximum label width. * @param {string} updatePoint - Specifies remove or add point. * @param {number} index - specifies point index to remove. * @returns {void} */ AccumulationSeries.prototype.updateSeries = function (seriesGroup, maxLabelWidth, updatePoint, index) { var previousRadius = this.accumulation[(firstToLowerCase(this.type) + 'SeriesModule')].radius; var previousCenter = this.accumulation[(firstToLowerCase(this.type) + 'SeriesModule')].center; var previousLegendBounds; if (this.accumulation.legendSettings.visible) { if (updatePoint === 'addPoint') { this.accumulation.accumulationLegendModule. legendCollections.push(new LegendOptions(this.points[this.points.length - 1].x.toString(), this.points[this.points.length - 1].color, this.legendShape, this.points[this.points.length - 1].visible, this.type, this.points[this.points.length - 1].legendImageUrl, null, null, this.points[this.points.length - 1].index, this.index)); } else { this.accumulation.accumulationLegendModule.legendCollections.splice(index, 1); for (var i = index; i < this.accumulation.accumulationLegendModule.legendCollections.length; i++) { this.accumulation.accumulationLegendModule.legendCollections[i].pointIndex = i; } } if (this.accumulation.accumulationLegendModule.legendCollections.length >= 1) { previousLegendBounds = this.accumulation.accumulationLegendModule.legendBounds; this.accumulation.accumulationLegendModule.calculateLegendBounds(this.accumulation.initialClipRect, this.accumulation.availableSize, null, previousLegendBounds, true); if (this.dataLabel && this.dataLabel.position === 'Outside' && (this.accumulation.legendSettings.position === 'Bottom' || (this.accumulation.legendSettings.position === 'Top')) ? (previousLegendBounds.height !== this.accumulation.accumulationLegendModule.legendBounds.height) : (previousLegendBounds.width !== this.accumulation.accumulationLegendModule.legendBounds.width)) { var titleHeight = (this.accumulation.title ? measureText(this.accumulation.title, this.accumulation.titleStyle, this.accumulation.themeStyle.chartTitleFont).height * this.accumulation.titleCollection.length : 0); var subTitleHeight = (this.accumulation.subTitle ? (measureText(this.accumulation.subTitle, this.accumulation.subTitleStyle, this.accumulation.themeStyle.chartSubTitleFont).height * this.accumulation.subTitleCollection.length) : 0); this.accumulation.initialClipRect = new Rect(this.accumulation.margin.left, this.accumulation.margin.top, this.accumulation.availableSize.width, this.accumulation.availableSize.height); subtractRect(this.accumulation.initialClipRect, new Rect(0, (subTitleHeight + titleHeight), this.accumulation.margin.right + this.accumulation.margin.left, this.accumulation.margin.bottom + this.accumulation.margin.top)); this.accumulation.accumulationLegendModule.calculateLegendBounds(this.accumulation.initialClipRect, this.accumulation.availableSize, null); } } } this.accumulation[(firstToLowerCase(this.type) + 'SeriesModule')].initProperties(this.accumulation, this); this.renderPoints(this.accumulation, seriesGroup, this.accumulation.redraw, previousRadius, previousCenter, true); if (previousLegendBounds && ((this.accumulation.legendSettings.position === 'Bottom' || (this.accumulation.legendSettings.position === 'Top')) ? (previousLegendBounds.height !== this.accumulation.accumulationLegendModule.legendBounds.height) : (previousLegendBounds.width !== this.accumulation.accumulationLegendModule.legendBounds.width)) && this.accumulation.centerLabel.text) { this.accumulation.renderCenterLabel(true, true); } if (this.accumulation.annotationModule) { this.accumulation.annotationModule.renderAnnotations(getElement(this.accumulation.element.id + '_Secondary_Element')); } if (this.accumulation.accumulationDataLabelModule && this.dataLabel.visible) { var datalabelGroup = this.accumulation.renderer.createGroup({ id: this.accumulation.element.id + '_datalabel_Series_' + this.index }); this.renderDataLabel(this.accumulation, datalabelGroup, this.accumulation.redraw); } if (this.accumulation.legendSettings.visible) { if (this.type === 'Pie') { if (this.dataLabel.visible && this.points[this.points.length - 1] && this.points[this.points.length - 1].textSize.width > maxLabelWidth && this.accumulation.legendSettings.position !== 'Top' && this.accumulation.legendSettings.position !== 'Bottom') { this.accumulation.visibleSeries[0].findMaxBounds(this.accumulation.visibleSeries[0].labelBound, this.points[this.points.length - 1].labelRegion); this.findMaxBounds(this.labelBound, this.accumulationBound); this.labelBound.x -= this.accumulation.explodeDistance; this.labelBound.y -= this.accumulation.explodeDistance; this.labelBound.height += (this.accumulation.explodeDistance - this.labelBound.y); this.labelBound.width += (this.accumulation.explodeDistance - this.labelBound.x); } this.accumulation.accumulationLegendModule.getSmartLegendLocation(this.accumulation.visibleSeries[0].labelBound, this.accumulation.accumulationLegendModule.legendBounds, this.accumulation.margin); } this.accumulation.accumulationLegendModule.renderLegend(this.accumulation, this.accumulation.legendSettings, this.accumulation.accumulationLegendModule.legendBounds, this.accumulation.redraw, true); } }; /** * To find point is empty. * * @param {AccPoints} point - The point to check. * @returns {boolean} - True if the point is empty, otherwise false. */ AccumulationSeries.prototype.isEmpty = function (point) { return point.color === this.emptyPointSettings.fill; }; __decorate([ Property('') ], AccumulationSeries.prototype, "dataSource", void 0); __decorate([ Property() ], AccumulationSeries.prototype, "query", void 0); __decorate([ Property('') ], AccumulationSeries.prototype, "xName", void 0); __decorate([ Property('') ], AccumulationSeries.prototype, "name", void 0); __decorate([ Property('') ], AccumulationSeries.prototype, "tooltipMappingName", void 0); __decorate([ Property('') ], AccumulationSeries.prototype, "yName", void 0); __decorate([ Property(true) ], AccumulationSeries.prototype, "visible", void 0); __decorate([ Complex({ color: null, width: 0 }, Border) ], AccumulationSeries.prototype, "border", void 0); __decorate([ Complex(null, Animation) ], AccumulationSeries.prototype, "animation", void 0); __decorate([ Property('SeriesType') ], AccumulationSeries.prototype, "legendShape", void 0); __decorate([ Property('') ], AccumulationSeries.prototype, "legendImageUrl", void 0); __decorate([ Property('') ], AccumulationSeries.prototype, "pointColorMapping", void 0); __decorate([ Property(false) ], AccumulationSeries.prototype, "applyPattern", void 0); __decorate([ Property(null) ], AccumulationSeries.prototype, "selectionStyle", void 0); __decorate([ Property(null) ], AccumulationSeries.prototype, "groupTo", void 0); __decorate([ Property('Value') ], AccumulationSeries.prototype, "groupMode", void 0); __decorate([ Complex({}, AccumulationDataLabelSettings) ], AccumulationSeries.prototype, "dataLabel", void 0); __decorate([ Property([]) ], AccumulationSeries.prototype, "palettes", void 0); __decorate([ Property(0) ], AccumulationSeries.prototype, "startAngle", void 0); __decorate([ Property(null) ], AccumulationSeries.prototype, "endAngle", void 0); __decorate([ Property(null) ], AccumulationSeries.prototype, "radius", void 0); __decorate([ Property('0') ], AccumulationSeries.prototype, "innerRadius", void 0); __decorate([ Property('Pie') ], AccumulationSeries.prototype, "type", void 0); __decorate([ Property(true) ], AccumulationSeries.prototype, "enableTooltip", void 0); __decorate([ Property(false) ], AccumulationSeries.prototype, "explode", void 0); __decorate([ Property('30%') ], AccumulationSeries.prototype, "explodeOffset", void 0); __decorate([ Property(false) ], AccumulationSeries.prototype, "explodeAll", void 0); __decorate([ Property(null) ], AccumulationSeries.prototype, "explodeIndex", void 0); __decorate([ Complex({ mode: 'Drop' }, EmptyPointSettings) ], AccumulationSeries.prototype, "emptyPointSettings", void 0); __decorate([ Property(0) ], AccumulationSeries.prototype, "gapRatio", void 0); __decorate([ Property('80%') ], AccumulationSeries.prototype, "width", void 0); __decorate([ Property('80%') ], AccumulationSeries.prototype, "height", void 0); __decorate([ Property('20%') ], AccumulationSeries.prototype, "neckWidth", void 0); __decorate([ Property('20%') ], AccumulationSeries.prototype, "neckHeight", void 0); __decorate([ Property('Linear') ], AccumulationSeries.prototype, "pyramidMode", void 0); __decorate([ Property('Standard') ], AccumulationSeries.prototype, "funnelMode", void 0); __decorate([ Property(1) ], AccumulationSeries.prototype, "opacity", void 0); __decorate([ Property('0') ], AccumulationSeries.prototype, "dashArray", void 0); __decorate([ Complex({}, Accessibility) ], AccumulationSeries.prototype, "accessibility", void 0); __decorate([ Property(0) ], AccumulationSeries.prototype, "borderRadius", void 0); return AccumulationSeries; }(ChildProperty)); export { AccumulationSeries }; /** * method to get series from index. * * @private * @param {number} index - The index of the series to retrieve. * @param {AccumulationSeries[]} visibleSeries - The array of visible series in the chart. * @returns {AccumulationSeries} - The series retrieved from the specified index. */ export function getSeriesFromIndex(index, visibleSeries) { for (var _i = 0, visibleSeries_1 = visibleSeries; _i < visibleSeries_1.length; _i++) { var series = visibleSeries_1[_i]; if (index === series.index) { return series; } } return visibleSeries[0]; } /** * method to get point from index. * * @private * @param {number} index - The index of the point to retrieve. * @param {AccPoints[]} points - The array of points in the data set. * @returns {AccPoints} - The point retrieved from the specified index. */ export function pointByIndex(index, points) { for (var _i = 0, points_1 = points; _i < points_1.length; _i++) { var point = points_1[_i]; if (point.index === index) { return point; } } return null; }