UNPKG

@syncfusion/ej2-spreadsheet

Version:

Feature-rich JavaScript Spreadsheet (Excel) control with built-in support for selection, editing, formatting, importing and exporting to Excel

986 lines 98 kB
import { getSheetIndex, isHiddenRow, getCell, setCell, getSheet } from '../../workbook/index'; import { initiateChart, getRangeIndexes, isNumber, getSheetIndexFromAddress } from '../../workbook/index'; import { refreshChartCellOnInit } from '../../workbook/index'; import { overlay, locale, refreshChartCellObj, getRowIdxFromClientY, getColIdxFromClientX, deleteChart, dialog, overlayEleSize, undoRedoForChartDesign, refreshChartCellModel } from '../common/index'; import { completeAction, clearChartBorder, focusBorder } from '../common/index'; import { Chart, ColumnSeries, Category, StackingColumnSeries, BarSeries, DateTime } from '@syncfusion/ej2-charts'; import { AreaSeries, StackingAreaSeries, AccumulationChart, Tooltip } from '@syncfusion/ej2-charts'; import { Legend, StackingBarSeries, LineSeries, StackingLineSeries, ScatterSeries } from '@syncfusion/ej2-charts'; import { AccumulationLegend, PieSeries, AccumulationTooltip, AccumulationDataLabel } from '@syncfusion/ej2-charts'; import { isNullOrUndefined, getComponent, closest, detach, isUndefined, getUniqueID } from '@syncfusion/ej2-base'; import { isCustomDateTime, getAutoDetectFormatParser, calculateFormula, checkRange, inRange } from '../../workbook/index'; import { refreshChart, deleteChartColl, getFormattedCellObject, setChart, getCellAddress, skipHiddenIdx, addDPRValue, dateToInt } from '../../workbook/common/index'; import { insertChart, chartRangeSelection, chartDesignTab, removeDesignChart, insertDesignChart, getUpdateUsingRaf, focus } from '../common/index'; import { DataLabel } from '@syncfusion/ej2-charts'; import { isHiddenCol, beginAction } from '../../workbook/index'; Chart.Inject(ColumnSeries, LineSeries, BarSeries, AreaSeries, StackingColumnSeries, StackingLineSeries, StackingBarSeries, ScatterSeries); Chart.Inject(StackingAreaSeries, Category, Legend, Tooltip, DataLabel, DateTime); AccumulationChart.Inject(PieSeries, AccumulationTooltip, AccumulationDataLabel, AccumulationLegend); /** * Represents Chart support for Spreadsheet. */ var SpreadsheetChart = /** @class */ (function () { /** * Constructor for the Spreadsheet Chart module. * * @param {Spreadsheet} parent - Constructor for the Spreadsheet Chart module. */ function SpreadsheetChart(parent) { this.parent = parent; this.addEventListener(); } /** * Adding event listener for success and failure * * @returns {void} - Adding event listener for success and failure */ SpreadsheetChart.prototype.addEventListener = function () { this.parent.on(initiateChart, this.initiateChartHandler, this); this.parent.on(refreshChartCellObj, this.refreshChartCellObj, this); this.parent.on(refreshChartCellModel, this.refreshChartCellModel, this); this.parent.on(refreshChartCellOnInit, this.refreshChartCellObj, this); this.parent.on(deleteChart, this.deleteChart, this); this.parent.on(clearChartBorder, this.clearBorder, this); this.parent.on(insertChart, this.insertChartHandler, this); this.parent.on(chartRangeSelection, this.chartRangeHandler, this); this.parent.on(chartDesignTab, this.chartDesignTabHandler, this); this.parent.on(undoRedoForChartDesign, this.undoRedoForChartDesign, this); this.parent.on(refreshChart, this.refreshChartData, this); }; SpreadsheetChart.prototype.insertChartHandler = function (args) { var _this = this; var chartType = 'Column'; var markerVisible = false; switch (args.id) { case 'clusteredColumn': chartType = 'Column'; break; case 'stackedColumn': chartType = 'StackingColumn'; break; case 'stackedColumn100': chartType = 'StackingColumn100'; break; case 'clusteredBar': chartType = 'Bar'; break; case 'stackedBar': chartType = 'StackingBar'; break; case 'stackedBar100': chartType = 'StackingBar100'; break; case 'area': chartType = 'Area'; break; case 'stackedArea': chartType = 'StackingArea'; break; case 'stackedArea100': chartType = 'StackingArea100'; break; case 'line': chartType = 'Line'; break; case 'lineMarker': chartType = 'Line'; markerVisible = true; break; case 'stackedLine': chartType = 'StackingLine'; break; case 'stackedLineMarker': chartType = 'StackingLine'; markerVisible = true; break; case 'stackedLine100': chartType = 'StackingLine100'; break; case 'stackedLine100Marker': chartType = 'StackingLine100'; markerVisible = true; break; case 'pie': chartType = 'Pie'; break; case 'doughnut': chartType = 'Doughnut'; break; // case 'radar': // chartType = ; // break; // case 'radar_markers': // chartType = 'Column'; // break; case 'scatter': chartType = 'Scatter'; break; } var chart = [{ type: chartType, markerSettings: { visible: markerVisible, isFilled: true } }]; if (args.isChart) { this.parent.notify(setChart, { chart: chart }); getUpdateUsingRaf(function () { return focus(_this.parent.element); }); } else { this.parent.notify(chartDesignTab, { chartType: chartType, triggerEvent: true, markerVisible: markerVisible }); } }; SpreadsheetChart.prototype.chartRangeHandler = function () { var overlayEle = document.querySelector('.e-datavisualization-chart.e-ss-overlay-active'); if (overlayEle) { var chartId = overlayEle.getElementsByClassName('e-control')[0].id; var chartColl = this.parent.chartColl; var chartCollLen = chartColl.length; for (var idx = 0; idx < chartCollLen; idx++) { var chartEle = document.getElementById(chartColl[idx].id); if (overlayEle && chartEle && chartColl[idx].id === chartId) { this.initiateChartHandler({ option: chartColl[idx], isRefresh: true }); } } } }; SpreadsheetChart.prototype.refreshChartData = function (args) { if (!this.parent.chartColl || !this.parent.chartColl.length) { return; } var chart; var sheetName; var range; var insideRange; var chartEle; var chartObj; for (var i = 0, len = this.parent.chartColl.length; i < len; i++) { chart = this.parent.chartColl[i]; if (chart.range.includes('!')) { sheetName = chart.range.substring(0, chart.range.lastIndexOf('!')); if (this.parent.activeSheetIndex !== getSheetIndex(this.parent, sheetName)) { continue; } range = chart.range.substring(chart.range.lastIndexOf('!') + 1); } else { range = chart.range; } if (args.viewportIndexes) { for (var idx = 0; idx < args.viewportIndexes.length; idx++) { if (checkRange([args.viewportIndexes[idx]], range)) { insideRange = true; break; } } } else { insideRange = args.range ? checkRange([args.range], range) : (args.showHide ? this.inRowColumnRange(getRangeIndexes(range), args.rIdx, args.showHide) : inRange(getRangeIndexes(range), args.rIdx, args.cIdx)); } if (insideRange || (args.isSelectAll && !args.isRefreshChart)) { chartEle = this.parent.element.querySelector('.' + chart.id); if (chartEle) { chartObj = getComponent(chartEle, 'chart') || getComponent(chartEle, 'accumulationchart'); if (chartObj) { chartObj.series = this.initiateChartHandler({ option: chart, isRefresh: true }); chartObj.refresh(); } } } } }; SpreadsheetChart.prototype.inRowColumnRange = function (range, index, showHide) { return showHide === 'rows' ? index >= range[0] && index <= range[2] : index >= range[1] && index <= range[3]; }; SpreadsheetChart.prototype.refreshChartCellModel = function (args) { for (var i = 0, len = args.prevChartIndexes.length; i < len; i++) { var chart = args.prevChartIndexes[i].chart; var prevRowIdx = args.prevChartIndexes[i].chartRowIdx; var prevColIdx = args.prevChartIndexes[i].chartColIdx; var currentRowIdx = args.currentChartIndexes[i].chartRowIdx; var currentColIdx = args.currentChartIndexes[i].chartColIdx; var eventArgs = { prevTop: chart.top, prevLeft: chart.left, prevRowIdx: prevRowIdx, prevColIdx: prevColIdx, prevHeight: chart.height, prevWidth: chart.width, currentTop: chart.top, currentLeft: chart.left, currentRowIdx: currentRowIdx, currentColIdx: currentColIdx, currentHeight: chart.height, currentWidth: chart.width, id: chart.id, requestType: 'chartRefreshOnFilter' }; this.parent.notify(refreshChartCellObj, eventArgs); } }; SpreadsheetChart.prototype.refreshChartCellObj = function (args) { var sheetIndex = isUndefined(args.sheetIdx) ? this.parent.activeSheetIndex : args.sheetIdx; var sheet = getSheet(this.parent, sheetIndex); var prevCellObj = getCell(args.prevRowIdx, args.prevColIdx, sheet); var currCellObj = getCell(args.currentRowIdx, args.currentColIdx, sheet); var prevCellChart = prevCellObj ? prevCellObj.chart : []; var prevChartObj; var currChartObj; var prevCellChartLen = (prevCellChart && prevCellChart.length) ? prevCellChart.length : 0; if (prevCellChartLen) { for (var i = 0; i < prevCellChartLen; i++) { if (prevCellChart[i].id === args.id.split('_overlay')[0]) { prevChartObj = prevCellChart[i]; prevChartObj.height = args.currentHeight; prevChartObj.width = args.currentWidth; prevChartObj.top = args.currentTop; prevChartObj.left = args.currentLeft; prevChartObj.address = [args.currentRowIdx, args.currentColIdx]; prevCellChart.splice(i, 1); i--; prevCellChartLen--; for (var idx = 0, chartCollLen = this.parent.chartColl.length; idx < chartCollLen; idx++) { if (prevChartObj.id === this.parent.chartColl[idx].id) { prevChartObj.height = args.currentHeight; this.parent.chartColl[idx].width = args.currentWidth; this.parent.chartColl[idx].height = args.currentHeight; this.parent.chartColl[idx].top = args.currentTop; this.parent.chartColl[idx].left = args.currentLeft; this.parent.chartColl[idx].address = prevChartObj.address; } } } } if (currCellObj && currCellObj.chart) { currChartObj = currCellObj.chart; if (prevChartObj) { currChartObj.push(prevChartObj); } } if (currChartObj) { setCell(args.currentRowIdx, args.currentColIdx, sheet, { chart: currChartObj }, true); } else { setCell(args.currentRowIdx, args.currentColIdx, sheet, { chart: [prevChartObj] }, true); } if (args.requestType === 'chartRefresh' && !args.isUndoRedo) { var eventArgs = { requestType: 'chartRefresh', currentRowIdx: args.currentRowIdx, currentColIdx: args.currentColIdx, currentWidth: args.currentWidth, prevHeight: args.prevHeight, prevWidth: args.prevWidth, prevRowIdx: args.prevRowIdx, prevColIdx: args.prevColIdx, prevTop: args.prevTop, prevLeft: args.prevLeft, currentTop: args.currentTop, currentLeft: args.currentLeft, currentHeight: args.currentHeight, id: args.id, sheetIdx: sheetIndex }; this.parent.notify('actionComplete', { eventArgs: eventArgs, action: 'chartRefresh' }); } } if (args.isUndoRedo && sheetIndex === this.parent.activeSheetIndex) { var overlayEle = document.getElementById(args.id); if (overlayEle) { overlayEle.style.height = args.currentHeight + "px"; overlayEle.style.width = args.currentWidth + "px"; var frozenRow = this.parent.frozenRowCount(sheet); var frozenCol = this.parent.frozenColCount(sheet); if (frozenRow || frozenCol) { if (args.currentRowIdx < frozenRow || args.currentColIdx < frozenCol) { this.parent.element.querySelector('#' + this.parent.element.id + '_sheet').appendChild(overlayEle); } else { this.parent.getMainContent().appendChild(overlayEle); } this.parent.serviceLocator.getService(overlay).adjustFreezePaneSize({ top: args.currentTop, left: args.currentLeft }, overlayEle, getCellAddress(args.currentRowIdx, args.currentColIdx)); var chartEle = overlayEle.querySelector('.e-chart'); if (chartEle) { focus(chartEle); } } else { overlayEle.style.top = args.currentTop + "px"; overlayEle.style.left = args.currentLeft + "px"; } } } }; SpreadsheetChart.prototype.processChartRange = function (range, dataSheetIdx, opt) { var _this = this; var xRange; var yRange; var lRange; var isDateTimeFormat; var isDateTime; var minr = range[0]; var minc = range[1]; var maxr = range[2]; var maxc = range[3]; var isSingleRow = minr === maxr; var isSingleCol = minc === maxc; var sheet = getSheet(this.parent, dataSheetIdx); var autoDetectFormatFn = getAutoDetectFormatParser(this.parent); var getPropertyValue = function (rIdx, cIdx, isFirstCol, checkDateTime) { var cell = getCell(rIdx, cIdx, sheet); if (cell) { if (cell.formula && isNullOrUndefined(cell.value)) { _this.parent.notify(calculateFormula, { cell: cell, rowIdx: rIdx, colIdx: cIdx, sheetIndex: dataSheetIdx }); } var value = void 0; if (cell.format) { var formatObj = { value: cell.value, format: cell.format, formattedText: cell.value, cell: cell, rowIndex: rIdx, colIndex: cIdx }; _this.parent.notify(getFormattedCellObject, formatObj); var isNum = isNumber(cell.value); if (isNum && !isCustomDateTime(cell.format, true, null, true)) { value = Number(cell.value); } else { if (checkDateTime && isNum) { isDateTimeFormat = true; } else if (isFirstCol && isNum) { isDateTime = true; } value = formatObj.formattedText && formatObj.formattedText.toString(); } } else { autoDetectFormatFn(cell); value = cell.value; } return isNullOrUndefined(value) ? '' : value; } else { return ''; } }; var trVal = sheet ? getPropertyValue(minr, maxc, false, true) : ''; var blVal = sheet ? getPropertyValue(maxr, minc, true) : ''; var tlVal = sheet ? getPropertyValue(minr, minc, true) : ''; var isStringSeries = false; if (!isNumber(blVal) || !tlVal) { isStringSeries = true; } if ((isNullOrUndefined(tlVal) || (opt.type === 'Scatter' && !opt.isSeriesInRows)) && !isSingleRow && !isSingleCol) { var startMinRow = skipHiddenIdx(sheet, minr + 1, true); var startMinCol = skipHiddenIdx(sheet, minc + 1, true, 'columns'); xRange = [startMinRow, minc, maxr, minc]; yRange = [startMinRow, startMinCol, maxr, maxc]; lRange = [minr, startMinCol, minr, maxc]; } else if (!isNullOrUndefined(blVal) && isStringSeries && !isSingleRow && !isSingleCol && !isDateTimeFormat) { var startMinCol = skipHiddenIdx(sheet, minc + 1, true, 'columns'); if (!isNullOrUndefined(trVal) && (!isNumber(trVal) || !tlVal)) { var startMinRow = skipHiddenIdx(sheet, minr + 1, true); xRange = [startMinRow, minc, maxr, minc]; yRange = [startMinRow, startMinCol, maxr, maxc]; lRange = [minr, startMinCol, minr, maxc]; } else { xRange = [minr, minc, maxr, minc]; yRange = [minr, startMinCol, maxr, maxc]; } } else { yRange = [minr, minc, maxr, maxc]; if ((!isNullOrUndefined(trVal) && !isNumber(trVal) && !isDateTimeFormat)) { lRange = [minr, minc, minr, maxc]; if (!isSingleRow) { yRange[0] = skipHiddenIdx(sheet, yRange[0] + 1, true); } } else if ((isSingleRow || isSingleCol) && isNullOrUndefined(tlVal)) { lRange = [minr, minc, minr, maxc]; if (isSingleRow) { yRange[1] = skipHiddenIdx(sheet, yRange[1] + 1, true, 'columns'); lRange[3] = lRange[1]; } else { yRange[0] = skipHiddenIdx(sheet, yRange[0] + 1, true); } } } return { xRange: xRange, yRange: yRange, lRange: lRange, isStringSeries: isStringSeries, isDateTime: isDateTime }; }; SpreadsheetChart.prototype.getRangeData = function (options) { var sheet = options.sheet; if (!options.range) { options.range = getRangeIndexes(sheet.selectedRange); } else if (typeof (options.range) === 'string') { options.range = getRangeIndexes(options.range); } var rangeData = []; var cIdx; var formatArgs; var rIdx = options.range[0]; var autoDetectFormatFn = options.isYvalue && getAutoDetectFormatParser(this.parent); while (rIdx <= options.range[2]) { if (isHiddenRow(sheet, rIdx)) { rIdx++; continue; } cIdx = options.range[1]; while (cIdx <= options.range[3]) { if (isHiddenCol(sheet, cIdx)) { cIdx++; continue; } var cell = getCell(rIdx, cIdx, sheet, false, true); if (cell.formula && isNullOrUndefined(cell.value)) { this.parent.notify(calculateFormula, { cell: cell, rowIdx: rIdx, colIdx: cIdx, sheetIndex: options.sheetIdx }); } if (options.isYvalue) { autoDetectFormatFn(cell); } var rObj = { value: cell.value || (cell.value === 0 ? 0 : null) }; if (cell.format) { formatArgs = { formattedText: cell.value, value: cell.value, format: cell.format, cell: cell, skipFormatCheck: true, checkDate: true }; this.parent.notify(getFormattedCellObject, formatArgs); if (options.isYvalue) { if (isNumber(cell.value)) { rObj.value = Number(cell.value); rObj.displayText = formatArgs.formattedText ? formatArgs.formattedText.toString() : ''; } else { rObj.displayText = rObj.value === null ? '' : this.parent.getDisplayText({ format: cell.format, value: '0' }); rObj.value = 0; } } else { if (options.isScatter && !options.isDateTime && isNumber(cell.value)) { rObj.value = Number(cell.value); } else if (options.isDateFormat && isNumber(cell.value)) { rObj.value = formatArgs.dateObj ? formatArgs.dateObj : null; } else { rObj.value = formatArgs.formattedText ? formatArgs.formattedText.toString() : null; } } } else if (options.isYvalue) { if (isNumber(rObj.value)) { rObj.displayText = rObj.value.toString(); rObj.value = Number(rObj.value); } else { rObj.displayText = rObj.value === null ? '' : '0'; rObj.value = 0; } } rangeData.push(rObj); cIdx++; } rIdx++; } return rangeData; }; SpreadsheetChart.prototype.toArrayData = function (args) { var prop = 'value'; var obj; var i = 0; var temp = []; while (i < args.length) { obj = args[i]; if (Object.keys(obj).length) { if (prop in obj) { temp.push(obj["" + prop]); } } else { temp.push(''); } i++; } return temp; }; SpreadsheetChart.prototype.getVirtualXValues = function (limit) { var i = 1; var arr = []; while (i < limit) { arr.push(i.toString()); i++; } return arr; }; SpreadsheetChart.prototype.isDateFormattedRange = function (range, sheet) { for (var col = range[1]; col <= range[3]; col++) { if (isHiddenCol(sheet, col)) { continue; } for (var row = range[0]; row <= range[2]; row++) { if (isHiddenRow(sheet, row)) { continue; } var cell = getCell(row, col, sheet); if (!cell || !cell.format || (cell.value && !isNumber(cell.value)) || !isCustomDateTime(cell.format, false)) { return false; } } } return true; }; SpreadsheetChart.prototype.processChartSeries = function (options, sheetIndex, xRange, yRange, lRange, isDateTime, skipDateSeries) { options = options || {}; var seriesName; var xValue; var lValue; var diff; var pArr; var pObj = {}; var j; var i = 0; var yInc = 0; var sArr = []; var isDateFormat; var minDate; var maxDate; sheetIndex = isNullOrUndefined(sheetIndex) ? this.parent.activeSheetIndex : sheetIndex; var sheet = getSheet(this.parent, sheetIndex); var isScatter = options && options.type === 'Scatter'; var isAccChart = options && (options.type === 'Pie' || options.type === 'Doughnut'); var dataLabel = { name: 'displayText' }; var isPrint = this.parent.isPrintingProcessing; var rDiff = ((yRange[2] - yRange[0]) + 1) - this.parent.hiddenCount(yRange[0], yRange[2], 'rows', sheet); var cDiff = ((yRange[3] - yRange[1]) + 1) - this.parent.hiddenCount(yRange[1], yRange[3], 'columns', sheet); var yValue = this.getRangeData({ range: yRange, sheet: sheet, isYvalue: true, sheetIdx: sheetIndex }); if (options.isSeriesInRows) { xValue = lRange ? this.toArrayData(this.getRangeData({ range: lRange, sheet: sheet, isScatter: isScatter, isDateTime: isDateTime })) : this.getVirtualXValues(cDiff + 1); if (xRange) { lValue = this.toArrayData(this.getRangeData({ range: xRange, sheet: sheet })); } diff = rDiff; } else { if (xRange) { isDateFormat = !options.skipDateInterpolation && !skipDateSeries && !isAccChart && this.isDateFormattedRange(xRange, sheet); xValue = this.toArrayData(this.getRangeData({ range: xRange, sheet: sheet, isScatter: isScatter, isDateTime: isDateTime, isDateFormat: isDateFormat })); if (isDateFormat) { minDate = new Date(8640000000000000); maxDate = new Date(-8640000000000000); } } else { xValue = this.getVirtualXValues(rDiff + 1); } if (lRange) { lValue = this.toArrayData(this.getRangeData({ range: lRange, sheet: sheet })); } diff = cDiff; } var len = xValue.length; var inc = options.isSeriesInRows ? 1 : diff; if (!isNullOrUndefined(options.dataLabelSettings)) { dataLabel.visible = options.dataLabelSettings.visible; dataLabel.position = options.dataLabelSettings.position; } while (i < diff) { j = 0; pArr = []; yInc = options.isSeriesInRows ? yInc : i; while (j < len) { if (isDateFormat) { if (isNullOrUndefined(xValue[j])) { yInc += inc; j++; continue; } else { var dateValue = xValue[j]; if (dateValue < minDate) { minDate = dateValue; } if (dateValue > maxDate) { maxDate = dateValue; } } } if (isNullOrUndefined(xValue[j])) { xValue[j] = getUniqueID('spread-chart-empty-label-'); } pArr.push({ x: xValue[j], y: yValue[yInc].value, displayText: yValue[yInc].displayText }); yInc += inc; j++; } if (lValue && lValue.length > 0) { seriesName = lValue[i]; } else { seriesName = options.type === 'Scatter' ? ('series' + (i + 1)) : ('series' + i); } seriesName = isNullOrUndefined(seriesName) ? '' : seriesName.toString(); if (options.type) { var type = options.type; if (type === 'Line' || type === 'StackingLine' || type === 'StackingLine100') { pObj = { dataSource: pArr, type: options.type, xName: 'x', yName: 'y', name: seriesName, animation: { enable: !isPrint }, tooltipMappingName: 'displayText', marker: options.markerSettings ? { visible: options.markerSettings.visible, width: options.markerSettings.size, height: options.markerSettings.size, shape: options.markerSettings.shape, dataLabel: dataLabel, isFilled: options.markerSettings.isFilled, border: options.markerSettings.border, fill: options.markerSettings.isFilled ? options.markerSettings.fill : null } : { dataLabel: dataLabel } }; } else if (type === 'Scatter') { pObj = { dataSource: pArr, type: options.type, xName: 'x', yName: 'y', name: seriesName, tooltipMappingName: 'displayText', animation: { enable: !isPrint }, marker: { visible: false, width: 12, height: 12, shape: 'Circle', dataLabel: dataLabel } }; } else if (type === 'Pie' || type === 'Doughnut') { pObj = { dataSource: pArr, radius: '100%', xName: 'x', yName: 'y', innerRadius: options.type === 'Pie' ? '0%' : '40%', dataLabel: { visible: !!dataLabel.visible, position: dataLabel.position === 'Outer' ? 'Outside' : 'Inside', name: 'displayText', font: { fontWeight: '600' } }, animation: { enable: !isPrint }, tooltipMappingName: 'displayText' }; } else { pObj = { dataSource: pArr, type: options.type, xName: 'x', yName: 'y', animation: { enable: !isPrint }, name: seriesName, marker: { dataLabel: dataLabel }, tooltipMappingName: 'displayText' }; } } sArr.push(pObj); i++; } if (minDate && maxDate && minDate === maxDate) { return this.processChartSeries(options, sheetIndex, xRange, yRange, lRange, isDateTime, true); } var result; if (options.type) { result = { series: sArr, xRange: options.isSeriesInRows ? lRange : xRange, yRange: yRange, lRange: options.isSeriesInRows ? xRange : lRange, isDateFormat: isDateFormat, minDate: minDate, maxDate: maxDate }; } return result; }; SpreadsheetChart.prototype.getAxisFormat = function (range, sheet) { var format = ''; if (!isNullOrUndefined(range)) { var cell = getCell(range[0], range[1], sheet); if (cell && cell.format) { format = cell.format; } } return format; }; SpreadsheetChart.prototype.focusChartRange = function (xRange, yRange, lRange) { var border = ['e-rcborderright', 'e-rcborderbottom', 'e-vcborderright', 'e-vcborderbottom', 'e-bcborderright', 'e-bcborderbottom']; this.clearBorder(); var range; var sheet = this.parent.getActiveSheet(); var isFreezePane = !!(sheet.frozenRows || sheet.frozenColumns); if (lRange) { if (isFreezePane) { range = lRange; } else { this.parent.notify(focusBorder, { startcell: { rowIndex: lRange[0], colIndex: lRange[1] }, endcell: { rowIndex: lRange[2], colIndex: lRange[3] }, classes: [border[0], border[1]] }); } } if (xRange) { if (isFreezePane) { if (range) { range[0] = Math.min(lRange[0], xRange[0]); range[1] = Math.min(lRange[1], xRange[1]); range[2] = Math.max(lRange[2], xRange[2]); range[3] = Math.max(lRange[3], xRange[3]); } else { range = xRange; } } else { this.parent.notify(focusBorder, { startcell: { rowIndex: xRange[0], colIndex: xRange[1] }, endcell: { rowIndex: xRange[2], colIndex: xRange[3] }, classes: [border[2], border[3]] }); } } if (isFreezePane && range) { this.parent.notify(focusBorder, { startcell: { rowIndex: Math.min(range[0], yRange[0]), colIndex: Math.min(range[1], yRange[1]) }, endcell: { rowIndex: Math.max(range[2], yRange[2]), colIndex: Math.max(range[3], yRange[3]) }, classes: [border[4], border[5]] }); } else { this.parent.notify(focusBorder, { startcell: { rowIndex: yRange[0], colIndex: yRange[1] }, endcell: { rowIndex: yRange[2], colIndex: yRange[3] }, classes: [border[4], border[5]] }); } }; SpreadsheetChart.prototype.clearBorder = function () { var sheet = this.parent.getActiveSheet(); if (sheet.frozenColumns || sheet.frozenRows) { var chartIndicator = [].slice.call(this.parent.element.getElementsByClassName('e-chart-range')); chartIndicator.forEach(function (indicator) { detach(indicator); }); return; } var mainCont = this.parent.getMainContent(); var border = ['e-rcborderright', 'e-rcborderbottom', 'e-vcborderright', 'e-vcborderbottom', 'e-bcborderright', 'e-bcborderbottom']; for (var borderIdx = 0, borderLen = border.length; borderIdx < borderLen; borderIdx++) { var eleColl = mainCont.querySelectorAll('.' + border[borderIdx]); for (var tdIdx = 0, eleCollLen = eleColl.length; tdIdx < eleCollLen; tdIdx++) { var td = eleColl[tdIdx]; td.classList.remove(border[borderIdx]); } } }; SpreadsheetChart.prototype.initiateChartHandler = function (argsOpt) { var _this = this; var isRangeSelect = isNullOrUndefined(argsOpt.isInitCell) ? true : !argsOpt.isInitCell; argsOpt.triggerEvent = isNullOrUndefined(argsOpt.triggerEvent) ? true : argsOpt.triggerEvent; argsOpt.isRefresh = isNullOrUndefined(argsOpt.isRefresh) ? false : argsOpt.isRefresh; var activeSheetIdx = this.parent.activeSheetIndex; var chart = argsOpt.option; var sheetIdx = (chart.range && chart.range.lastIndexOf('!') > 0) ? getSheetIndex(this.parent, chart.range.substring(0, chart.range.lastIndexOf('!'))) : activeSheetIdx; var sheet = getSheet(this.parent, sheetIdx); var range = chart.range ? chart.range : this.parent.getActiveSheet().selectedRange; var rangeIdx = getRangeIndexes(range); var options = {}; var isRowLesser; var seriesModel; var eventArgs; var overlayEleRange = !isNullOrUndefined(argsOpt.isInitCell) && argsOpt.isInitCell ? argsOpt.range : range; var overlaySIdx = argsOpt.isChangeChartType || !overlayEleRange ? activeSheetIdx : getSheetIndexFromAddress(this.parent, overlayEleRange); var isPrint = this.parent.isPrintingProcessing; if ((!this.parent.allowChart && sheet.isProtected) || (overlaySIdx !== activeSheetIdx && !isPrint)) { return seriesModel; } var args = { sheetIndex: sheetIdx, reqType: 'shape', type: 'actionBegin', shapeType: 'chart', action: 'create', options: chart, range: range, operation: 'create' }; options = args.options; range = args.range; options = options || {}; if (rangeIdx.length > 0 && !argsOpt.isRefresh && isRangeSelect) { var rDiff = rangeIdx[2] - rangeIdx[0]; var cDiff = rangeIdx[3] - rangeIdx[1]; if (rDiff < cDiff) { isRowLesser = true; } } options.isSeriesInRows = isRowLesser ? true : options.isSeriesInRows ? options.isSeriesInRows : false; argsOpt.dataSheetIdx = isNullOrUndefined(argsOpt.dataSheetIdx) ? sheetIdx : argsOpt.dataSheetIdx; var chartRange = this.processChartRange(rangeIdx, argsOpt.dataSheetIdx, options); var xRange = chartRange.xRange; var yRange = chartRange.yRange; var lRange = chartRange.lRange; if (sheetIdx === activeSheetIdx && isRangeSelect) { this.focusChartRange(xRange, yRange, lRange); } if (argsOpt.triggerEvent && !argsOpt.isRefresh) { eventArgs = { type: chart.type, theme: chart.theme, isSeriesInRows: chart.isSeriesInRows, range: chart.range, markerSettings: options.markerSettings, dataLabelSettings: options.dataLabelSettings, title: options.title, legendSettings: options.legendSettings, primaryXAxis: options.primaryXAxis, primaryYAxis: options.primaryYAxis, id: chart.id, height: chart.height, width: chart.width, posRange: argsOpt.range, isInitCell: argsOpt.isInitCell, cancel: false, top: chart.top, left: chart.left, enableCanvas: chart.enableCanvas, skipDateInterpolation: chart.skipDateInterpolation }; this.parent.notify(beginAction, { eventArgs: eventArgs, action: 'beforeInsertChart' }); if (eventArgs.cancel) { return []; } chart.type = eventArgs.type; chart.theme = eventArgs.theme; chart.isSeriesInRows = eventArgs.isSeriesInRows; chart.markerSettings = eventArgs.markerSettings; chart.range = eventArgs.range; chart.id = eventArgs.id; chart.height = eventArgs.height; chart.width = eventArgs.width; if (eventArgs.enableCanvas) { chart.enableCanvas = eventArgs.enableCanvas; } if (eventArgs.skipDateInterpolation) { chart.skipDateInterpolation = eventArgs.skipDateInterpolation; } } var chartOptions = this.processChartSeries(options, argsOpt.dataSheetIdx, xRange, yRange, lRange, chartRange.isDateTime); this.isDateFormatRange = chartOptions.isDateFormat; if (this.isDateFormatRange) { this.minDate = chartOptions.minDate; this.maxDate = chartOptions.maxDate; } var primaryXAxis = { majorGridLines: chart.primaryXAxis && chart.primaryXAxis.majorGridLines && !isNullOrUndefined(chart.primaryXAxis.majorGridLines.width) ? { width: chart.primaryXAxis.majorGridLines.width } : { width: 0 }, minorGridLines: chart.primaryXAxis && chart.primaryXAxis.minorGridLines && !isNullOrUndefined(chart.primaryXAxis.minorGridLines.width) ? { width: chart.primaryXAxis.minorGridLines.width } : { width: 0 }, majorTickLines: chart.primaryXAxis && chart.primaryXAxis.majorTickLines && !isNullOrUndefined(chart.primaryXAxis.majorTickLines.width) ? { width: chart.primaryXAxis.majorTickLines.width } : { width: 1 }, minorTicksPerInterval: chart.primaryXAxis && chart.primaryXAxis.minorGridLines && chart.primaryXAxis.minorGridLines.width > 0 ? 5 : 0, labelStyle: chart.primaryXAxis && chart.primaryXAxis.labelStyle && !isNullOrUndefined(chart.primaryXAxis.labelStyle.size) ? { size: chart.primaryXAxis.labelStyle.size } : {}, edgeLabelPlacement: 'Shift', lineStyle: { width: 0 }, crossesAt: 0, valueType: chart.type === 'Scatter' && !chartRange.isStringSeries && !chart.isSeriesInRows ? 'Double' : this.isDateFormatRange ? 'DateTime' : 'Category', rangePadding: chart.type === 'Scatter' && !chartRange.isStringSeries && !chart.isSeriesInRows ? 'Round' : 'Auto', title: chart.primaryXAxis ? chart.primaryXAxis.title : '' }; if (chart.primaryXAxis && chart.primaryXAxis.visible === false) { delete chart.primaryXAxis.visible; chart.primaryXAxis.majorTickLines = { width: 0 }; primaryXAxis.majorTickLines = { width: 0 }; chart.primaryXAxis.labelStyle = { size: '0px' }; primaryXAxis.labelStyle = { size: '0px' }; } var primaryYAxis = { majorGridLines: chart.primaryYAxis && chart.primaryYAxis.majorGridLines && !isNullOrUndefined(chart.primaryYAxis.majorGridLines.width) ? { width: chart.primaryYAxis.majorGridLines.width } : { width: 1 }, minorGridLines: chart.primaryYAxis && chart.primaryYAxis.minorGridLines && !isNullOrUndefined(chart.primaryYAxis.minorGridLines.width) ? { width: chart.primaryYAxis.minorGridLines.width } : { width: 0 }, majorTickLines: chart.primaryYAxis && chart.primaryYAxis.majorTickLines && !isNullOrUndefined(chart.primaryYAxis.majorTickLines.width) ? { width: chart.primaryYAxis.majorTickLines.width } : { width: 1 }, minorTicksPerInterval: chart.primaryYAxis && chart.primaryYAxis.minorGridLines && chart.primaryYAxis.minorGridLines.width > 0 ? 5 : 0, labelStyle: chart.primaryYAxis && chart.primaryYAxis.labelStyle && !isNullOrUndefined(chart.primaryYAxis.labelStyle.size) ? { size: chart.primaryYAxis.labelStyle.size } : {}, edgeLabelPlacement: 'Shift', lineStyle: { width: 0 }, crossesAt: this.isDateFormatRange ? null : 0, title: chart.primaryYAxis ? chart.primaryYAxis.title : '' }; if (chart.primaryYAxis && chart.primaryYAxis.visible === false) { delete chart.primaryYAxis.visible; chart.primaryYAxis.majorTickLines = { width: 0 }; primaryYAxis.majorTickLines = { width: 0 }; chart.primaryYAxis.labelStyle = { size: '0px' }; primaryYAxis.labelStyle = { size: '0px' }; } this.primaryYAxisFormat = this.getAxisFormat(yRange, sheet); this.primaryXAxisFormat = this.getAxisFormat(xRange, sheet); if (argsOpt.isRefresh) { var chartObj = this.parent.element.querySelector('.' + chart.id); var chartComp = void 0; if (chartObj) { chartComp = getComponent(chartObj, 'chart'); if (argsOpt.isSwitchRowColumn && chart.type === 'Scatter') { chartComp.primaryXAxis.valueType = !chartRange.isStringSeries && !chart.isSeriesInRows ? 'Double' : 'Category'; } else if (chart.type !== 'Pie' && chart.type !== 'Doughnut') { chartComp.primaryXAxis.valueType = this.isDateFormatRange ? 'DateTime' : 'Category'; } } return chartOptions.series; } var id = chart.id + '_overlay'; var overlayObj = this.parent.serviceLocator.getService(overlay); var overlayProps = overlayObj.insertOverlayElement(id, overlayEleRange, overlaySIdx); overlayProps.element.classList.add('e-datavisualization-chart'); overlayProps.element.style.width = chart.width + 'px'; overlayProps.element.style.height = chart.height + 'px'; if (sheet && (sheet.frozenRows || sheet.frozenColumns)) { overlayObj.adjustFreezePaneSize(chart, overlayProps.element, overlayEleRange); } else { if (isNullOrUndefined(chart.top)) { chart.top = overlayProps.top; } else { overlayProps.element.style.top = Number(addDPRValue(chart.top).toFixed(2)) + 'px'; } if (isNullOrUndefined(chart.left)) { chart.left = overlayProps.left; } else { overlayProps.element.style.left = Number(addDPRValue(chart.left).toFixed(2)) + 'px'; } } this.parent.notify(overlayEleSize, { height: chart.height, width: chart.width }); var legendSettings = (chart.type === 'Pie' || chart.type === 'Doughnut') ? { position: 'Bottom', visible: true } : {}; if (!isNullOrUndefined(chart.legendSettings)) { legendSettings.visible = chart.legendSettings.visible; legendSettings.position = chart.legendSettings.position; } var theme = chart.theme || 'Material'; var borderWidth = Math.round(parseFloat(getComputedStyle(overlayProps.element).borderWidth)) * 2; var height = (parseFloat(overlayProps.element.style.height) - (isNaN(borderWidth) ? 0 : borderWidth)) + 'px'; var chartContent = this.parent.createElement('div', { id: chart.id, className: chart.id }); if (chart.type !== 'Pie' && chart.type !== 'Doughnut') { this.chart = new Chart({ primaryXAxis: primaryXAxis, primaryYAxis: primaryYAxis, background: this.getThemeBgColor(theme), chartArea: { border: { width: 0 } }, title: chart.title, legendSettings: legendSettings, theme: theme, series: chartOptions.series, tooltip: { enable: true, format: '${point.x} : <b>${point.tooltip}</b>' }, width: overlayProps.element.style.width, height: height, enableRtl: this.parent.enableRtl, enableCanvas: chart.enableCanvas ? true : false, load: function (args) { args.chart.theme = chart.theme || 'Material'; if (args.chart.primaryXAxis) { if (_this.isDateFormatRange) { args.chart.primaryXAxis.minimum = _this.minDate; args.chart.primaryXAxis.maximum = _this.maxDate; } else { if (args.chart.primaryXAxis.minimum) { args.chart.primaryXAxis.minimum = null; } if (args.chart.primaryXAxis.maximum) { args.chart.primaryXAxis.maximum = null; } } } }, beforeResize: function (args) { args.cancelResizedEvent = true; // This is for cancel the resized event. }, tooltipRender: function (args) { if (_this.isDateFormatRange) { if (_this.primaryXAxisFormat) { var point = args.point; var val = dateToInt(new Date(point.xValue)); var xValue = _this.parent.getDisplayText({ format: _this.primaryXAxisFormat, value: val.toString() }); args.text = xValue + " : <b>" + point.yValue + "</b>"; } } else if (chartRange.isDateTime) { var isXNegative = args.point.x && _this.isDateTimeNegativeValue(args.point.x.toString()); var isTooltipNegative = args.point.tooltip && _this.isDateTimeNegativeValue(args.point.tooltip.toString()); if (isXNegative || isTooltipNegative) { var point = args.point; var xValue = isXNegative ? point.xValue : args.point.x; var yValue = isTooltipNegative ? point.yValue : args.point.tooltip; args.text = xValue + " : <b>" + yValue + "</b>"; } } }, axisLabelRender: function (args) { if (args.axis.name === 'primaryYAxis' && _this.primaryYAxisFormat && !chart.type.includes('100') && !isNullOrUndefined(args.value) && _this.parent) { args.text = _this.parent.getDisplayText({ format: _this.primaryYAxisFormat, value: args.value.toString() }); } else if (args.axis.name === 'primaryXAxis' && args.text.startsWith('spread-chart-empty-label-')) { args.text = ''; } if (args.axis.name === 'primaryXAxis') { if (chart.type === 'Scatter' && !chartRange.isDateTime) { if (args.axis.labels.length > 0 && !isNumber(args.text)) { args.text = (args.axis.labels.indexOf(args.text) + 1).toString(); } else if (_this.primaryXAxisFormat && !isNullOrUndefined(args.value)) { args.text = _this.parent.getDisplayText({ format: _this.primaryXAxisFormat, value: args.value.toString() }); } } else if (_this.isDateFormatRange && _this.primaryXAxisFormat) { var val