@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,167 lines (1,166 loc) • 49.1 kB
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
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, Complex, Collection, Internationalization, NotifyPropertyChanges } from '@syncfusion/ej2-base';
import { Browser, remove, Event, EventHandler } from '@syncfusion/ej2-base';
import { DataManager } from '@syncfusion/ej2-data';
import { Chart, ZoomSettings, CrosshairSettings } from '../chart/chart';
import { appendChildElement, redrawElement, titlePositionX, textElement } from '../common/utils/helper';
import { Size, Rect, TextOption, measureText, SvgRenderer } from '@syncfusion/ej2-svg-base';
import { calculateSize, getElement } from '../common/utils/helper';
import { RangeNavigator } from '../range-navigator/range-navigator';
import { getRangeValueXByPoint } from '../range-navigator/utils/helper';
import { PeriodSelector } from '../common/period-selector/period-selector';
import { CartesianChart } from './renderer/cartesian-chart';
import { RangeSelector } from './renderer/range-selector';
import { ToolBarSelector } from './renderer/toolbar-selector';
import { StockMargin, StockChartArea, StockChartAxis, StockChartRow, StockChartIndexes, StockEventsSettings } from './model/base';
import { StockSeries, StockChartIndicator, StockChartBorder } from './model/base';
import { StockChartAnnotationSettings } from './model/base';
import { StockChartFont } from './model/base';
import { getSeriesColor, getThemeColor } from '../common/model/theme';
import { StockEvents } from './renderer/stock-events';
import { StockChartLegendSettings } from './legend/legend';
import { ColumnSeries, RangeAreaSeries, SplineRangeAreaSeries } from './index';
import { Periods, StockTooltipSettings } from '../common/model/base';
import { isNullOrUndefined } from '@syncfusion/ej2-base';
import { createTemplate } from '../common/utils/helper';
import { createElement } from '@syncfusion/ej2-base';
/**
* Stock Chart
*
* @public
*/
var StockChart = /** @class */ (function (_super) {
__extends(StockChart, _super);
/**
* Constructor for creating the widget.
*
* @param {StockChartModel} options - Specifies the stock chart model.
* @param {string | HTMLElement} element - Specifies the element for the stock chart.
* @hidden
*/
function StockChart(options, element) {
var _this = _super.call(this, options, element) || this;
/** @private */
_this.isSingleAxis = false;
_this.chartid = 57723;
_this.tempSeriesType = [];
/** private */
_this.zoomChange = false;
/** @private */
_this.allowPan = false;
/** @private */
_this.onPanning = false;
/** @private */
_this.trendlinetriggered = true;
/** @private */
_this.initialRender = true;
/** @private */
_this.rangeFound = false;
/** @private */
_this.tempPeriods = [];
_this.isDateTimeCategory = false;
_this.sortedData = [];
_this.visibleRange = {
min: 0, max: 0,
delta: 0, interval: 0
};
_this.isStockChartRendered = false;
StockChart_1.Inject(ColumnSeries, RangeAreaSeries, SplineRangeAreaSeries);
_this.toolbarHeight = _this.enablePeriodSelector ? (Browser.isDevice ? 56 : 42) : 0;
return _this;
}
StockChart_1 = StockChart;
/**
* Called internally if any of the property value changed.
*
* @private
* @param {StockChartModel} newProp - The new StockChartModel.
* @returns {void}
*/
StockChart.prototype.onPropertyChanged = function (newProp) {
// on property changes
for (var _i = 0, _a = Object.keys(newProp); _i < _a.length; _i++) {
var property = _a[_i];
switch (property) {
case 'series':
this.storeDataSource();
this.chartRender();
this.stockChartDataManagerSuccess();
this.legendClicked = false;
break;
}
}
};
/**
* To change the range for chart.
*
* @param {number} updatedStart - The updated start value for the chart range.
* @param {number} updatedEnd - The updated end value for the chart range.
* @returns {void}
*/
StockChart.prototype.rangeChanged = function (updatedStart, updatedEnd) {
// manage chart refresh
var chartElement = document.getElementById(this.chartObject.id);
if (chartElement) {
while (chartElement.firstChild) {
chartElement.removeChild(chartElement.firstChild);
}
}
this.startValue = updatedStart;
this.endValue = updatedEnd;
this.cartesianChart.initializeChart();
this.periodSelector.datePicker.startDate = this.isDateTimeCategory ? new Date(this.sortedData[updatedStart]) :
new Date(updatedStart);
this.periodSelector.datePicker.endDate = this.isDateTimeCategory ? new Date(this.sortedData[updatedEnd]) :
new Date(updatedEnd);
this.periodSelector.datePicker.dataBind();
};
/**
* Pre render for financial Chart.
*
* @returns {void}
*/
StockChart.prototype.preRender = function () {
this.unWireEvents();
this.initPrivateVariable();
this.allowServerDataBinding = false;
this.isProtectedOnChange = true;
this.setCulture();
this.wireEvents();
};
/**
* Method to bind events for chart.
*
* @returns {void}
*/
StockChart.prototype.unWireEvents = function () {
/** Find the Events type */
var startEvent = Browser.touchStartEvent;
var moveEvent = Browser.touchMoveEvent;
var stopEvent = Browser.touchEndEvent;
var cancelEvent = Browser.isPointer ? 'pointerleave' : 'mouseleave';
/** UnBind the Event handler */
EventHandler.remove(this.element, startEvent, this.stockChartOnMouseDown);
EventHandler.remove(this.element, moveEvent, this.stockChartOnMouseMove);
EventHandler.remove(this.element, stopEvent, this.stockChartMouseEnd);
EventHandler.remove(this.element, 'click', this.stockChartOnMouseClick);
EventHandler.remove(this.element, 'contextmenu', this.stockChartRightClick);
EventHandler.remove(this.element, cancelEvent, this.stockChartOnMouseLeave);
window.removeEventListener((Browser.isTouch && ('orientation' in window && 'onorientationchange' in window)) ? 'orientationchange' : 'resize', this.stockChartResize);
};
StockChart.prototype.wireEvents = function () {
/** Find the Events type */
var cancelEvent = Browser.isPointer ? 'pointerleave' : 'mouseleave';
/** Bind the Event handler */
EventHandler.add(this.element, Browser.touchStartEvent, this.stockChartOnMouseDown, this);
EventHandler.add(this.element, Browser.touchMoveEvent, this.stockChartOnMouseMove, this);
EventHandler.add(this.element, Browser.touchEndEvent, this.stockChartMouseEnd, this);
EventHandler.add(this.element, 'click', this.stockChartOnMouseClick, this);
EventHandler.add(this.element, 'contextmenu', this.stockChartRightClick, this);
EventHandler.add(this.element, cancelEvent, this.stockChartOnMouseLeave, this);
window.addEventListener((Browser.isTouch && ('orientation' in window && 'onorientationchange' in window)) ? 'orientationchange' : 'resize', this.stockChartResize.bind(this));
this.setStyle(this.element);
};
StockChart.prototype.initPrivateVariable = function () {
if (this.element.id === '') {
var collection = document.getElementsByClassName('e-stockChart').length;
this.element.id = 'stockChart_' + this.chartid + '_' + collection;
}
this.seriesXMax = null;
this.seriesXMin = null;
this.startValue = null;
this.endValue = null;
this.currentEnd = null;
this.margin = {
right: this.margin.right === null ? (Browser.isDevice ? 5 : 10) : this.margin.right,
left: this.margin.left === null ? (Browser.isDevice ? 5 : 10) : this.margin.left,
top: this.margin.top === null ? (Browser.isDevice ? 5 : 10) : this.margin.top,
bottom: this.margin.bottom === null ? (Browser.isDevice ? 5 : 10) : this.margin.bottom
};
this.isStockChartRendered = false;
};
/**
* Method to set culture for chart.
*
* @returns {void}
*/
StockChart.prototype.setCulture = function () {
this.intl = new Internationalization();
};
StockChart.prototype.storeDataSource = function () {
for (var i = 0; i < this.series.length; i++) {
var series = this.series[i];
this.tempSeriesType.push(series.type);
series.localData = undefined;
}
if (this.series.length === 0) {
this.series.push({});
}
this.initialRender = !this.legendClicked;
this.rangeFound = false;
this.resizeTo = null;
this.startValue = null;
this.endValue = null;
};
/**
* To Initialize the control rendering.
*
* @returns {void}
*/
StockChart.prototype.render = function () {
var _this = this;
var loadEventData = { name: 'load', stockChart: this, theme: this.theme };
this.trigger('load', loadEventData, function () {
//this.theme = this.theme;
_this.themeStyle = getThemeColor(_this.theme, false, _this);
_this.storeDataSource();
_this.drawSVG();
_this.renderTitle();
_this.renderLegend();
_this.chartModuleInjection();
_this.chartRender();
if (!(_this.dataSource instanceof DataManager) || !(_this.series[0].dataSource instanceof DataManager)) {
_this.stockChartDataManagerSuccess();
_this.initialRender = false;
}
_this.renderComplete();
_this.allowServerDataBinding = true;
_this.isStockChartRendered = true;
});
this.isProtectedOnChange = false;
};
/**
* DataManager Success.
*
* @returns {void}
*/
StockChart.prototype.stockChartDataManagerSuccess = function () {
this.findRange();
var isAllSeriesEmpty = this.series.every(function (s) {
var dataSource = s.dataSource || [];
return !dataSource || dataSource.length === 0;
});
this.renderNoDataTemplate(isAllSeriesEmpty && !isNullOrUndefined(this.noDataTemplate));
this.renderRangeSelector();
this.renderPeriodSelector();
this.trigger('loaded', { stockChart: this });
};
StockChart.prototype.renderNoDataTemplate = function (allowTemplate) {
var existingTemplate = this.element.querySelector("#" + this.element.id + "_NoDataTemplate_wrapper");
if (existingTemplate) {
existingTemplate.remove();
}
if (allowTemplate) {
var rawTemplate = typeof this.noDataTemplate === 'function'
? this.noDataTemplate() : this.noDataTemplate;
var wrapper = createElement('div', { id: this.element.id + '_NoDataTemplate_wrapper' });
var container = this.element.querySelector("#" + this.element.id + "_Secondary_Element");
var borderStrokeWidth = 0;
var borderElement = document.getElementById(this.element.id + "_stock_border");
if (borderElement) {
var computedStyle = getComputedStyle(borderElement);
var borderWidth = computedStyle.borderWidth || computedStyle.borderTopWidth;
borderStrokeWidth = borderWidth ? parseFloat(borderWidth) : 0;
}
var topOffset = 0;
if (this.title) {
var titleHeight = measureText(this.title, this.titleStyle, this.themeStyle.chartTitleFont).height;
topOffset = titleHeight + 11;
}
var chartRect = this.element.getBoundingClientRect();
var rangeSelector = document.querySelector("#" + this.element.id + "_rangeSelector") ||
container.querySelector('[id*="rangeSelector"]');
var bottom = chartRect.bottom;
if (rangeSelector) {
var rangeRect = rangeSelector.getBoundingClientRect();
bottom = Math.max(bottom, rangeRect.bottom);
}
var containerRect = container.getBoundingClientRect();
var height = bottom - containerRect.top - topOffset - borderStrokeWidth;
wrapper.style.cssText = "position: absolute; top: " + topOffset + "px; left: " + borderStrokeWidth + "px; width: " + (this.availableSize.width - borderStrokeWidth * 2) + "px;\n height: " + height + "px; z-index: 1;\n ";
var secondaryElement = getElement(this.element.id + '_Secondary_Element');
secondaryElement.appendChild(wrapper);
createTemplate(wrapper, null, rawTemplate, this, null, null, this.element.id + '_NoData');
}
};
/**
* To set styles to resolve mvc width issue.
*
* @param {HTMLElement} element - The html element.
* @returns {void}
*/
StockChart.prototype.setStyle = function (element) {
var zooming = this.zoomSettings;
var disableScroll = zooming.enableSelectionZooming || zooming.enablePinchZooming ||
this.selectionMode !== 'None' || this.crosshair.enable;
element.style.msTouchAction = disableScroll ? 'none' : 'element';
element.style.touchAction = disableScroll ? 'none' : 'element';
element.style.msUserSelect = 'none';
element.style.msContentZooming = 'none';
element.style.position = 'relative';
element.style.display = 'block';
element.style.webkitUserSelect = 'none';
};
StockChart.prototype.drawSVG = function () {
this.removeSvg();
calculateSize(this);
this.renderer = new SvgRenderer(this.element.id);
this.renderBorder();
this.createSecondaryElements();
this.calculateVisibleSeries();
this.calculateLegendBounds();
//overall svg in which chart and selector appened
this.mainObject = this.renderer.createSvg({
id: this.element.id + '_stockChart_svg',
width: this.availableSize.width,
height: this.availableSize.height - (this.enablePeriodSelector ? this.toolbarHeight : 0) - this.titleSize.height,
style: 'display: block;'
});
this.svgObject = this.mainObject;
this.element.appendChild(this.mainObject);
};
StockChart.prototype.calculateVisibleSeries = function () {
this.visibleSeries = [];
var series;
var color = getSeriesColor(this.theme);
var count = color.length;
var seriesCollections = this.series.sort(function (a, b) { return a.zOrder - b.zOrder; });
for (var i = 0, len = seriesCollections.length; i < len; i++) {
series = seriesCollections[i];
series.category = 'Series';
series.index = i;
series.interior = series.fill || color[i % count];
this.visibleSeries.push(series);
seriesCollections[i] = series;
}
};
StockChart.prototype.createSecondaryElements = function () {
var tooltipDiv = redrawElement(false, this.element.id + '_Secondary_Element') ||
this.createElement('div');
tooltipDiv.id = this.element.id + '_Secondary_Element';
if (this.title) {
this.titleSize = measureText(this.title, this.titleStyle, this.themeStyle.chartTitleFont);
this.titleSize.height += 15; // for title padding
}
else {
this.titleSize = { height: null, width: null };
}
var height = (this.enablePeriodSelector ? this.toolbarHeight : 0) + this.titleSize.height;
tooltipDiv.style.cssText = 'position: relative; height:' + height + 'px';
appendChildElement(false, this.element, tooltipDiv, false);
};
/**
* To provide the array of modules needed for control rendering
*
* @returns {ModuleDeclaration[]} required modules
* @private
*/
StockChart.prototype.requiredModules = function () {
var modules = [];
if (this.legendSettings.visible) {
modules.push({
member: 'StockLegend',
args: [this]
});
}
return modules;
};
StockChart.prototype.findCurrentData = function (totalData, xName) {
var tempData = (!this.enablePeriodSelector && !this.enableSelector) ? totalData : undefined;
var start = (this.isDateTimeCategory) ? new Date(this.sortedData[Math.floor(this.startValue)]).getTime() :
this.startValue;
var end = (this.isDateTimeCategory) ? new Date(this.sortedData[Math.floor(this.endValue)]).getTime() : this.endValue;
if (totalData && start && end) {
tempData = totalData
.filter(function (data) {
return (new Date(Date.parse(data[xName])).getTime() >= start &&
new Date(Date.parse(data[xName])).getTime() <= end);
});
}
return tempData;
};
/**
* Render period selector.
*
* @returns {void}
*/
StockChart.prototype.renderPeriodSelector = function () {
if (this.enablePeriodSelector) {
this.toolbarSelector.initializePeriodSelector();
this.periodSelector.toolbar.refreshOverflow(); //to avoid overlapping toolbar elements
if (!this.enableSelector) {
this.cartesianChart.cartesianChartRefresh(this);
}
}
};
StockChart.prototype.chartRender = function () {
this.sortedData = [];
this.cartesianChart = new CartesianChart(this);
this.cartesianChart.initializeChart();
};
/**
* To render range Selector.
*
* @returns {void}
*/
StockChart.prototype.renderRangeSelector = function () {
//SVG in which range navigator is going to append
if (this.enableSelector) {
this.rangeSelector = new RangeSelector(this);
this.rangeSelector.initializeRangeNavigator();
}
};
/**
* Get component name.
*
* @returns {string} - To get the module name.
*/
StockChart.prototype.getModuleName = function () {
return 'stockChart';
};
/**
* Get the properties to be maintained in the persisted state.
*
* @private
* @returns {string} - The persisted data containing the properties.
*/
StockChart.prototype.getPersistData = function () {
return '';
};
/**
* To Remove the SVG.
*
* @returns {void}
* @private
*/
StockChart.prototype.removeSvg = function () {
if (document.getElementById(this.element.id + '_Secondary_Element')) {
remove(document.getElementById(this.element.id + '_Secondary_Element'));
}
var removeLength = 0;
if (this.mainObject) {
while (this.mainObject.childNodes.length > removeLength) {
this.mainObject.removeChild(this.mainObject.firstChild);
}
if (!this.mainObject.hasChildNodes() && this.mainObject.parentNode) {
remove(this.mainObject);
this.mainObject = null;
this.selectorObject = null;
this.chartObject = null;
}
}
};
/**
* Module Injection for components.
*
* @returns {void}
*/
StockChart.prototype.chartModuleInjection = function () {
var moduleName;
for (var _i = 0, _a = this.getInjectedModules(); _i < _a.length; _i++) {
var modules = _a[_i];
moduleName = modules.prototype.getModuleName().toLowerCase();
if (moduleName.indexOf('rangetooltip') === -1) {
Chart.Inject(modules);
}
else {
RangeNavigator.Inject(modules);
}
if (moduleName === 'datetime' || moduleName === 'areaseries' || moduleName === 'steplineseries' || moduleName === 'datetimecategory') {
RangeNavigator.Inject(modules);
}
}
};
/**
* Find range for financal chart.
*
* @returns {void}
* @private
*/
StockChart.prototype.findRange = function () {
var _this = this;
this.seriesXMin = Infinity;
this.seriesXMax = -Infinity;
for (var _i = 0, _a = this.chart.series; _i < _a.length; _i++) {
var value = _a[_i];
if (value.visible) {
this.seriesXMin = Math.min(this.seriesXMin, value.xMin);
this.seriesXMax = Math.max(this.seriesXMax, value.xMax);
}
}
this.endValue = this.currentEnd = this.seriesXMax;
if (this.enablePeriodSelector) {
this.toolbarSelector = new ToolBarSelector(this);
this.periodSelector = new PeriodSelector(this);
this.tempPeriods = this.periods.length ? this.periods : this.toolbarSelector.calculateAutoPeriods();
this.tempPeriods.map(function (period) {
if (period.selected && period.text.toLowerCase() === 'ytd') {
if (_this.isDateTimeCategory) {
var currentYear = new Date(_this.sortedData[_this.currentEnd]).getFullYear();
var index = _this.currentEnd - 1;
for (; index >= 0; index--) {
if (new Date(_this.sortedData[index]).getFullYear() !== currentYear) {
_this.startValue = index + 1;
break;
}
}
_this.startValue = index === -1 ? 0 : _this.startValue;
}
else {
_this.startValue = new Date(new Date(_this.currentEnd).getFullYear().toString()).getTime();
}
}
else if (period.selected && period.text.toLowerCase() === 'all') {
_this.startValue = _this.seriesXMin;
}
else if (period.selected) {
_this.startValue = _this.periodSelector.changedRange(period.intervalType, _this.endValue, period.interval).getTime();
_this.startValue = _this.isDateTimeCategory ? _this.periodSelector.findStartValue(_this.startValue, _this.endValue) :
_this.startValue;
}
});
}
else {
this.startValue = this.seriesXMin;
}
this.rangeFound = true;
};
/**
* Handles the chart resize.
*
* @returns {boolean} false
* @private
*/
StockChart.prototype.stockChartResize = function () {
var _this = this;
// To avoid resize console error
if (!document.getElementById(this.element.id)) {
return false;
}
this.animateSeries = false;
if (this.resizeTo) {
clearTimeout(this.resizeTo);
}
this.resizeTo = +setTimeout(function () {
if (_this.cartesianChart) {
calculateSize(_this);
_this.renderBorder();
_this.calculateLegendBounds();
_this.renderTitle();
_this.renderLegend();
_this.cartesianChart.cartesianChartRefresh(_this);
_this.mainObject.setAttribute('width', (_this.availableSize.width + (_this.stockLegendModule && (_this.legendSettings.position === 'Right' || _this.legendSettings.position === 'Left') ? _this.stockLegendModule.legendBounds.width : 0)).toString());
if (_this.enablePeriodSelector) {
_this.renderPeriodSelector();
}
}
}, 500);
return false;
};
/**
* Handles the mouse down on chart.
*
* @param {PointerEvent} e - The pointer event.
* @returns {boolean} - false
* @private
*/
StockChart.prototype.stockChartOnMouseDown = function (e) {
var pageX;
var pageY;
var target;
var touchArg;
var rect = this.chart.element.getBoundingClientRect();
var element = e.target;
this.trigger('stockChartMouseDown', { target: element.id, x: this.mouseX, y: this.mouseY });
if (e.type === 'touchstart') {
this.isTouch = true;
touchArg = e;
pageX = touchArg.changedTouches[0].clientX;
target = touchArg.target;
pageY = touchArg.changedTouches[0].clientY;
}
else {
this.isTouch = e.pointerType === 'touch';
pageX = e.clientX;
pageY = e.clientY;
target = e.target;
}
if (target.id.indexOf(this.element.id + '_stockChart_chart') > -1) {
var svgRect = getElement(this.element.id + '_stockChart_chart').getBoundingClientRect();
this.mouseDownY = this.previousMouseMoveY = (pageY - rect.top) - Math.max(svgRect.top - rect.top, 0);
this.mouseDownX = this.previousMouseMoveX = (pageX - rect.left) - Math.max(svgRect.left - rect.left, 0);
this.setMouseXY(pageX, pageY);
this.referenceXAxis = this.chart.primaryXAxis;
getElement(this.element.id + '_stockChart_chart').setAttribute('cursor', 'pointer');
if (this.isDateTimeCategory) {
this.visibleRange.min = this.sortedData.indexOf(parseInt(this.referenceXAxis.labels[this.referenceXAxis.visibleRange.min], 10));
this.visibleRange.max = this.sortedData.indexOf(parseInt(this.referenceXAxis.labels[this.referenceXAxis.visibleRange.max], 10));
this.visibleRange.delta = this.referenceXAxis.visibleRange.delta;
this.visibleRange.interval = this.referenceXAxis.visibleRange.interval;
}
else {
this.visibleRange = this.referenceXAxis.visibleRange;
}
this.mouseDownXPoint = getRangeValueXByPoint(this.mouseX - this.referenceXAxis.rect.x, this.referenceXAxis.rect.width, this.visibleRange, this.referenceXAxis.isInversed);
this.allowPan = true;
this.notify(Browser.touchStartEvent, e);
}
return false;
};
/**
* Handles the mouse up.
*
* @param {PointerEvent} e - The pointer event.
* @returns {boolean} - false
* @private
*/
StockChart.prototype.stockChartMouseEnd = function (e) {
var pageY;
var pageX;
var touchArg;
if (e.type === 'touchend') {
touchArg = e;
pageX = touchArg.changedTouches[0].clientX;
pageY = touchArg.changedTouches[0].clientY;
this.isTouch = true;
}
else {
pageY = e.clientY;
pageX = e.clientX;
this.isTouch = e.pointerType === 'touch' || e.pointerType === '2';
}
getElement(this.element.id + '_stockChart_chart').setAttribute('cursor', 'auto');
this.onPanning = false;
this.setMouseXY(pageX, pageY);
this.stockChartOnMouseUp(e);
return false;
};
/**
* Handles the mouse up.
*
* @param {PointerEvent | TouchEvent} e - The pointer event or touch event.
* @returns {boolean} - false
* @private
*/
StockChart.prototype.stockChartOnMouseUp = function (e) {
var element = e.target;
this.trigger('stockChartMouseUp', { target: element.id, x: this.mouseX, y: this.mouseY });
this.isChartDrag = false;
this.allowPan = false;
if (this.rangeNavigator) {
this.rangeNavigator.rangeSlider.isDrag = false;
}
if (this.isTouch) {
this.threshold = new Date().getTime() + 300;
}
this.notify(Browser.touchEndEvent, e);
if (this.stockEvent) {
this.stockEvent.removeStockEventTooltip(0);
}
return false;
};
/**
* To find mouse x, y for aligned chart element svg position.
*
* @param {number} pageX - The x-coordinate of the mouse pointer event.
* @param {number} pageY - The y-coordinate of the mouse pointer event.
* @returns {void}
*/
StockChart.prototype.setMouseXY = function (pageX, pageY) {
var svgRectElement = getElement(this.element.id + '_stockChart_chart');
if (this.element && svgRectElement) {
var stockRect = this.element.getBoundingClientRect();
var svgRect = svgRectElement.getBoundingClientRect();
this.mouseX = (pageX - stockRect.left) - Math.max(svgRect.left - stockRect.left, 0);
this.mouseY = (pageY - stockRect.top) - Math.max(svgRect.top - stockRect.top, 0);
}
};
/**
* Handles the mouse move.
*
* @param {PointerEvent} e - The pointer event.
* @returns {boolean} - false
* @private
*/
StockChart.prototype.stockChartOnMouseMove = function (e) {
var pageX;
var touchArg;
var pageY;
this.mouseMoveEvent = e;
if (e.type === 'touchmove') {
this.isTouch = true;
touchArg = e;
pageY = touchArg.changedTouches[0].clientY;
pageX = touchArg.changedTouches[0].clientX;
}
else {
this.isTouch = e.pointerType === 'touch' || e.pointerType === '2' || this.isTouch;
pageX = e.clientX;
pageY = e.clientY;
}
this.trigger('stockChartMouseMove', { target: e.target.id, x: this.mouseX, y: this.mouseY });
if (getElement(this.element.id + '_stockChart_chart')) {
this.setMouseXY(pageX, pageY);
this.chartOnMouseMove(e);
}
return false;
};
/**
* Handles the mouse move on chart.
*
* @param {PointerEvent | TouchEvent} e - The pointer event or touch event.
* @returns {boolean} - false
* @private
*/
StockChart.prototype.chartOnMouseMove = function (e) {
if (this.rangeNavigator && this.rangeNavigator.rangeSlider.isDrag) {
this.rangeNavigator.mouseX = this.mouseX;
this.rangeNavigator.rangeSlider.mouseMoveHandler(e);
}
if (this.allowPan && !this.chart.startMove && this.mouseDownXPoint && this.mouseX !== this.previousMouseMoveX &&
this.zoomSettings.enablePan) {
this.onPanning = true;
this.zoomChange = false;
getElement(this.element.id + '_stockChart_chart').setAttribute('cursor', 'pointer');
this.mouseUpXPoint = getRangeValueXByPoint(this.mouseX - this.referenceXAxis.rect.x, this.referenceXAxis.rect.width, this.visibleRange, this.referenceXAxis.isInversed);
var diff = Math.abs(this.mouseUpXPoint - this.mouseDownXPoint);
if (this.mouseDownXPoint < this.mouseUpXPoint) {
if (this.seriesXMin <= this.visibleRange.min - diff) {
this.startValue = this.visibleRange.min - diff;
this.endValue = this.visibleRange.max - diff;
if (this.enableSelector) {
this.rangeNavigator.rangeSlider.setSlider(this.visibleRange.min - diff, this.visibleRange.max - diff, !this.rangeNavigator.enableDeferredUpdate, (this.rangeNavigator.rangeTooltipModule
&& this.rangeNavigator.tooltip.enable));
}
else {
this.cartesianChart.cartesianChartRefresh(this);
}
}
}
else {
if (this.seriesXMax >= this.visibleRange.max + diff) {
this.startValue = this.visibleRange.min + diff;
this.endValue = this.visibleRange.max + diff;
if (this.enableSelector) {
this.rangeNavigator.rangeSlider.setSlider(this.visibleRange.min + diff, this.visibleRange.max + diff, !this.rangeNavigator.enableDeferredUpdate, (this.rangeNavigator.rangeTooltipModule
&& this.rangeNavigator.tooltip.enable));
}
else {
this.cartesianChart.cartesianChartRefresh(this);
}
}
}
}
this.notify(Browser.touchMoveEvent, e);
if (e.target.id === '' && !this.onPanning === true) { //to remove the tooltip when hover on mouse move
var element = void 0;
if (this.chart.tooltip.enable || this.crosshair.enable) {
element = document.getElementById(this.element.id + '_stockChart_chart_tooltip');
if (element) {
remove(element);
}
}
if (getElement(this.element.id + '_StockEvents_Tooltip')) {
this.stockEvent.removeStockEventTooltip(0);
}
}
if (e.target.id.indexOf('StockEvents') !== -1) {
clearInterval(this.stockEvent.toolTipInterval);
this.stockEvent.renderStockEventTooltip(e.target.id);
}
else {
if (this.stockEvent) {
this.stockEvent.removeStockEventTooltip(1000);
}
}
this.isTouch = false;
return false;
};
/**
* Handles the mouse click on chart.
*
* @param {PointerEvent | TouchEvent} e - The pointer event or touch event.
* @returns {boolean} - false
* @private
*/
StockChart.prototype.stockChartOnMouseClick = function (e) {
var element = e.target;
this.trigger('stockChartMouseClick', { target: element.id, x: this.mouseX, y: this.mouseY });
this.notify('click', e);
return false;
};
StockChart.prototype.stockChartRightClick = function (event) {
if (this.crosshair.enable &&
(event.buttons === 2 || event.which === 0 || event.pointerType === 'touch')) {
event.preventDefault();
event.stopPropagation();
return false;
}
return true;
};
/**
* Handles the mouse leave.
*
* @param {PointerEvent} e - The pointer event.
* @returns {boolean} false
* @private
*/
StockChart.prototype.stockChartOnMouseLeave = function (e) {
var touchArg;
var pageX;
var pageY;
if (e.type === 'touchleave') {
this.isTouch = true;
touchArg = e;
pageX = touchArg.changedTouches[0].clientX;
pageY = touchArg.changedTouches[0].clientY;
}
else {
pageX = e.clientX;
pageY = e.clientY;
this.isTouch = e.pointerType === 'touch' || e.pointerType === '2';
}
this.setMouseXY(pageX, pageY);
this.allowPan = false;
this.stockChartOnMouseLeaveEvent(e);
return false;
};
/**
* Handles the mouse leave on chart.
*
* @param {PointerEvent | TouchEvent} e - The pointer event or touch event.
* @returns {boolean} - false
* @private
*/
StockChart.prototype.stockChartOnMouseLeaveEvent = function (e) {
var cancelEvent = Browser.isPointer ? 'pointerleave' : 'mouseleave';
//this.trigger(chartMouseLeave, { target: element.id, x: this.mouseX, y: this.mouseY });
this.isChartDrag = false;
this.notify(cancelEvent, e);
if (this.stockEvent) {
this.stockEvent.removeStockEventTooltip(1000);
}
if (this.rangeNavigator) {
this.rangeNavigator.rangeSlider.isDrag = false;
}
if (this.onPanning) {
this.onPanning = false;
this.chart.mouseLeave(e);
getElement(this.element.id + '_stockChart_chart').setAttribute('cursor', 'auto');
}
return false;
};
/**
* Destroy method.
*
* @returns {void}
*/
StockChart.prototype.destroy = function () {
this.cartesianChart = null;
this.chart = null;
this.periodSelector = null;
this.rangeNavigator = null;
this.rangeSelector = null;
this.tempPeriods = [];
this.toolbarSelector = null;
this.visibleSeries = [];
this.yAxisElements = null;
var element = document.getElementById(this.element.id + '_stockChart_chartKeyboard_chart_focus');
if (element) {
element.remove();
}
var borderElement = document.getElementById(this.element.id + '_stock_border');
if (borderElement) {
borderElement.remove();
}
if (this.element) {
this.unWireEvents();
_super.prototype.destroy.call(this);
this.removeSvg();
this.svgObject = null;
}
};
StockChart.prototype.renderBorder = function () {
if (this.border.width) {
var border = this.createElement('div');
border.id = this.element.id + '_stock_border';
border.style.width = (this.availableSize.width) + 'px';
border.style.height = (this.availableSize.height) + 'px';
border.style.position = 'absolute';
border.style.border = this.border.width + 'px solid ' + this.border.color;
border.style.pointerEvents = 'none';
appendChildElement(false, getElement(this.element.id), border);
}
};
/**
* Render title for chart.
*
* @returns {void}
*/
StockChart.prototype.renderTitle = function () {
var rect;
if (this.title) {
appendChildElement(false, getElement(this.element.id + '_Secondary_Element'), this.renderer.createSvg({
id: this.element.id + '_stockChart_Title',
width: this.availableSize.width,
height: this.titleSize.height,
fill: this.background || this.themeStyle.background
}), false);
var alignment = this.titleStyle.textAlignment;
var getAnchor = alignment === 'Near' ? 'start' : alignment === 'Far' ? 'end' : 'middle';
rect = new Rect(0, 0, this.availableSize.width, 0);
var options = new TextOption(this.element.id + '_ChartTitle', titlePositionX(rect, this.titleStyle), ((this.titleSize.height - 10)), getAnchor, this.title, '', 'auto');
textElement(this.renderer, options, this.titleStyle, this.titleStyle.color || this.themeStyle.chartTitleFont.color || this.findTitleColor(), getElement(this.element.id + '_stockChart_Title'), false, false, null, null, null, null, null, null, null, null, this.themeStyle.chartTitleFont);
this.availableSize.height -= (this.titleSize.height + 5);
}
};
/**
* To calculate the legend bounds.
*
* @private
* @returns {void}
*/
StockChart.prototype.calculateLegendBounds = function () {
if (this.stockLegendModule && this.legendSettings.visible) {
this.stockLegendModule.getLegendOptions(this.visibleSeries);
}
var titleHeight = this.titleSize.height;
var left = this.border.width;
var width = this.availableSize.width - this.border.width - left;
var top = this.chartArea.border.width * 0.5 + this.border.width;
var height = this.availableSize.height - top - this.border.width -
(this.enablePeriodSelector ? this.toolbarHeight : 0) - titleHeight;
this.initialClipRect = new Rect(left, top, width, height);
this.tempAvailableSize = new Size(this.availableSize.width, this.availableSize.height -
(this.enablePeriodSelector ? this.toolbarHeight : 0) - titleHeight);
if (this.stockLegendModule && this.legendSettings.visible) {
this.stockLegendModule.calculateLegendBounds(this.initialClipRect, this.tempAvailableSize, null);
}
};
/**
* To render the legend.
*
* @private
* @returns {void}
*/
StockChart.prototype.renderLegend = function () {
if (this.stockLegendModule && this.stockLegendModule.legendCollections.length && this.legendSettings.visible) {
this.stockLegendModule.calTotalPage = true;
var bounds = this.stockLegendModule.legendBounds;
this.stockLegendModule.renderLegend(this, this.legendSettings, bounds);
if (this.legendSettings.position === 'Auto' || this.legendSettings.position === 'Bottom' || this.legendSettings.position === 'Top') {
this.availableSize.height -= this.stockLegendModule.legendBounds.height;
}
else if (this.legendSettings.position === 'Left' || this.legendSettings.position === 'Right') {
this.availableSize.width -= this.stockLegendModule.legendBounds.width;
}
}
};
StockChart.prototype.findTitleColor = function () {
if (this.theme.toLocaleLowerCase().indexOf('highcontrast') > -1 || this.theme.indexOf('Dark') > -1) {
return '#ffffff';
}
return '#424242';
};
/**
* To calculate the stock events.
*
* @private
* @returns {void}
*/
StockChart.prototype.calculateStockEvents = function () {
if (this.stockEvents.length) {
this.stockEvent = new StockEvents(this);
appendChildElement(false, this.chartObject, this.stockEvent.renderStockEvents());
}
};
var StockChart_1;
__decorate([
Property(null)
], StockChart.prototype, "noDataTemplate", void 0);
__decorate([
Property(null)
], StockChart.prototype, "width", void 0);
__decorate([
Property(null)
], StockChart.prototype, "height", void 0);
__decorate([
Property('')
], StockChart.prototype, "dataSource", void 0);
__decorate([
Complex({}, StockMargin)
], StockChart.prototype, "margin", void 0);
__decorate([
Complex({ color: '#DDDDDD', width: 1 }, StockChartBorder)
], StockChart.prototype, "border", void 0);
__decorate([
Property(null)
], StockChart.prototype, "background", void 0);
__decorate([
Property('Material')
], StockChart.prototype, "theme", void 0);
__decorate([
Complex({ name: 'primaryXAxis', valueType: 'DateTime' }, StockChartAxis)
], StockChart.prototype, "primaryXAxis", void 0);
__decorate([
Complex({ border: { color: null, width: 0.5 }, background: 'transparent' }, StockChartArea)
], StockChart.prototype, "chartArea", void 0);
__decorate([
Complex({ name: 'primaryYAxis', opposedPosition: true, labelPosition: 'Inside', tickPosition: 'Inside' }, StockChartAxis)
], StockChart.prototype, "primaryYAxis", void 0);
__decorate([
Collection([{}], StockChartRow)
], StockChart.prototype, "rows", void 0);
__decorate([
Collection([{ opposedPosition: true }], StockChartAxis)
], StockChart.prototype, "axes", void 0);
__decorate([
Collection([], StockSeries)
], StockChart.prototype, "series", void 0);
__decorate([
Collection([], StockEventsSettings)
], StockChart.prototype, "stockEvents", void 0);
__decorate([
Property(false)
], StockChart.prototype, "isTransposed", void 0);
__decorate([
Property('')
], StockChart.prototype, "title", void 0);
__decorate([
Complex({ size: null, fontWeight: null, color: null, fontStyle: null, fontFamily: null }, StockChartFont)
], StockChart.prototype, "titleStyle", void 0);
__decorate([
Collection([], StockChartIndicator)
], StockChart.prototype, "indicators", void 0);
__decorate([
Complex({ shared: true, enableMarker: false }, StockTooltipSettings)
], StockChart.prototype, "tooltip", void 0);
__decorate([
Complex({ dashArray: '5', lineType: 'Vertical' }, CrosshairSettings)
], StockChart.prototype, "crosshair", void 0);
__decorate([
Complex({}, StockChartLegendSettings)
], StockChart.prototype, "legendSettings", void 0);
__decorate([
Complex({ enablePan: true }, ZoomSettings)
], StockChart.prototype, "zoomSettings", void 0);
__decorate([
Property(true)
], StockChart.prototype, "enablePeriodSelector", void 0);
__decorate([
Property(true)
], StockChart.prototype, "enableCustomRange", void 0);
__decorate([
Property(false)
], StockChart.prototype, "isSelect", void 0);
__decorate([
Property(true)
], StockChart.prototype, "enableSelector", void 0);
__decorate([
Collection([], Periods)
], StockChart.prototype, "periods", void 0);
__decorate([
Collection([{}], StockChartAnnotationSettings)
], StockChart.prototype, "annotations", void 0);
__decorate([
Event()
], StockChart.prototype, "selectorRender", void 0);
__decorate([
Event()
], StockChart.prototype, "stockChartMouseMove", void 0);
__decorate([
Event()
], StockChart.prototype, "stockChartMouseLeave", void 0);
__decorate([
Event()
], StockChart.prototype, "stockChartMouseDown", void 0);
__decorate([
Event()
], StockChart.prototype, "stockChartMouseUp", void 0);
__decorate([
Event()
], StockChart.prototype, "stockChartMouseClick", void 0);
__decorate([
Event()
], StockChart.prototype, "pointClick", void 0);
__decorate([
Event()
], StockChart.prototype, "pointMove", void 0);
__decorate([
Event()
], StockChart.prototype, "onZooming", void 0);
__decorate([
Event()
], StockChart.prototype, "legendRender", void 0);
__decorate([
Event()
], StockChart.prototype, "legendClick", void 0);
__decorate([
Property('None')
], StockChart.prototype, "selectionMode", void 0);
__decorate([
Property(false)
], StockChart.prototype, "isMultiSelect", void 0);
__decorate([
Event()
], StockChart.prototype, "load", void 0);
__decorate([
Event()
], StockChart.prototype, "loaded", void 0);
__decorate([
Event()
], StockChart.prototype, "rangeChange", void 0);
__decorate([
Event()
], StockChart.prototype, "axisLabelRender", void 0);
__decorate([
Event()
], StockChart.prototype, "beforeExport", void 0);
__decorate([
Event()
], StockChart.prototype, "tooltipRender", void 0);
__decorate([
Event()
], StockChart.prototype, "seriesRender", void 0);
__decorate([
Event()
], StockChart.prototype, "stockEventRender", void 0);
__decorate([
Collection([], StockChartIndexes)
], StockChart.prototype, "selectedDataIndexes", void 0);
__decorate([
Property([])
], StockChart.prototype, "seriesType", void 0);
__decorate([
Property(['EMA', 'TMA', 'SMA', 'Momentum', 'ATR', 'Accumulation Distribution', 'Bollinger Bands', 'MACD', 'Stochastic', 'RSI'])
], StockChart.prototype, "indicatorType", void 0);
__decorate([
Property(['PNG', 'JPEG', 'SVG', 'PDF', 'XLSX', 'CSV', 'Print'])
], StockChart.prototype, "exportType", void 0);
__decorate([
Property([])
], StockChart.prototype, "trendlineType", void 0);
StockChart = StockChart_1 = __decorate([
NotifyPropertyChanges
], StockChart);
return StockChart;
}(Component));
export { StockChart };