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,040 lines (1,039 loc) 47.5 kB
import { extend, isNullOrUndefined } from '@syncfusion/ej2-base'; import { PathOption, drawPath, drawRectangle, RectOption, Rect, CircleOption, drawCircle, getSeriesColor } from '../utils/helper'; import { measureText, renderTextElement, TextOption } from '../utils/helper'; import { DataManager, Query } from '@syncfusion/ej2-data'; /** * Sparkline rendering calculation file */ var SparklineRenderer = /** @class */ (function () { /** * Sparkline data calculations. * * @param {Sparkline} sparkline - The Sparkline control. */ function SparklineRenderer(sparkline) { this.sparkline = sparkline; } /** * To process the sparkline data. * * @returns {void} */ SparklineRenderer.prototype.processData = function () { var data = this.sparkline.dataSource; if (isNullOrUndefined(data) || !data.length) { return; } else if (!isNaN(this.sparkline.dataSource[0]) || this.sparkline.valueType === 'Numeric') { data = (this.sparkline.enableRtl) ? data.reverse() : data; this.sparkline.sparklineData = data; // extend([], data) as Object[]; } else { this['process' + this.sparkline.valueType](); } this.axisCalculation(); }; SparklineRenderer.prototype.processDataManager = function () { var _this = this; var dataModule; var queryModule; if (this.sparkline.dataSource instanceof DataManager) { dataModule = this.sparkline.dataSource; queryModule = this.sparkline.query instanceof Query ? this.sparkline.query : new Query(); var dataManager = dataModule.executeQuery(queryModule); dataManager.then(function (e) { _this.sparkline.setProperties({ dataSource: e['result'] }, true); _this.sparkline.sparklineData = _this.sparkline.dataSource; _this.sparkline.processSparklineData(); }); } else { this.sparkline.processSparklineData(); } }; /** * To process sparkline category data. * * @param {Object[]} data - The data array to process. * @param {string} x - The name of the x-field. * @param {string} y - The name of the y-field. * @returns {void} */ SparklineRenderer.prototype.processCategory = function (data, x, y) { var _this = this; if (data === void 0) { data = this.sparkline.dataSource; } if (x === void 0) { x = this.sparkline.xName; } if (y === void 0) { y = this.sparkline.yName; } var temp = []; var xValues = []; data.forEach(function (value) { if (xValues.indexOf(value[x]) === -1) { xValues.push(value[x]); } var currentData = {}; currentData[_this.sparkline.xName] = xValues.indexOf(value[x]); currentData[_this.sparkline.yName] = value[y]; temp.push(currentData); }); this.sparkline.sparklineData = temp; }; /** * To process sparkline DateTime data. * * @param {Object[]} data - The data array to process. * @param {string} x - The name of the x-field. * @param {string} y - The name of the y-field. * @returns {void} */ SparklineRenderer.prototype.processDateTime = function (data, x, y) { if (data === void 0) { data = this.sparkline.dataSource; } if (x === void 0) { x = this.sparkline.xName; } if (y === void 0) { y = this.sparkline.yName; } var temp = []; data.forEach(function (value) { var currentData = {}; currentData[x] = value[x].getTime(); currentData[y] = value[y]; temp.push(currentData); }); this.sparkline.sparklineData = temp; }; /** * To render sparkline series. * * @private * @returns {void} */ SparklineRenderer.prototype.renderSeries = function () { var _this = this; var spark = this.sparkline; this.clipId = spark.element.id + '_sparkline_clip_path'; this.drawAxis(); var argsData = { name: 'seriesRendering', cancel: false, lineWidth: spark.lineWidth, border: spark.border, fill: spark.fill, sparkline: spark }; var seriesRenderingSuccess = function (args) { if (!_this.visiblePoints || args.cancel) { return; } if (spark.type !== 'Pie' && spark.type !== 'WinLoss' && spark.rangeBandSettings.length) { var group = _this.sparkline.renderer.createGroup({ id: _this.sparkline.element.id + '_sparkline_rangeband_g' }); for (var i = 0; i < spark.rangeBandSettings.length; i++) { if ((spark.axisSettings.minY <= spark.rangeBandSettings[i].startRange) || (spark.axisSettings.maxY >= spark.rangeBandSettings[i].endRange)) { _this.rangeBand(spark.rangeBandSettings[i], group, i); } } _this.sparkline.svgObject.appendChild(group); } _this['render' + spark.type](_this.visiblePoints, args); _this.renderMarker(_this.visiblePoints); _this.renderLabel(_this.visiblePoints); }; seriesRenderingSuccess.bind(this); spark.trigger('seriesRendering', argsData, seriesRenderingSuccess); }; /** * To render a range band. * * @param {RangeBandSettingsModel} rangeBandSettings - The settings for the range band. * @param {Element} group - The group element to render the range band. * @param {number} index - The index of the range band. * @returns {void} */ SparklineRenderer.prototype.rangeBand = function (rangeBandSettings, group, index) { var model = this.sparkline; var height = (model.availableSize.height) - model.padding.top * 2; var width = (model.availableSize.width) - model.padding.left * 2; var stValue = rangeBandSettings.startRange; var edValue = rangeBandSettings.endRange; var stHeight = (height - ((height / this.unitY) * (stValue - this.min))) + model.padding.top; var edHeight = (height - ((height / this.unitY) * (edValue - this.min))) + model.padding.top; var color = rangeBandSettings.color || this.sparkline.sparkTheme.rangeBandColor; if (edHeight > (height + model.padding.top)) { edHeight = (height + model.padding.top); } else if (edHeight < (0 + model.padding.top)) { edHeight = (0 + model.padding.top); } if (stHeight > (height + model.padding.top)) { stHeight = (height + model.padding.top); } else if (stHeight < (0 + model.padding.top)) { stHeight = (0 + model.padding.top); } var path = 'M ' + (model.padding.left) + ' ' + stHeight + ' L ' + (width + (model.padding.left)) + ' ' + stHeight + ' L ' + (width + (model.padding.left)) + ' ' + edHeight + ' L ' + (model.padding.left) + ' ' + edHeight + ' Z '; var pathOption = { 'id': model.element.id + '_rangeBand_' + index, 'fill': color, 'opacity': rangeBandSettings.opacity, 'stroke': 'transparent', 'stroke-width': model.lineWidth, 'd': path, 'stroke-dasharray': '' }; drawPath(this.sparkline, pathOption, group); }; /** * To render line series. * * @param {SparkValues[]} points - The data points for the line series. * @param {ISeriesRenderingEventArgs} args - The rendering event arguments. * @returns {void} */ SparklineRenderer.prototype.renderLine = function (points, args) { var spark = this.sparkline; var g = this.sparkline.renderer.createGroup({ id: spark.element.id + '_sparkline_g', 'clip-path': 'url(#' + this.clipId + ')' }); var color = this.sparkline.fill; color = (this.sparkline.fill === '#00bdae' && this.sparkline.theme === 'Bootstrap4') ? this.sparkline.sparkTheme.axisLineColor : color; var pathOption = new PathOption(spark.element.id + '_sparkline_line', 'transparent', args.lineWidth, color, spark.opacity); var d = ''; for (var i = 0, len = points.length; i < len; i++) { if (i === 0) { d = 'M ' + points[0].x + ' ' + points[i].y + ' '; } d += 'L ' + points[i].x + ' ' + points[i].y + ' '; } pathOption.d = d; pathOption['aria-label'] = 'Line series with' + points.length + 'data points'; pathOption['tabindex'] = '0'; drawPath(this.sparkline, pathOption, g); this.sparkline.svgObject.appendChild(g); }; /** * To render pie series. * * @param {SparkValues[]} points - The data points for the pie series. * @param {ISeriesRenderingEventArgs} args - The rendering event arguments. * @returns {void} */ SparklineRenderer.prototype.renderPie = function (points, args) { var spark = this.sparkline; var height = spark.availableSize.height - (spark.padding.top + spark.padding.bottom); var width = spark.availableSize.width - (spark.padding.left + spark.padding.right); var area = (height <= width) ? height / 2 : width / 2; var X = spark.availableSize.width / 2; // center position of x var Y = spark.availableSize.height / 2; // center position of y var deg = 0; var stRad; var edRad; var stroke = args.border.color; var opacity = spark.opacity; var strokeWidth = args.border.width; var colors = (spark.palette.length) ? spark.palette : getSeriesColor(this.sparkline.theme); var group = this.sparkline.renderer.createGroup({ id: spark.element.id + '_sparkline_g' }); var low; var high; var locations = extend([], [], points); if (spark.highPointColor || spark.lowPointColor) { var pointsYvalues = locations.map(function (a) { return a.yVal; }); low = Math.min.apply(null, pointsYvalues); high = Math.max.apply(null, pointsYvalues); } this.negativePointIndexes = []; for (var i = 0, stDeg = 90, edDeg = void 0, flag = void 0; i < points.length; i++) { stDeg += deg; deg = points[i]['degree']; deg = (deg === 360 ? deg - 0.001 : deg); edDeg = stDeg + deg; stRad = (stDeg - 90) * Math.PI / 180.0; edRad = (edDeg - 90) * Math.PI / 180.0; points[i]['stAng'] = stRad; points[i]['endAng'] = edRad; flag = (deg < 180) ? '0' : '1'; var temp = points[i]['coordinates'] = { sX: X + (area * Math.cos(stRad)), sY: Y + (area * Math.sin(stRad)), eX: X + (area * Math.cos(edRad)), eY: Y + (area * Math.sin(edRad)) }; var pathArc = 'M ' + X + ' ' + Y + ' L ' + temp['eX'] + ' ' + temp['eY'] + ' A ' + area + ' ' + area + ' 0 ' + flag + ',0 ' + temp['sX'] + ' ' + temp['sY'] + ' Z'; var pathOption = { 'id': spark.element.id + '_sparkline_pie_' + i, 'opacity': opacity, 'fill': colors[i % colors.length], 'stroke': stroke, 'stroke-width': strokeWidth, 'd': pathArc, 'stroke-dasharray': '' }; this.getPieSpecialPoint(points[i], spark, pathOption, i, high, low, points.length); var pointArgs = this.triggerPointRender('pointRendering', i, pathOption.fill, { color: stroke, width: strokeWidth }); pathOption.fill = pointArgs.fill; pathOption.stroke = pointArgs.border.color; pathOption['stroke-width'] = pointArgs.border.width; if (!pointArgs.cancel) { var element = drawPath(this.sparkline, pathOption, group); element.setAttribute('role', 'img'); element.setAttribute('aria-label', spark.dataSource[i][spark.xName] + ' : ' + points[i].yVal); element.setAttribute('tabindex', i === 0 ? '0' : '-1'); element.style.outline = 'none'; } var diffRadian = edRad - stRad; var mid = { x: X + ((area / 2) * Math.cos(stRad + (diffRadian / 2))), y: Y + ((area / 2) * Math.sin(stRad + (diffRadian / 2))) }; points[i].location.x = mid.x; points[i].location.y = mid.y; } this.sparkline.svgObject.appendChild(group); }; /** * To get special point color and option for Pie series. * * @param {SparkValues} temp - The data point for the special point. * @param {Sparkline} spark - The sparkline instance. * @param {PathOption} option - The option for the special point. * @param {number} i - The index of the special point. * @param {number} high - The high value. * @param {number} low - The low value. * @param {number} length - The total number of data points. * @returns {void} */ SparklineRenderer.prototype.getPieSpecialPoint = function (temp, spark, option, i, high, low, length) { if (temp.yVal < 0 && spark.negativePointColor) { option.fill = spark.negativePointColor; this.negativePointIndexes.push(i); } if (i === 0 && spark.startPointColor) { option.fill = spark.startPointColor; this.startPointIndex = i; } else if ((i === (length - 1)) && spark.endPointColor) { option.fill = spark.endPointColor; this.endPointIndex = i; } if (temp.yVal === high && spark.highPointColor) { option.fill = spark.highPointColor; this.highPointIndex = i; } else if (temp.yVal === low && spark.lowPointColor) { option.fill = spark.lowPointColor; this.lowPointIndex = i; } }; /** * To render area series. * * @param {SparkValues[]} points - The data points for the area series. * @param {ISeriesRenderingEventArgs} args - The rendering event arguments. * @returns {void} */ SparklineRenderer.prototype.renderArea = function (points, args) { var spark = this.sparkline; var group = this.sparkline.renderer.createGroup({ id: spark.element.id + '_sparkline_g', 'clip-path': 'url(#' + this.clipId + ')' }); var pathOption = new PathOption(spark.element.id + '_sparkline_area', args.fill, 0, 'transparent', spark.opacity); var d = ''; var str = ''; for (var i = 0, len = points.length; i < len; i++) { if (i !== 0) { str += 'L ' + points[i].x + ' ' + points[i].y + ' '; } else { d = 'M ' + points[i].x + ' ' + this.axisHeight + ' '; str = 'M ' + points[i].x + ' ' + points[i].y + ' '; } d += 'L ' + points[i].x + ' ' + points[i].y + ' '; if (i === (len - 1)) { d += 'L ' + points[i].x + ' ' + this.axisHeight + ' Z'; } } pathOption.d = d; pathOption['aria-label'] = 'Area series with' + points.length + 'data points'; drawPath(this.sparkline, pathOption, group); pathOption = new PathOption(spark.element.id + '_sparkline_area_str', 'transparent', args.border.width, args.border.color, spark.opacity, '', str); drawPath(this.sparkline, pathOption, group); this.sparkline.svgObject.appendChild(group); }; /** * To render column series. * * @param {SparkValues[]} points - The data points for the column series. * @param {ISeriesRenderingEventArgs} args - The rendering event arguments. * @returns {void} */ SparklineRenderer.prototype.renderColumn = function (points, args) { var _this = this; var spark = this.sparkline; var locations = extend([], [], points); var group = this.sparkline.renderer.createGroup({ id: spark.element.id + '_sparkline_g', 'clip-path': 'url(#' + this.clipId + ')' }); var lowPos; var highPos; if (this.sparkline.highPointColor || this.sparkline.lowPointColor) { var pointsYPos = locations.map(function (a) { return a.markerPosition; }); highPos = Math.min.apply(null, pointsYPos); lowPos = Math.max.apply(null, pointsYPos); } var id = spark.element.id + '_sparkline_column_'; var rectOptions = new RectOption(id, '', args.border, spark.opacity, null); var temp; var len = points.length; this.negativePointIndexes = []; var colors = (spark.palette.length) ? spark.palette : getSeriesColor(this.sparkline.theme); var _loop_1 = function (i) { temp = points[i]; rectOptions.id = id + i; rectOptions.fill = spark.fill !== '#00bdae' ? spark.fill : colors[0]; rectOptions.rect = new Rect(temp.x, temp.y, temp.width, temp.height); this_1.getSpecialPoint(true, temp, spark, rectOptions, i, highPos, lowPos, len); temp.location.y = (temp.markerPosition <= this_1.axisHeight) ? temp.y : (temp.y + temp.height); temp.location.x = temp.x + (temp.width / 2); rectOptions.stroke = args.border.color ? (args.border.color) : rectOptions.fill; var pointArgs = { name: 'pointRendering', cancel: false, pointIndex: i, fill: rectOptions.fill, border: { color: rectOptions.stroke, width: args.border.width } }; this_1.sparkline.trigger('pointRendering', pointArgs, function () { temp = points[i]; rectOptions.id = id + i; rectOptions.rect = new Rect(temp.x, temp.y, temp.width, temp.height); _this.getSpecialPoint(true, temp, spark, rectOptions, i, highPos, lowPos, len); rectOptions.fill = pointArgs.fill; rectOptions.stroke = pointArgs.border.color; temp.location.y = (temp.markerPosition <= _this.axisHeight) ? temp.y : (temp.y + temp.height); rectOptions['stroke-width'] = pointArgs.border.width; temp.location.x = temp.x + (temp.width / 2); if (!pointArgs.cancel) { var element = drawRectangle(spark, rectOptions, group); element.setAttribute('role', 'img'); element.setAttribute('aria-label', spark.dataSource[i][spark.xName] + ' : ' + points[i].yVal); element.setAttribute('tabindex', i === 0 ? '0' : '-1'); element.style.outline = 'none'; group.appendChild(element); } }); }; var this_1 = this; for (var i = 0; i < len; i++) { _loop_1(i); } this.sparkline.svgObject.appendChild(group); }; /** * To render WinLoss series. * * @param {SparkValues[]} points - The data points for the winloss series. * @param {ISeriesRenderingEventArgs} args - The rendering event arguments. * @returns {void} */ SparklineRenderer.prototype.renderWinLoss = function (points, args) { var spark = this.sparkline; var group = this.sparkline.renderer.createGroup({ id: spark.element.id + '_sparkline_g', 'clip-path': 'url(#' + this.clipId + ')' }); var id = spark.element.id + '_sparkline_winloss_'; var options = new RectOption(id, '', args.border, spark.opacity, null); var temp; var len = points.length; var paletteLength = spark.palette.length; var colors = (spark.palette.length) ? spark.palette : getSeriesColor(this.sparkline.theme); for (var i = 0; i < len; i++) { temp = points[i]; options.id = id + i; options.fill = (paletteLength) ? spark.palette[i % paletteLength] : ((temp.yVal === this.axisValue) ? (this.sparkline.tiePointColor || '#a216f3') : ((temp.yVal > this.axisValue) ? args.fill || colors[i % colors.length] : (spark.negativePointColor || '#e20f07'))); options.stroke = (args.border.color) ? (args.border.color) : options.fill; options.rect = new Rect(temp.x, temp.y, temp.width, temp.height); temp.location.x = temp.x + (temp.width / 2); temp.location.y = (temp.yVal >= this.axisValue) ? (temp.y) : (temp.y + temp.height); var pointArgs = this.triggerPointRender('pointRendering', i, options.fill, { color: options.stroke, width: args.border.width }); options.fill = pointArgs.fill; options.stroke = pointArgs.border.color; options['stroke-width'] = pointArgs.border.width; if (!pointArgs.cancel) { var element = drawRectangle(spark, options, group); element.setAttribute('role', 'img'); element.setAttribute('aria-label', spark.dataSource[i][spark.xName] + ' : ' + points[i].yVal); element.setAttribute('tabindex', i === 0 ? '0' : '-1'); element.style.outline = 'none'; } } this.sparkline.svgObject.appendChild(group); }; SparklineRenderer.prototype.renderMarker = function (points) { var _this = this; var spark = this.sparkline; var marker = spark.markerSettings; if ((spark.type === 'Pie' || spark.type === 'WinLoss' || !marker.visible.length)) { return; } var locations = extend([], [], points); var group = this.sparkline.renderer.createGroup({ id: spark.element.id + '_sparkline_marker_g', 'clip-path': 'url(#' + this.clipId + ')' }); var temp; var id = spark.element.id + '_sparkline_marker_'; var option = new CircleOption('', marker.fill, marker.border, marker.opacity, 0, 0, marker.size / 2, ''); var highPos; var lowPos; var visible = marker.visible.join(); if ((visible.toLowerCase().indexOf('high') > -1) || (visible.toLowerCase().indexOf('low') > -1)) { var pointsYPos = locations.map(function (a) { return a.markerPosition; }); highPos = Math.min.apply(null, pointsYPos); lowPos = Math.max.apply(null, pointsYPos); } this.negativePointIndexes = []; var _loop_2 = function (i, length_1) { temp = points[i]; option.id = id + i; option.cx = temp.location.x; option.cy = temp.location.y; option.fill = marker.fill; var render = (visible.toLowerCase().indexOf('all') > -1); render = this_2.getSpecialPoint(render, temp, spark, option, i, highPos, lowPos, length_1, visible.toLowerCase()); option.stroke = marker.border.color || option.fill; var markerArgs = { name: 'markerRendering', cancel: false, border: { color: option.stroke, width: marker.border.width }, fill: option.fill, pointIndex: i, sparkline: this_2.sparkline, x: option.cx, y: option.cy, size: marker.size }; this_2.sparkline.trigger('markerRendering', markerArgs, function () { if (render && !markerArgs.cancel) { option.id = id + i; option.cx = markerArgs.x; option.cy = markerArgs.y; option.fill = markerArgs.fill; option.stroke = markerArgs.border.color; option['stroke-width'] = markerArgs.border.width; option.r = markerArgs.size / 2; var element = drawCircle(spark, option, group); element.setAttribute('role', 'img'); element.setAttribute('aria-label', spark.dataSource[i][spark.xName] + ' : ' + points[i].yVal); if ((_this.sparkline.type.indexOf('Line') > -1) || (_this.sparkline.type.indexOf('Area') > -1)) { element.setAttribute('tabindex', i === 0 ? '0' : '-1'); element.style.outline = 'none'; } group.appendChild(element); } }); }; var this_2 = this; for (var i = 0, length_1 = points.length; i < length_1; i++) { _loop_2(i, length_1); } this.sparkline.svgObject.appendChild(group); }; /** * To get special point color and option. * * @param {boolean} render - Indicates whether to render the special point. * @param {SparkValues} temp - The data point for the special point. * @param {Sparkline} spark - The sparkline instance. * @param {PathOption} option - The option for the special point. * @param {number} i - The index of the special point. * @param {number} highPos - The position of the high value. * @param {number} lowPos - The position of the low value. * @param {number} length - The total number of data points. * @param {string} visible - The visibility state of the special point. * @returns {boolean} - Indicates whether the special point is rendered. */ SparklineRenderer.prototype.getSpecialPoint = function (render, temp, spark, option, i, highPos, lowPos, length, visible) { if (visible === void 0) { visible = ''; } if (temp.markerPosition > this.axisHeight) { option.fill = spark.negativePointColor || option.fill; this.negativePointIndexes.push(i); render = render || (visible.indexOf('negative') > -1); } if (i === 0) { option.fill = spark.startPointColor || option.fill; this.startPointIndex = i; render = render || (visible.indexOf('start') > -1); } else if ((i === (length - 1))) { option.fill = spark.endPointColor || option.fill; this.endPointIndex = i; render = render || (visible.indexOf('end') > -1); } if (temp.markerPosition === highPos) { option.fill = spark.highPointColor || option.fill; this.highPointIndex = i; render = render || (visible.indexOf('high') > -1); } else if (temp.markerPosition === lowPos) { option.fill = spark.lowPointColor || option.fill; this.lowPointIndex = i; render = render || (visible.indexOf('low') > -1); } if (visible.indexOf('none') > -1) { render = false; } return render; }; /** * To render data label for sparkline. * * @param {SparkValues[]} points - The data points for the series datalabels. * @returns {void} */ SparklineRenderer.prototype.renderLabel = function (points) { var _this = this; var spark = this.sparkline; var dataLabel = spark.dataLabelSettings; var color = dataLabel.textStyle.color || spark.sparkTheme.dataLabelColor; if ((spark.type === 'WinLoss' || !dataLabel.visible.length)) { return; } var locations = extend([], [], points); var id = spark.element.id + '_sparkline_label_'; var group = this.sparkline.renderer.createGroup({ id: spark.element.id + '_sparkline_label_g', style: 'pointer-events: none;' }); group.setAttribute('aria-hidden', 'true'); var g; var temp; var textId = id + 'text_'; var rectId = id + 'rect_'; var option = new TextOption('', 0, 0, 'middle', '', 'middle'); var labelStyle = dataLabel.textStyle; var pointsYPos = locations.map(function (a) { return a.markerPosition; }); var highPos = Math.min.apply(null, pointsYPos); var lowPos = Math.max.apply(null, pointsYPos); var space = 1; var padding = (dataLabel.fill !== 'transparent' || dataLabel.border.width) ? 2 : 0; var size = measureText('sparkline_measure_text', labelStyle, this.sparkline.sparkTheme.dataLabelFont); var rectOptions = new RectOption('', dataLabel.fill, dataLabel.border, dataLabel.opacity, null); var edgeLabelOption; var _loop_3 = function (i, length_2) { temp = points[i]; option.id = textId + i; option.x = temp.location.x + dataLabel.offset.x; option.y = ((spark.type === 'Pie') ? temp.location.y : ((temp.markerPosition > this_3.axisHeight) ? (temp.location.y + (size.height / 2) + space + 2 + padding) : (temp.location.y - (size.height / 2) - space - padding))) + dataLabel.offset.y; option.text = (dataLabel.format !== '') ? this_3.formatter(dataLabel.format, this_3.sparkline.dataSource[i]) : temp.yVal.toString(); var labelArgs = { name: 'dataLabelRendering', cancel: false, border: dataLabel.border, fill: dataLabel.fill, pointIndex: i, sparkline: this_3.sparkline, x: option.x, y: option.y, text: option.text, color: color }; this_3.sparkline.trigger('dataLabelRendering', labelArgs, function () { size = measureText(labelArgs.text, labelStyle, _this.sparkline.sparkTheme.dataLabelFont); option.text = labelArgs.text; var renderLabel = (dataLabel.visible.join().toLowerCase().indexOf('all') > -1); renderLabel = _this.getLabelVisible(renderLabel, temp, i, dataLabel, length_2, highPos, lowPos); edgeLabelOption = _this.arrangeLabelPosition(dataLabel.edgeLabelMode, renderLabel, labelArgs.x, i, length_2, size, padding); if (renderLabel && !labelArgs.cancel && edgeLabelOption.render) { rectOptions.id = rectId + i; rectOptions.fill = labelArgs.fill; rectOptions.stroke = labelArgs.border.color; rectOptions['stroke-width'] = labelArgs.border.width; option.y = labelArgs.y; option.x = edgeLabelOption.x; rectOptions.rect = new Rect(option.x - ((size.width / 2) + padding), (option.y - padding - (size.height / 1.75)), size.width + (padding * 2), size.height + (padding * 2)); g = _this.sparkline.renderer.createGroup({ id: id + 'g' + i }); drawRectangle(spark, rectOptions, g); renderTextElement(option, labelStyle, labelArgs.color, g, _this.sparkline.sparkTheme.dataLabelFont); group.appendChild(g); } }); }; var this_3 = this; for (var i = 0, length_2 = points.length; i < length_2; i++) { _loop_3(i, length_2); } this.sparkline.svgObject.appendChild(group); }; SparklineRenderer.prototype.arrangeLabelPosition = function (edgeLabel, render, x, index, length, size, padding) { if (edgeLabel === 'None') { return { x: x, render: render }; } if (index === 0 && ((x - (size.width / 2) - padding) <= 0)) { if (edgeLabel === 'Hide') { render = false; } else { x = this.sparkline.padding.left + padding + (size.width / 2); } } else if (index === length - 1 && ((x + (size.width / 2) + padding) >= this.sparkline.availableSize.width)) { if (edgeLabel === 'Hide') { render = false; } else { x -= (size.width / 2 + padding); } } return { x: x, render: render }; }; /** * To get special point color and option. * * @param {boolean} render - Indicates whether to render the special point. * @param {SparkValues} temp - The data point for the special point. * @param {number} i - The index of the sparkline instance. * @param {SparklineDataLabelSettingsModel} label - The options for the special point. * @param {number} length - The total number of data points. * @param {number} highPos - The position of the high value. * @param {number} lowPos - The position of the low value. * @returns {boolean} - Indicates whether the special point is rendered. */ SparklineRenderer.prototype.getLabelVisible = function (render, temp, i, label, length, highPos, lowPos) { var labelVisible = label.visible.join().toLowerCase(); if (temp.markerPosition > this.axisHeight) { render = render || (labelVisible.indexOf('negative') > -1); } if (i === 0) { render = render || (labelVisible.indexOf('start') > -1); } else if ((i === (length - 1))) { render = render || (labelVisible.indexOf('end') > -1); } if (temp.markerPosition === highPos) { render = render || (labelVisible.indexOf('high') > -1); } else if (temp.markerPosition === lowPos) { render = render || (labelVisible.indexOf('low') > -1); } if (label.visible.join().toLowerCase().indexOf('none') > -1) { render = false; } return render; }; /** * To format text. * * @param {string} format - The format string to apply. * @param {object} data - The data object to format. * @returns {string} - The formatted text. */ SparklineRenderer.prototype.formatter = function (format, data) { if (isNullOrUndefined(format)) { return null; } var keys = Object.keys(data); for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) { var key = keys_1[_i]; format = format.split('${' + key + '}').join(data[key]); } return format; }; /** * To calculate min and max for x and y axis. * * @returns {void} */ SparklineRenderer.prototype.axisCalculation = function () { this.findRanges(this.sparkline.sparklineData); }; /** * To find x axis interval. * * @param {Object[]} data - The data points. * @param {string} x - The x-axis field name. * @returns {number} - The calculated interval. */ SparklineRenderer.prototype.getInterval = function (data, x) { var interval = 1; var x1 = data[0][x]; var x2 = isNullOrUndefined(data[1]) ? undefined : data[1][x]; if (!isNullOrUndefined(x1) && !isNullOrUndefined(x2)) { var temp = extend([], data); var validData_1 = []; temp.forEach(function (value) { if (!isNullOrUndefined(value[x])) { validData_1.push(value); } }); validData_1.sort(function (a, b) { if (isNullOrUndefined(a[x]) || isNullOrUndefined(b[x])) { return 0; } return a[x] - b[x]; }); validData_1 = (this.sparkline.enableRtl) ? validData_1.reverse() : validData_1; interval = validData_1[1][x] - validData_1[0][x]; } return interval; }; /** * To find x axis interval for padding. * * @param {Object[]} data - The data points. * @param {string} x - The x-axis field name. * @param {SparklineValueType} type - The type of sparkline value. * @param {number} delta - The delta values. * @returns {number} - The calculated x-axis interval for padding. */ SparklineRenderer.prototype.getPaddingInterval = function (data, x, type, delta) { var interval = 1; var size = this.sparkline.availableSize.height; var intervalCount = interval * data.length; intervalCount = Math.max((size * (intervalCount / 100)), 1); var niceInterval = delta / intervalCount; for (var _i = 0, _a = this.sparkline.intervalDivs; _i < _a.length; _i++) { var intervalVal = _a[_i]; var currentInterval = interval * intervalVal; if (intervalCount < (delta / currentInterval)) { break; } niceInterval = currentInterval; } return niceInterval; }; /** * To calculate axis ranges internally. * * @param {Object[]} data - The data points. * @returns {void} */ SparklineRenderer.prototype.findRanges = function (data) { var model = this.sparkline; var max; var min; var minX; var maxX; var maxPointsLength = data.length; var temp; var sumofValues = 0; var isNumericArray = Array.isArray(data) && typeof data[0] !== 'object'; if (isNumericArray) { if (model.type === 'Pie') { for (var i = 0; i < maxPointsLength; i++) { sumofValues += Math.abs(data[i]); } } else { max = Math.max.apply(null, data); min = Math.min.apply(null, data); minX = 0; maxX = maxPointsLength - 1; } } else { if (model.type === 'Pie') { for (var i = 0; i < maxPointsLength; i++) { sumofValues += Math.abs(data[i][model.yName]); } } else { if (isNullOrUndefined(data[0][model.xName])) { var x_1 = data.map(function (z) { return z[model.yName]; }); max = Math.max.apply(null, x_1); min = Math.min.apply(null, x_1); } else { temp = extend([], data); temp = temp.sort(function (a, b) { return a[model.yName] - b[model.yName]; }); max = temp[temp.length - 1][model.yName]; min = temp[0][model.yName]; } if (!isNullOrUndefined(data[0][model.xName])) { temp = temp.sort(function (a, b) { return a[model.xName] - b[model.xName]; }); temp = (this.sparkline.enableRtl) ? temp.reverse() : temp; maxX = temp[temp.length - 1][model.xName]; minX = temp[0][model.xName]; } else { minX = 0; maxX = maxPointsLength - 1; } } } var y2; var height; var width; var x1 = 0; var y1; var padding = model.padding; var point; var axis = model.axisSettings; var value = axis.value; if (model.type !== 'Pie') { this.maxLength = maxPointsLength; height = model.availableSize.height - (padding.bottom + padding.top); width = model.availableSize.width - (padding.left + padding.right); maxX = isNullOrUndefined(axis.maxX) ? maxX : axis.maxX; minX = isNullOrUndefined(axis.minX) ? minX : axis.minX; max = isNullOrUndefined(axis.maxY) ? max : axis.maxY; min = isNullOrUndefined(axis.minY) ? min : axis.minY; var color = axis.lineSettings.color || this.sparkline.sparkTheme.axisLineColor; var eventArgs = { name: 'axisRendering', cancel: false, sparkline: model, maxX: maxX, minX: minX, maxY: max, minY: min, value: axis.value, lineColor: color, lineWidth: axis.lineSettings.width }; model.trigger('axisRendering', eventArgs); if (eventArgs.cancel) { this.visiblePoints = []; return; } maxX = eventArgs.maxX; minX = eventArgs.minX; max = eventArgs.maxY; min = eventArgs.minY; value = this.axisValue = eventArgs.value; this.axisColor = eventArgs.lineColor; this.axisWidth = eventArgs.lineWidth; } var unitX = maxX - minX; var unitY = max - min; unitX = (unitX === 0) ? 1 : unitX; unitY = (unitY === 0) ? 1 : unitY; this.unitX = unitX; this.unitY = unitY; this.min = min; x1 = 0; y1 = height - ((height / unitY) * (-min)); y1 = (min < 0 && max <= 0) ? 0 : (min < 0 && max > 0) ? y1 : height; if (value >= min && value <= max) { y1 = height - Math.round(height * ((value - min) / this.unitY)); } this.axisHeight = y1 + padding.top; var percent; var x; var y; var visiblePoints = []; var delta = max - min; var interval = this.getInterval(data, model.xName); var interVal = this.getPaddingInterval(data, model.xName, model.valueType, delta); for (var i = 0; i < maxPointsLength; i++) { if (isNullOrUndefined(data[i][model.xName]) && isNullOrUndefined(data[i][model.yName]) && ((data[i][model.yName]) !== 0) && isNumericArray) { x = i; y = data[i]; } else if (isNullOrUndefined(data[i][model.xName])) { x = i; y = data[i][model.yName]; } else { x = data[i][model.xName]; y = data[i][model.yName]; } if (isNullOrUndefined(x) || isNullOrUndefined(y)) { continue; } if (model.type === 'Line' || model.type === 'Area') { y2 = (min !== max && maxPointsLength !== 1) ? height - Math.round(height * ((y - min) / this.unitY)) : padding.top; point = { x: (minX !== maxX) ? Math.round(width * ((x - minX) / this.unitX)) : width / 2, y: y2, markerPosition: y2 }; } else if (model.type === 'Column' || model.type === 'WinLoss') { var colWidth = width / (((maxX - minX) / interval) + 1); var calSpace = 0.5; var space = (calSpace * 2); //calspace is default space for column and winloss colWidth -= (space); x1 = (((x - minX) / interval) * (colWidth + space)) + (space / 2); if (model.type === 'WinLoss') { // win or gain column height half of the height , draw(zero) height factor var winLossFactor = 0.5; var drawHeightFactor = 40; y2 = (y > value) ? (height / 4) : (y < value) ? (height * winLossFactor) : ((height * winLossFactor) - (height / drawHeightFactor)); point = { x: x1, y: y2, height: (y !== value) ? (height / 4) : height / 20, width: colWidth, markerPosition: (y2 > y1) ? (y1 + Math.abs(y2 - y1)) : y2 }; } else { if (i === 0 && model.rangePadding !== 'None') { min -= model.rangePadding === 'Additional' ? (interVal + padding.top) : interVal; max += model.rangePadding === 'Additional' ? (interVal + padding.top) : interVal; unitX = maxX - minX; unitY = max - min; unitX = (unitX === 0) ? 1 : unitX; unitY = (unitY === 0) ? 1 : unitY; this.unitX = unitX; this.unitY = unitY; this.min = min; } var z = ((height / this.unitY) * (y - min)); var z1 = (y === min && y > value) ? ((maxPointsLength !== 1 && this.unitY !== 1) ? (height / this.unitY) * (min / 2) : (z | 1)) : (y === max && y < value && maxPointsLength !== 1 && this.unitY !== 1) ? (height / this.unitY) * (-max / 2) : z; y2 = Math.abs(height - z1); point = { x: x1, y: (y2 > y1) ? y1 : y2, height: Math.abs(y2 - y1), width: colWidth, markerPosition: (y2 > y1) ? (y1 + Math.abs(y2 - y1)) : y2 }; } } else if (model.type === 'Pie') { percent = (Math.abs(y) / sumofValues) * 100; point = { percent: percent, degree: ((Math.abs(y) / sumofValues) * 360) }; } if (model.type !== 'Pie') { point.x += padding.left; point.y += padding.top; } if (model.type !== 'WinLoss') { point.markerPosition += padding.top; } point.location = { x: point.x, y: point.y }; point.xVal = x; point.yVal = y; visiblePoints.push(point); } visiblePoints.sort(function (a, b) { return a.x - b.x; }); this.visiblePoints = visiblePoints; }; /** * To render the sparkline axis. * * @returns {void} */ SparklineRenderer.prototype.drawAxis = function () { var spark = this.sparkline; var height = this.axisHeight; if ((spark.type !== 'WinLoss') && (spark.type !== 'Pie') && spark.axisSettings.lineSettings.visible) { var xAxis = { 'id': spark.element.id + '_Sparkline_XAxis', 'x1': spark.padding.left, 'y1': height, 'x2': spark.availableSize.width - spark.padding.right, 'y2': height, 'stroke': this.axisColor, 'opacity': spark.axisSettings.lineSettings.opacity, 'stroke-dasharray': spark.axisSettings.lineSettings.dashArray, 'stroke-width': this.axisWidth, 'clip-path': 'url(#' + this.clipId + ')' }; spark.svgObject.appendChild(spark.renderer.drawLine(xAxis)); } }; /** * To trigger point render event. * * @param {string} name - The name of the data point. * @param {number} i - The index of the data point. * @param {string} fill - The fill color of the data point. * @param {SparklineBorderModel} border - The border settings of the data point. * @returns {ISparklinePointEventArgs} - The event arguments for the point render event. */ SparklineRenderer.prototype.triggerPointRender = function (name, i, fill, border) { var args = { name: name, cancel: false, border: border, fill: fill, sparkline: this.sparkline, pointIndex: i }; this.sparkline.trigger(name, args); return args; }; return SparklineRenderer; }()); export { SparklineRenderer };