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,142 lines 161 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; }; import { Component, Property, NotifyPropertyChanges, Internationalization, SanitizeHtmlHelper } from '@syncfusion/ej2-base'; import { L10n, setValue, isNullOrUndefined, updateBlazorTemplate } from '@syncfusion/ej2-base'; import { ChildProperty } from '@syncfusion/ej2-base'; import { remove, extend } from '@syncfusion/ej2-base'; import { Browser, Touch } from '@syncfusion/ej2-base'; import { Event, EventHandler, Complex, Collection } from '@syncfusion/ej2-base'; import { findClipRect, showTooltip, ImageOption, removeElement, appendChildElement, blazorTemplatesReset, withInBounds, getValueXByPoint, getValueYByPoint } from '../common/utils/helper'; import { textElement, RectOption, createSvg, firstToLowerCase, titlePositionX, redrawElement, getTextAnchor } from '../common/utils/helper'; import { appendClipElement, ChartLocation } from '../common/utils/helper'; import { getSeriesColor, getThemeColor } from '../common/model/theme'; import { Margin, Border, TooltipSettings, Indexes, ChartArea, titleSettings, Accessibility } from '../common/model/base'; import { Row, Column, Axis } from './axis/axis'; import { CartesianAxisLayoutPanel } from './axis/cartesian-panel'; import { Rect, measureText, TextOption, Size, SvgRenderer } from '@syncfusion/ej2-svg-base'; import { ChartData } from './utils/get-data'; import { Series } from './series/chart-series'; import { Data } from '../common/model/data'; import { Marker, markerShapes } from './series/marker'; import { LegendSettings } from '../common/legend/legend'; import { TechnicalIndicator } from './technical-indicators/technical-indicator'; import { chartMouseClick, chartDoubleClick, pointClick, pointDoubleClick, axisLabelClick, beforeResize } from '../common/model/constants'; import { chartMouseDown, chartMouseMove, chartMouseUp, load, pointMove, chartMouseLeave, resized } from '../common/model/constants'; import { ChartAnnotationSettings, StackLabelSettings, ToolbarPosition } from './model/chart-base'; import { getElement, getTitle } from '../common/utils/helper'; import { PrintUtils } from '../common/utils/print'; /** * Configures the range color settings in the chart. */ var RangeColorSetting = /** @class */ (function (_super) { __extends(RangeColorSetting, _super); function RangeColorSetting() { return _super !== null && _super.apply(this, arguments) || this; } __decorate([ Property() ], RangeColorSetting.prototype, "start", void 0); __decorate([ Property() ], RangeColorSetting.prototype, "end", void 0); __decorate([ Property([]) ], RangeColorSetting.prototype, "colors", void 0); __decorate([ Property('') ], RangeColorSetting.prototype, "label", void 0); return RangeColorSetting; }(ChildProperty)); export { RangeColorSetting }; /** * Options to configure the crosshair on the chart, which displays lines that follow the mouse cursor and show the axis values of the data points. */ var CrosshairSettings = /** @class */ (function (_super) { __extends(CrosshairSettings, _super); function CrosshairSettings() { return _super !== null && _super.apply(this, arguments) || this; } __decorate([ Property(false) ], CrosshairSettings.prototype, "enable", void 0); __decorate([ Property('') ], CrosshairSettings.prototype, "dashArray", void 0); __decorate([ Complex({ color: null, width: 1 }, Border) ], CrosshairSettings.prototype, "line", void 0); __decorate([ Property('Both') ], CrosshairSettings.prototype, "lineType", void 0); __decorate([ Property('') ], CrosshairSettings.prototype, "verticalLineColor", void 0); __decorate([ Property('') ], CrosshairSettings.prototype, "horizontalLineColor", void 0); __decorate([ Property(1) ], CrosshairSettings.prototype, "opacity", void 0); __decorate([ Property(false) ], CrosshairSettings.prototype, "snapToData", void 0); __decorate([ Property(false) ], CrosshairSettings.prototype, "highlightCategory", void 0); return CrosshairSettings; }(ChildProperty)); export { CrosshairSettings }; /** * Configures the zooming behavior for the chart. */ var ZoomSettings = /** @class */ (function (_super) { __extends(ZoomSettings, _super); function ZoomSettings() { return _super !== null && _super.apply(this, arguments) || this; } __decorate([ Property(false) ], ZoomSettings.prototype, "enableSelectionZooming", void 0); __decorate([ Property(false) ], ZoomSettings.prototype, "enablePinchZooming", void 0); __decorate([ Property(false) ], ZoomSettings.prototype, "showToolbar", void 0); __decorate([ Property(false) ], ZoomSettings.prototype, "enableMouseWheelZooming", void 0); __decorate([ Property(true) ], ZoomSettings.prototype, "enableDeferredZooming", void 0); __decorate([ Property('XY') ], ZoomSettings.prototype, "mode", void 0); __decorate([ Property(['Zoom', 'ZoomIn', 'ZoomOut', 'Pan', 'Reset']) ], ZoomSettings.prototype, "toolbarItems", void 0); __decorate([ Property(false) ], ZoomSettings.prototype, "enablePan", void 0); __decorate([ Property(false) ], ZoomSettings.prototype, "enableScrollbar", void 0); __decorate([ Property(false) ], ZoomSettings.prototype, "enableAnimation", void 0); __decorate([ Complex({}, ToolbarPosition) ], ZoomSettings.prototype, "toolbarPosition", void 0); __decorate([ Complex({}, Accessibility) ], ZoomSettings.prototype, "accessibility", void 0); return ZoomSettings; }(ChildProperty)); export { ZoomSettings }; /** * Represents the chart control. * ```html * <div id="chart"/> * <script> * var chartObj = new Chart({}); * chartObj.appendTo("#chart"); * </script> * ``` * * @public */ var Chart = /** @class */ (function (_super) { __extends(Chart, _super); /** * Constructor for the chart component. * * @param {ChartModel} [options] - The chart model options. * @param {string | HTMLElement} [element] - The element ID or instance where the chart needs to be rendered. * @private */ function Chart(options, element) { var _this = _super.call(this, options, element) || this; /** @private */ _this.rotatedDataLabelCollections = []; /** @public */ _this.animated = false; /** @private */ _this.isPointMouseDown = false; /** @private */ _this.isScrolling = false; /** @private */ _this.checkResize = 0; /** @private */ _this.visible = 0; /** @private */ _this.clickCount = 0; /** @private */ _this.maxPointCount = 0; /** @private */ _this.singleClickTimer = 0; /** @private */ _this.chartAreaType = 'Cartesian'; /** @private */ _this.isRtlEnabled = false; _this.isCrosshair = true; _this.chartid = 57723; /** @private */ _this.isLegendClicked = false; _this.isZoomed = false; _this.previousTargetId = ''; _this.currentPointIndex = 0; _this.currentSeriesIndex = 0; _this.currentLegendIndex = 0; _this.previousPageX = null; _this.previousPageY = null; _this.allowPan = false; /** @private */ _this.pointsRemoved = false; /** @private */ _this.pointsAdded = false; /** @private */ _this.zoomRedraw = false; setValue('mergePersistData', _this.mergePersistChartData, _this); return _this; } /** * To manage persist chart data. * * @returns {void} */ Chart.prototype.mergePersistChartData = function () { var data = window.localStorage.getItem(this.getModuleName() + this.element.id); if (!(isNullOrUndefined(data) || (data === ''))) { var dataObj = JSON.parse(data); var keys = Object.keys(dataObj); this.isProtectedOnChange = true; for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) { var key = keys_1[_i]; if ((typeof this[key] === 'object') && !isNullOrUndefined(this[key])) { extend(this[key], dataObj[key]); } else { this[key] = dataObj[key]; } } this.isProtectedOnChange = false; } }; /** * Checks if the element ID contains special characters. * * @param {string} elementId - The ID of the element. * @returns {string} - The modified ID without special characters. */ Chart.prototype.isIdHasSpecialCharacter = function (elementId) { var regex = /^[A-Za-z ]+$/; var numberRegex = /^[0-9 ]+$/; var childElementId = ''; if (!regex.test(elementId)) { var start = 0; if (numberRegex.test(elementId[0])) { childElementId += ('\\3' + elementId[0]); start = 1; } for (var i = start; i < elementId.length; i++) { if (!regex.test(elementId[i]) && elementId.indexOf('-') === -1 && elementId.indexOf('_') === -1 && elementId.indexOf('\\') === -1 && !numberRegex.test(elementId[i])) { childElementId += ('\\' + elementId[i]); } else { childElementId += elementId[i]; } } return childElementId; } else { return elementId; } }; /** * Initialize the event handler. */ Chart.prototype.preRender = function () { this.element.id = this.isIdHasSpecialCharacter(this.element.id); // It is used for checking blazor framework or not. var blazor = 'Blazor'; this.isBlazor = window[blazor]; this.allowServerDataBinding = false; this.markerIndex = 0; this.unWireEvents(); this.initPrivateVariable(); this.setCulture(); this.wireEvents(); if (this.stockChart) { if (this.stockChart.tooltip.header === null) { this.tooltip.header = this.stockChart.theme.indexOf('Tailwind3') > -1 ? '${point.x}' : '<b>${point.x}</b>'; } if (this.stockChart.tooltip.format === null) { this.tooltip.format = this.stockChart.theme.indexOf('Tailwind3') > -1 ? 'High : ${point.high}<br/>Low :' + ' ${point.low}<br/>Open : ${point.open}<br/>Close : ${point.close}' : 'High : <b>${point.high}</b><br/>Low :' + ' <b>${point.low}</b><br/>Open : <b>${point.open}</b><br/>Close : <b>${point.close}</b>'; } } this.element.setAttribute('dir', this.enableRtl ? 'rtl' : 'ltr'); }; Chart.prototype.initPrivateVariable = function () { this.animateSeries = true; this.delayRedraw = false; this.dragY = null; this.horizontalAxes = []; this.verticalAxes = []; this.refreshAxis(); this.refreshDefinition(this.rows); this.refreshDefinition(this.columns); if (this.tooltipModule) { this.tooltipModule.previousPoints = []; } 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.style.outline = 'none'; this.element.setAttribute('aria-label', this.accessibility.accessibilityDescription ? this.accessibility.accessibilityDescription : this.title + '. Syncfusion interactive chart.'); if (!(this.element.classList.contains('e-chart-focused'))) { this.element.setAttribute('class', this.element.getAttribute('class') + ' e-chart-focused'); } if (this.element.id === '') { var collection = document.getElementsByClassName('e-chart').length; var elementid = 'chart_' + this.chartid + '_' + collection; while (document.getElementById(elementid)) { collection++; elementid = 'chart_' + this.chartid + '_' + collection; } this.element.id = 'chart_' + this.chartid + '_' + collection; } //seperate ID to differentiate chart and stock chart this.svgId = this.stockChart ? this.stockChart.element.id + '_stockChart_chart' : this.element.id + (this.enableCanvas ? '_canvas' : '_svg'); }; /** * To Initialize the control rendering. */ Chart.prototype.render = function () { var _this = this; this.svgRenderer = new SvgRenderer(this.element.id); var loadEventData = { chart: this.isBlazor ? {} : this, theme: this.theme, name: load, cancel: false }; if (!this.stockChart) { /** * Load event for the chart will be triggered only chart componet, if this is stock chart, load event did not triggered. */ this.trigger(load, loadEventData, function () { if (!loadEventData.cancel) { _this.cartesianChartRendering(loadEventData); } }); } else { // The fix is specific for nextjs app, as window is set as not defined for server side application like nextjs. this.isRtlEnabled = (window.getComputedStyle(document.querySelector('body')).direction === 'rtl'); this.cartesianChartRendering(loadEventData); } this.applyZoomkit(); }; Chart.prototype.cartesianChartRendering = function (beforeRenderData) { this.theme = this.isBlazor ? beforeRenderData.theme : this.theme; this.setTheme(); this.createChartSvg(); this.markerRender = new Marker(this); this.calculateAreaType(); this.calculateVisibleSeries(); this.initTechnicalIndicators(); this.initTrendLines(); this.calculateVisibleAxis(); this.processData(); this.renderComplete(); this.mouseMoveEvent(); this.allowServerDataBinding = true; }; /** * Gets the localized label by locale keyword. * * @param {string} key key * @returns {string} localized label */ Chart.prototype.getLocalizedLabel = function (key) { return this.localeObject.getConstant(key); }; /** * Initiates animation for the chart. * * @param {number} [duration] - The duration of the animation in milliseconds. * @returns {void} * @private */ Chart.prototype.animate = function (duration) { this.redraw = true; this.animated = true; //used to set duration as 1000 for animation at default 300 this.duration = duration ? duration : 1000; if (this.tooltipModule) { this.tooltipModule.removeHighlightedMarker(this.tooltipModule.previousPoints, true); } else if (this.markerRender.previousPoints) { for (var previousPoint = 0; previousPoint < this.markerRender.previousPoints.length; previousPoint++) { this.markerRender.removeHighlightedMarker(this.markerRender.previousPoints[previousPoint].series, this.markerRender.previousPoints[previousPoint].point); } } }; /** * Refresh the chart bounds. * * @private */ Chart.prototype.refreshBound = function () { this.rotatedDataLabelCollections = []; if (this.legendModule && this.legendSettings.visible) { this.legendModule.getLegendOptions(this.visibleSeries, this); } /** * I264230, EJ2-36761 * Issue: Tooltip doesnot appears after zooming and hovering on same point * Root cause: While performing zoom, previous points in tooltip restore. * Fix: previous points set to empty array */ if (this.tooltip.enable && this.tooltipModule) { this.tooltipModule.previousPoints = []; } this.calculateStackValues(); this.calculateBounds(); //this prevents the initial rendering of stock chart if (this.stockChart && !this.stockChart.rangeFound) { if (this.stockChart.enablePeriodSelector || this.stockChart.enableSelector) { return null; } } this.renderElements(); removeElement('chartmeasuretext'); this.removeSelection(); if (this.markerRender) { this.markerRender.mergeXvalues(this.visibleSeries); } }; /** * To calcualte the stack values. * * @returns {void} * @private */ Chart.prototype.calculateStackValues = function () { var series; var isCalculateStacking = false; for (var i = 0, len = this.visibleSeries.length; i < len; i++) { series = this.visibleSeries[i]; if (series.visible) { series.position = series.rectCount = undefined; } if (((series.type.indexOf('Stacking') !== -1) || (series.drawType.indexOf('Stacking') !== -1 && this.chartAreaType === 'PolarRadar')) && !isCalculateStacking) { series.calculateStackedValue(series.type.indexOf('100') > -1, this); isCalculateStacking = true; } } }; Chart.prototype.removeSelection = function () { for (var _i = 0, _a = this.visibleSeries; _i < _a.length; _i++) { var series = _a[_i]; if (series.visible) { for (var _b = 0, _c = series.points; _b < _c.length; _b++) { var point = _c[_b]; point.isSelect = false; } } } if (getElement(this.element.id + '_ej2_drag_multi_group')) { if (this.selectionMode.indexOf('Drag') > -1) { this.selectionModule.filterArray = []; } removeElement(this.element.id + '_ej2_drag_multi_group'); this.selectionModule.calculateDragSelectedElements(this, new Rect(0, 0, 0, 0), true); } else if (getElement(this.element.id + '_ej2_drag_group')) { if (this.selectionMode !== 'Lasso') { this.selectionModule.filterArray = []; } removeElement(this.element.id + '_ej2_drag_group'); this.selectionModule.calculateDragSelectedElements(this, new Rect(0, 0, 0, 0), true); } }; Chart.prototype.renderElements = function () { this.renderBorder(); this.renderTitle(); this.renderAreaBorder(); this.renderSeriesElements(this.renderAxes()); this.renderLegend(); this.applyZoomkit(); this.performSelection(); this.setSecondaryElementPosition(); for (var _i = 0, _a = this.visibleSeries; _i < _a.length; _i++) { var value = _a[_i]; updateBlazorTemplate(this.element.id + '_DataLabel', 'Template', value.marker.dataLabel); } this.renderAnnotation(); if (this.stackLabels.visible && this.visibleSeries.some(function (series) { return series.type && series.type.indexOf('Stacking') > -1; }) && this.dataLabelModule) { this.dataLabelModule.renderStackLabels(); } }; /** * To render the legend * * @private */ Chart.prototype.renderAxes = function () { this.yAxisElements = this.renderer.createGroup({ id: this.element.id + 'yAxisCollection' }); var axisElement; if (this.rows.length > 0 && this.columns.length > 0) { axisElement = this.chartAxisLayoutPanel.renderAxes(); } if (this.stripLineModule) { this.stripLineModule.renderStripLine(this, 'Behind', this.axisCollections); } return axisElement; }; /** * To render the legend */ Chart.prototype.renderLegend = function () { if (this.legendModule && this.legendModule.legendCollections.length && this.legendSettings.visible) { this.legendModule.calTotalPage = true; var borderWidth = this.legendSettings.border.width; var bounds = this.legendModule.legendBounds; var rect = new Rect(bounds.x, bounds.y, bounds.width, bounds.height); if (this.enableCanvas) { this.canvasRender.ctx.beginPath(); rect = new Rect(rect.x - borderWidth / 2, rect.y - borderWidth / 2, rect.width + borderWidth, rect.height + borderWidth); this.renderer.canvasClip(rect); } this.legendModule.renderLegend(this, this.legendSettings, bounds); if (this.enableCanvas) { this.renderer.canvasRestore(); } } if (!this.redraw) { if (!this.stockChart) { this.element.appendChild(this.svgObject); } else { if (!getElement(this.stockChart.chartObject.id)) { this.stockChart.mainObject.appendChild(this.svgObject); } } } }; /** * To set the left and top position for data label template for center aligned chart. * * @returns {void} */ Chart.prototype.setSecondaryElementPosition = function () { var element = getElement(this.element.id + '_Secondary_Element'); if (!element) { return; } var rect = this.element.getBoundingClientRect(); var svgRect = getElement(this.svgId).getBoundingClientRect(); element.style.left = Math.max(((svgRect.left - rect.left) / this.scaleX), 0) + 'px'; element.style.top = Math.max(((svgRect.top - rect.top) / this.scaleY), 0) + 'px'; }; Chart.prototype.initializeModuleElements = function () { this.dataLabelCollections = []; this.lastValueLabelCollections = []; var elementId = this.element.id; if (this.series.length) { this.seriesElements = this.svgRenderer.createGroup({ id: elementId + 'SeriesCollection' }); } if (this.indicators.length) { this.indicatorElements = this.renderer.createGroup({ id: elementId + 'IndicatorCollection' }); } if (this.hasTrendlines()) { this.trendLineElements = this.renderer.createGroup({ id: elementId + 'TrendLineCollection' }); } if (this.lastValueLabelModule) { this.lastValueLabelElements = this.renderer.createGroup({ id: elementId + 'LastValueLabelCollection' }); } this.dataLabelElements = this.renderer.createGroup({ id: elementId + 'DataLabelCollection' }); }; Chart.prototype.hasTrendlines = function () { var isTrendline; for (var _i = 0, _a = this.series; _i < _a.length; _i++) { var series = _a[_i]; isTrendline = series.trendlines.length ? true : false; if (isTrendline) { break; } } return isTrendline; }; Chart.prototype.renderSeriesElements = function (axisElement) { // Initialize the series elements values this.initializeModuleElements(); var elementId = this.element.id; if (this.element.tagName !== 'g') { var tooltipDiv = redrawElement(this.redraw, elementId + '_Secondary_Element') || this.createElement('div'); tooltipDiv.id = elementId + '_Secondary_Element'; tooltipDiv.style.cssText = 'position: relative'; appendChildElement(false, this.element, tooltipDiv, this.redraw); } // For canvas if (this.enableCanvas) { var tooltipdiv = document.getElementById(elementId + '_Secondary_Element'); tooltipdiv = !tooltipdiv ? this.createElement('div', { id: elementId + '_Secondary_Element', attrs: { 'style': 'position: relative; left:0px; top:0px' } }) : tooltipdiv; var svg = this.svgRenderer.createSvg({ id: elementId + '_tooltip_svg', width: this.availableSize.width, height: this.availableSize.height }); svg.style.cssText = 'position: absolute; pointer-events: none'; tooltipdiv.appendChild(svg); } // For userInteraction if (this.tooltip.enable && !this.stockChart) { appendChildElement(this.enableCanvas, this.svgObject, this.renderer.createGroup({ id: elementId + '_UserInteraction', style: 'pointer-events:none;' }), this.redraw); } if (this.rows.length > 0 && this.columns.length > 0) { this.initializeIndicator(); this.initializeTrendLine(); this.renderSeries(); if (this.enableCanvas) { for (var _i = 0, _a = this.visibleSeries; _i < _a.length; _i++) { var series = _a[_i]; if (series.lastValueLabel.enable) { this.lastValueLabelModule.render(series, this, series.lastValueLabel); } } } // Trendline is append to DOM after the series if (this.trendLineElements) { appendChildElement(this.enableCanvas, this.svgObject, this.trendLineElements, this.redraw); } this.appendElementsAfterSeries(axisElement); } }; /** * Renders the series on the chart. * * @private * @returns {void} */ Chart.prototype.renderSeries = function () { var visibility; if (this.enableCanvas) { // To clip the series rect for canvas this.renderer.canvasClip(this.chartAxisLayoutPanel.seriesClipRect); } for (var _i = 0, _a = this.visibleSeries; _i < _a.length; _i++) { var item = _a[_i]; if (item.category === 'TrendLine') { visibility = this.series[item.sourceIndex].trendlines[item.index].visible; } else { visibility = item.visible; } if (!visibility) { if (item.lastValueLabelElement) { removeElement(item.lastValueLabelElement.id); item.lastValueLabelElement = null; } } if (visibility) { this.visible++; findClipRect(item, this.enableCanvas); if (this.enableCanvas) { // To render scatter and bubble series in canvas this.renderCanvasSeries(); } item.renderSeries(this); } else if (item.isLegendClicked && (item.type.indexOf('StackingArea') > -1 || item.type.indexOf('StackingBar') > -1 || item.type.indexOf('StackingColumn') > -1)) { findClipRect(item, this.enableCanvas); item.renderSeries(this); } } if (this.enableCanvas) { this.renderer.canvasRestore(); } this.visible = 0; var options = { 'id': this.element.id + '_ChartAreaClipRect_', 'x': this.chartAxisLayoutPanel.seriesClipRect.x, 'y': this.chartAxisLayoutPanel.seriesClipRect.y, 'width': this.chartAxisLayoutPanel.seriesClipRect.width, 'height': this.chartAxisLayoutPanel.seriesClipRect.height, 'fill': 'transparent', 'stroke-width': 1, 'stroke': 'Gray' }; if (!this.seriesElements || (options.height < 0 || options.width < 0)) { return; } var clipRectElement; if (this.chartAreaType === 'PolarRadar') { clipRectElement = appendClipElement(this.redraw, options, this.renderer, 'drawCircularClipPath'); } else { clipRectElement = appendClipElement(this.redraw, options, this.renderer); } if (!this.enableCanvas) { this.seriesElements.appendChild(clipRectElement); } var seriesSvg = document.getElementById(this.element.id + '_series_svg'); if (seriesSvg) { appendChildElement(false, seriesSvg, this.seriesElements, this.redraw); } else { appendChildElement(this.enableCanvas, this.svgObject, this.seriesElements, this.redraw); } }; Chart.prototype.renderCanvasSeries = function () { // const svgElement: Element; // svgElement = (this.enableCanvas) ? // svgElement : this.svgObject; // const canvas: boolean = (this.enableCanvas) ? // false : this.enableCanvas; var svgElement; // let canvas: boolean; if (this.enableCanvas) { var tempSvgElement = svgElement; svgElement = tempSvgElement; // canvas = false; } else { svgElement = this.svgObject; // canvas = this.enableCanvas; } }; Chart.prototype.initializeIndicator = function () { for (var _i = 0, _a = this.indicators; _i < _a.length; _i++) { var indicator = _a[_i]; if (this[firstToLowerCase(indicator.type) + 'IndicatorModule']) { this[firstToLowerCase(indicator.type) + 'IndicatorModule'].createIndicatorElements(this, indicator, indicator.index); } } if (this.indicatorElements) { appendChildElement(this.enableCanvas, this.svgObject, this.indicatorElements, this.redraw); } }; Chart.prototype.initializeTrendLine = function () { for (var _i = 0, _a = this.visibleSeries; _i < _a.length; _i++) { var series = _a[_i]; if (series.trendlines.length) { this.trendLineModule.getTrendLineElements(series, this); } } }; Chart.prototype.appendElementsAfterSeries = function (axisElement) { if (this.chartAreaType === 'PolarRadar') { appendChildElement(this.enableCanvas, this.svgObject, this.yAxisElements, this.redraw); } appendChildElement(this.enableCanvas, this.svgObject, axisElement, this.redraw); if ((this.zoomModule && this.zoomSettings.enableScrollbar && this.scrollElement && this.scrollElement.childElementCount) || (this.scrollElement && this.scrollElement.childElementCount)) { appendChildElement(false, getElement(this.element.id + '_Secondary_Element'), this.scrollElement, this.redraw); } if (this.stripLineModule) { this.stripLineModule.renderStripLine(this, 'Over', this.axisCollections); } if (!this.tooltip.enable || this.stockChart) { appendChildElement(this.enableCanvas, this.svgObject, this.renderer.createGroup({ id: this.element.id + '_UserInteraction', style: 'pointer-events:none;' }), this.redraw); } if (this.stockChart) { this.stockChart.calculateStockEvents(); } if (this.lastValueLabelElements && this.lastValueLabelElements.hasChildNodes()) { appendChildElement(this.enableCanvas, this.svgObject, this.lastValueLabelElements, this.redraw); } }; Chart.prototype.applyZoomkit = function () { /** * Issue: Zoomkit not visible after performing refresh() * Fix: this method called without checking `zoomModule.isZoomed` */ if (this.chartAreaType === 'PolarRadar') { return; } if ((!this.redraw || this.zoomRedraw) && this.zoomModule && (!this.zoomSettings.enablePan || this.zoomModule.performedUI || this.zoomSettings.showToolbar)) { this.zoomModule.applyZoomToolkit(this, this.axisCollections); } }; /** * Render annotation perform here. * * @private * @returns {void} */ Chart.prototype.renderAnnotation = function () { if (this.annotationModule) { //for stock chart, stock chart's id is added to render the annotations this.annotationModule.renderAnnotations(getElement((this.stockChart ? this.stockChart.element.id : this.element.id) + '_Secondary_Element')); } }; Chart.prototype.performSelection = function () { var selectedDataIndexes = []; if (this.selectionModule) { selectedDataIndexes = extend([], this.selectionModule.selectedDataIndexes, null, true); this.selectionModule.invokeSelection(this); } if (this.highlightModule) { this.highlightModule.invokeHighlight(this); } if (selectedDataIndexes.length > 0) { this.selectionModule.selectedDataIndexes = selectedDataIndexes; this.selectionModule.redrawSelection(this, this.selectionMode); } }; Chart.prototype.processData = function (render) { if (render === void 0) { render = true; } this.visibleSeriesCount = 0; var check = true; var prevPointCount = 0; for (var _i = 0, _a = this.visibleSeries; _i < _a.length; _i++) { var series = _a[_i]; if (!series.visible && !this.legendSettings.visible) { this.visibleSeriesCount++; continue; } if (series.category !== 'Indicator' && series.category !== 'TrendLine') { this.initializeDataModule(series); } } for (var _b = 0, _c = this.indicators; _b < _c.length; _b++) { var indicator = _c[_b]; if (indicator.dataSource) { var techIndicator = indicator; this.initializeDataModule(techIndicator); check = false; } } if (render && (!this.visibleSeries.length || this.visibleSeriesCount === this.visibleSeries.length && check)) { this.refreshBound(); this.trigger('loaded', { chart: this.isBlazor ? {} : this }); } if (!this.stockChart && this.visibleSeries.length > 0) { for (var _d = 0, _e = this.visibleSeries; _d < _e.length; _d++) { var series = _e[_d]; if (!isNullOrUndefined(series.points)) { this.maxPointCount = Math.max(prevPointCount, series.points.length); prevPointCount = series.points.length; } } } }; Chart.prototype.initializeDataModule = function (series) { series.xData = []; series.yData = []; var dataSource; var isAngular = 'isAngular'; if (this[isAngular]) { dataSource = Object.keys(series.dataSource).length ? series.dataSource : this.dataSource; } else { dataSource = series.dataSource || this.dataSource; } series.dataModule = new Data(dataSource, series.query); series.points = []; series.refreshDataManager(this); }; /** * To provide the array of modules needed for control rendering. * * @returns {void} - To provide the array of modules needed for control rendering. * @private */ Chart.prototype.calculateBounds = function () { var margin = this.margin; // Title Height; var titleHeight = 0; var subTitleHeight = 0; var padding = this.titleStyle.position === 'Top' || (this.titleStyle.position === 'Bottom' && !this.legendSettings.visible) ? 15 : 5; var left = margin.left + this.border.width; var width = this.availableSize.width - left - margin.right - this.border.width; var elementSpacing = 0; this.titleCollection = []; this.subTitleCollection = []; if (this.title) { this.titleCollection = getTitle(this.title, this.titleStyle, width, this.enableRtl, this.themeStyle.chartTitleFont); titleHeight = (measureText(this.title, this.titleStyle, this.themeStyle.chartTitleFont).height * this.titleCollection.length) + padding; if (this.subTitle) { this.subTitleCollection = getTitle(this.subTitle, this.subTitleStyle, width, this.enableRtl, this.themeStyle.chartSubTitleFont); subTitleHeight = (measureText(this.subTitle, this.subTitleStyle, this.themeStyle.chartSubTitleFont).height * this.subTitleCollection.length) + padding; } } else if (this.legendSettings.position !== 'Top' && this.border.width) { elementSpacing = 10; } var top = margin.top + elementSpacing + this.border.width + this.chartArea.border.width * 0.5; var height = this.availableSize.height - top - this.border.width - margin.bottom; var marginTotal = subTitleHeight + titleHeight + this.titleStyle.border.width + this.subTitleStyle.border.width; switch (this.titleStyle.position) { case 'Top': top += marginTotal; height -= marginTotal; break; case 'Bottom': height -= marginTotal; break; case 'Left': left += marginTotal; width -= marginTotal; break; case 'Right': left -= (this.titleStyle.border.width + this.subTitleStyle.border.width); width -= marginTotal; break; } if (this.stockChart && this.stockChart.legendSettings.visible && this.stockChart.stockLegendModule) { if (this.stockChart.legendSettings.position === 'Top') { top += this.stockChart.stockLegendModule.legendBounds.height; } else if (this.stockChart.legendSettings.position === 'Left') { left += this.stockChart.stockLegendModule.legendBounds.width; } } if (this.scrollBarModule && ((this.zoomModule && this.zoomSettings.enableScrollbar && this.zoomModule.isZoomed) || this.scrollSettingEnabled)) { var scrollbarPadding = 10; for (var i = 0, len = this.axisCollections.length; i < len; i++) { var axis = this.axisCollections[i]; if (axis.orientation === 'Horizontal' && axis.scrollbarSettings.position === 'Bottom') { height -= axis.scrollbarSettings.height + scrollbarPadding; } else if (axis.orientation === 'Horizontal' && axis.scrollbarSettings.position === 'Top') { height -= axis.scrollbarSettings.height + scrollbarPadding; top += axis.scrollbarSettings.height + scrollbarPadding; } else if (axis.orientation === 'Vertical' && axis.scrollbarSettings.position === 'Right') { width -= axis.scrollbarSettings.height + scrollbarPadding; } else if (axis.orientation === 'Vertical' && axis.scrollbarSettings.position === 'Left') { width -= axis.scrollbarSettings.height + scrollbarPadding; left += axis.scrollbarSettings.height + scrollbarPadding; } } } this.initialClipRect = new Rect(left, top, width, height); if (this.legendModule && this.legendSettings.visible) { this.legendModule.calculateLegendBounds(this.initialClipRect, this.availableSize, null); } this.initialClipRect.y += this.chartArea.margin.top; this.initialClipRect.height -= (this.chartArea.margin.top + this.chartArea.margin.bottom); this.initialClipRect.x += this.chartArea.margin.left; this.initialClipRect.width -= (this.chartArea.margin.left + this.chartArea.margin.right); this.chartAxisLayoutPanel.measureAxis(this.initialClipRect); }; /** * Prints the chart or specified element. * * @param {string[] | string | Element} id - The ID or array of IDs of the elements to print. * @returns {void} */ Chart.prototype.print = function (id) { var exportChart = new PrintUtils(this); var width = this.width; if (this.getModuleName() === 'chart' && parseInt(this.width, 10) >= 80 && this.width.indexOf('%') > -1) { this.width = '80%'; this.dataBind(); } exportChart.print(id); if (this.getModuleName() === 'chart' && parseInt(this.width, 10) >= 80 && this.width.indexOf('%') > -1) { this.width = width; this.dataBind(); } }; /** * Defines the trendline initialization. * * @returns {void} */ Chart.prototype.initTrendLines = function () { this.isProtectedOnChange = true; for (var _i = 0, _a = this.visibleSeries; _i < _a.length; _i++) { var series = _a[_i]; var trendIndex = 0; for (var _b = 0, _c = series.trendlines; _b < _c.length; _b++) { var trendline = _c[_b]; var trendLine = trendline; if (this.trendLineModule) { trendLine.index = trendIndex; trendLine.sourceIndex = series.index; this.trendLineModule.initSeriesCollection(trendLine, this); if (trendLine.targetSeries) { trendLine.targetSeries.xAxisName = series.xAxisName; trendLine.targetSeries.yAxisName = series.yAxisName; this.visibleSeries.push(trendLine.targetSeries); } } trendIndex++; } } this.isProtectedOnChange = false; }; Chart.prototype.calculateAreaType = function () { var series = this.series[0]; this.chartArea.border.width = this.stockChart ? 0 : this.chartArea.border.width; if (series) { this.requireInvertedAxis = ((series.type.indexOf('Bar') !== -1) && !this.isTransposed) || ((series.type.indexOf('Bar') === -1) && this.isTransposed && this.chartAreaType !== 'PolarRadar'); } this.chartAxisLayoutPanel = this.chartAreaType === 'PolarRadar' ? (this.polarSeriesModule || this.radarSeriesModule) : new CartesianAxisLayoutPanel(this); }; /** * Calculate the visible axis. * * @private * @returns {void} */ Chart.prototype.calculateVisibleAxis = function () { var axis; var axes = [this.primaryXAxis, this.primaryYAxis]; axes = this.chartAreaType === 'Cartesian' ? axes.concat(this.axes) : axes; if (this.paretoSeriesModule && this.series[0] && this.series[0].type === 'Pareto') { axes = axes.concat(this.paretoSeriesModule.paretoAxes); } this.axisCollections = []; if (this.zoomModule) { this.zoomModule.isPanning = this.zoomModule.isAxisZoomed(axes) && this.zoomSettings.enablePan; this.svgObject.setAttribute('cursor', this.zoomModule.isPanning ? 'pointer' : 'auto'); if (this.scrollBarModule) { this.scrollBarModule.axes = axes; } } if (this.scrollSettingEnabled) { if (this.scrollBarModule) { this.scrollBarModule.axes = axes; } } for (var i = 0, len = axes.length; i < len; i++) { axis = axes[i]; axis.series = []; axis.labels = []; axis.indexLabels = {}; for (var _i = 0, _a = this.visibleSeries; _i < _a.length; _i++) { var series = _a[_i]; this.initAxis(series, axis, true); if (series.category === 'Pareto' && series.type === 'Line' && series.yAxis) { series.yAxis.internalVisibility = series.paretoOptions.showAxis; } } for (var _b = 0, _c = this.indicators; _b < _c.length; _b++) { var indicator = _c[_b]; this.initAxis(indicator, axis, false); } if (this.scrollBarModule && !axis.zoomingScrollBar) { this.scrollBarModule.injectTo(axis, this); } if (axis.orientation != null) { this.axisCollections.push(axis); } } if (this.rows.length > 0 && this.columns.length > 0) { this.chartAxisLayoutPanel.measure(); } }; Chart.prototype.initAxis = function (series, axis, isSeries) { if (series.xAxisName === axis.name || (series.xAxisName == null && axis.name === 'primaryXAxis')) { axis.orientation = this.requireInvertedAxis ? 'Vertical' : 'Horizontal'; series.xAxis = axis; if (isSeries) { axis.series.push(series); } } else if (series.yAxisName === axis.name || (series.yAxisName == null && axis.name === 'primaryYAxis')) { axis.orientation = this.requireInvertedAxis ? 'Horizontal' : 'Vertical'; series.yAxis = axis; if (isSeries) { axis.series.push(series); } } }; Chart.prototype.initTechnicalIndicators = function () { var i = 0; for (var _i = 0, _a = this.indicators; _i < _a.length; _i++) { var indicator = _a[_i]; var techIndicator = indicator; var type = firstToLowerCase(techIndicator.type); if (this[type + 'IndicatorModule']) { techIndicator.index = i; this[type + 'IndicatorModule'].initSeriesCollection(techIndicator, this); for (var _b = 0, _c = techIndicator.targetSeries; _b < _c.length; _b++) { var targetSeries = _c[_b]; if (indicator.seriesName || indicator.dataSource) { this.visibleSeries.push(targetSeries); } } } i++; } }; /** * Refreshes the technical indicator for the specified series. * * @param {SeriesBase} series - The series for which to refresh the technical indicator. * @returns {void} * @private */ Chart.prototype.refreshTechnicalIndicator = function (series) { if (this.indicators.length) { var targetIndicator = null; if (series instanceof Series && series.category !== 'Indicator') { for (var _i = 0, _a = this.indicators; _i < _a.length; _i++) { var indicator = _a[_i]; if (indicator.seriesName === series.name && !indicator.dataSource) { targetIndicator = indicator; targetIndicator.setDataSource(series, this); } } } else if (series instanceof TechnicalIndicator) { targetIndicator = series; targetIndicator.setDataSource(series instanceof Series ? series : null, this); } } }; Chart.prototype.calculateVisibleSeries = function () { var series; this.visibleSeries = []; var colors = this.palettes.length ? this.palettes : getSeriesColor(this.theme); var count = colors.length; var seriesCollection = this.series.sort(function (a, b) { return a.zOrder - b.zOrder; }); for (var i = 0, len = seriesCollection.length; i < len; i++) { series = seriesCollection[i]; // for y axis label issue during chart navigation series.category = seriesCollection[0].type === 'Pareto' ? 'Pareto' : 'Series'; series.index = i; series.interior = series.fill || colors[i % count]; if (!series.marker.shape && (series.marker.visible || series.type === 'Scatter' || series.drawType === 'Scatter')) { series.marker.shape = markerShapes[this.markerIndex % 10]; this.markerIndex++; } if (this.isSecondaryAxis(series.xAxis)) { series.xAxis.internalVisibility = series.xAxis.series.some(function (value) { return (value.visible); }); } if (this.isSecondaryAxis(series.yAxis)) { series.yAxis.internalVisibility = series.yAxis.series.some(function (value) { return (value.visible); }); } switch (series.