@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
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
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.