UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

962 lines (956 loc) • 53.6 kB
/** * DevExtreme (cjs/__internal/grids/pivot_grid/data_controller/m_data_controller.js) * Version: 24.2.6 * Build date: Mon Mar 17 2025 * * Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.DataController__internals = exports.DataController = void 0; var _class = _interopRequireDefault(require("../../../../core/class")); var _callbacks = _interopRequireDefault(require("../../../../core/utils/callbacks")); var _common = require("../../../../core/utils/common"); var _deferred = require("../../../../core/utils/deferred"); var _extend = require("../../../../core/utils/extend"); var _iterator = require("../../../../core/utils/iterator"); var _string = require("../../../../core/utils/string"); var _type = require("../../../../core/utils/type"); var _m_state_storing_core = _interopRequireDefault(require("../../../grids/grid_core/state_storing/m_state_storing_core")); var _m_virtual_columns_core = require("../../../grids/grid_core/virtual_columns/m_virtual_columns_core"); var _m_virtual_scrolling_core = _interopRequireDefault(require("../../../grids/grid_core/virtual_scrolling/m_virtual_scrolling_core")); var _m_data_source = require("../data_source/m_data_source"); var _m_widget_utils = require("../m_widget_utils"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e } } const math = Math; const GRAND_TOTAL_TYPE = "GT"; const TOTAL_TYPE = "T"; const DATA_TYPE = "D"; const NOT_AVAILABLE = "#N/A"; const CHANGING_DURATION_IF_PAGINATE = 300; const proxyMethod = function(instance, methodName, defaultResult) { if (!instance[methodName]) { instance[methodName] = function() { const dataSource = this._dataSource; return dataSource ? dataSource[methodName].apply(dataSource, arguments) : defaultResult } } }; const DataController = exports.DataController = _class.default.inherit(function() { function formatCellValue(value, dataField, errorText) { return "#N/A" === value ? errorText : (0, _m_widget_utils.formatValue)(value, dataField) } const createHeaderInfo = function() { const addInfoItem = function(info, options) { const breadth = options.lastIndex - options.index || 1; const itemInfo = function(headerItem, breadth, isHorizontal, isTree) { const infoItem = { type: headerItem.type, text: headerItem.text }; if (headerItem.path) { infoItem.path = headerItem.path } if (headerItem.width) { infoItem.width = headerItem.width } if ((0, _type.isDefined)(headerItem.wordWrapEnabled)) { infoItem.wordWrapEnabled = headerItem.wordWrapEnabled } if (headerItem.isLast) { infoItem.isLast = true } if (headerItem.sorted) { infoItem.sorted = true } if (headerItem.isMetric) { infoItem.dataIndex = headerItem.dataIndex } if ((0, _type.isDefined)(headerItem.expanded)) { infoItem.expanded = headerItem.expanded } if (breadth > 1) { infoItem[isHorizontal ? "colspan" : "rowspan"] = breadth } if (headerItem.depthSize && headerItem.depthSize > 1) { infoItem[isHorizontal ? "rowspan" : "colspan"] = headerItem.depthSize } if (headerItem.index >= 0) { infoItem.dataSourceIndex = headerItem.index } if (isTree && headerItem.children && headerItem.children.length && !headerItem.children[0].isMetric) { infoItem.width = null; infoItem.isWhiteSpace = true } return infoItem }(options.headerItem, breadth, options.isHorizontal, options.isTree); ! function(info, infoItem, itemIndex, depthIndex, isHorizontal) { const index = isHorizontal ? depthIndex : itemIndex; while (!info[index]) { info.push([]) } if (isHorizontal) { info[index].push(infoItem) } else { info[index].unshift(infoItem) } }(info, itemInfo, options.index, options.depth, options.isHorizontal); if (!options.headerItem.children || 0 === options.headerItem.children.length) { return options.lastIndex + 1 } return options.lastIndex }; const getViewHeaderItems = function(headerItems, headerDescriptions, cellDescriptions, depthSize, options) { const cellDescriptionsCount = cellDescriptions.length; const viewHeaderItems = function(headerItems, headerDescriptions) { const headerDescriptionsCount = headerDescriptions && headerDescriptions.length || 0; const childrenStack = []; const d = new _deferred.Deferred; let headerItem; (0, _deferred.when)((0, _m_widget_utils.foreachTreeAsync)(headerItems, ((items, index) => { const item = items[0]; const path = (0, _m_widget_utils.createPath)(items); headerItem = createHeaderItem(childrenStack, path.length, index); headerItem.type = "D"; headerItem.value = item.value; headerItem.path = path; headerItem.text = item.text; headerItem.index = item.index; headerItem.displayText = item.displayText; headerItem.key = item.key; headerItem.isEmpty = item.isEmpty; if (path.length < headerDescriptionsCount && (!item.children || 0 !== item.children.length)) { headerItem.expanded = !!item.children } }))).done((() => { d.resolve(createHeaderItem(childrenStack, 0, 0).children || []) })); return d }(headerItems, headerDescriptions); const { dataFields: dataFields } = options; const d = new _deferred.Deferred; (0, _deferred.when)(viewHeaderItems).done((viewHeaderItems => { options.notifyProgress(.5); if (options.showGrandTotals) { viewHeaderItems[!options.showTotalsPrior ? "push" : "unshift"]({ type: "GT", isEmpty: options.isEmptyGrandTotal }) } const hideTotals = false === options.showTotals || dataFields.length > 0 && dataFields.length === options.hiddenTotals.length; const hideData = dataFields.length > 0 && options.hiddenValues.length === dataFields.length; if (hideData && hideTotals) { depthSize = 1 } if (!hideTotals || "tree" === options.layout) { ! function(headerItems, headerDescriptions, showTotalsPrior, isTree) { showTotalsPrior = showTotalsPrior || isTree; (0, _m_widget_utils.foreachTree)(headerItems, ((items, index) => { const item = items[0]; const parentChildren = (items[1] ? items[1].children : headerItems) || []; const dataField = headerDescriptions[items.length - 1]; if ("D" === item.type && item.expanded && (false !== dataField.showTotals || isTree)) { -1 !== index && parentChildren.splice(showTotalsPrior ? index : index + 1, 0, (0, _extend.extend)({}, item, { children: null, type: "T", expanded: showTotalsPrior ? true : null, isAdditionalTotal: true })); if (showTotalsPrior) { item.expanded = null } } })) }(viewHeaderItems, headerDescriptions, options.showTotalsPrior, "tree" === options.layout) }(0, _deferred.when)((0, _m_widget_utils.foreachTreeAsync)(viewHeaderItems, (items => { const item = items[0]; if (!item.children || 0 === item.children.length) { item.depthSize = depthSize - items.length + 1 } }))).done((() => { if (cellDescriptionsCount > 1) { ! function(headerItems, cellDescriptions, options) { (0, _m_widget_utils.foreachTree)(headerItems, (items => { const item = items[0]; let i; if (!item.children || 0 === item.children.length) { item.children = []; for (i = 0; i < cellDescriptions.length; i += 1) { const isGrandTotal = "GT" === item.type; const isTotal = "T" === item.type; const isValue = "D" === item.type; const columnIsHidden = false === cellDescriptions[i].visible || isGrandTotal && options.hiddenGrandTotals.includes(i) || isTotal && options.hiddenTotals.includes(i) || isValue && options.hiddenValues.includes(i); if (columnIsHidden) { continue } item.children.push({ caption: cellDescriptions[i].caption, path: item.path, type: item.type, value: i, index: item.index, dataIndex: i, isMetric: true, isEmpty: item.isEmpty && item.isEmpty[i] }) } } })) }(viewHeaderItems, cellDescriptions, options) }!options.showEmpty && function(headerItems) { (0, _m_widget_utils.foreachTree)([{ children: headerItems }], ((items, index) => { const item = items[0]; const parentChildren = (items[1] ? items[1].children : headerItems) || []; let { isEmpty: isEmpty } = item; if (isEmpty && isEmpty.length) { isEmpty = item.isEmpty.filter((isEmpty => isEmpty)).length === isEmpty.length } if (item && !item.children && isEmpty) { parentChildren.splice(index, 1); removeEmptyParent(items, 1) } })) }(viewHeaderItems); options.notifyProgress(.75); (0, _deferred.when)((0, _m_widget_utils.foreachTreeAsync)(viewHeaderItems, (items => { const item = items[0]; const { isMetric: isMetric } = item; const field = headerDescriptions[items.length - 1] || {}; if ("D" === item.type && !isMetric) { item.width = field.width } if (hideData && "D" === item.type) { const parentChildren = (items[1] ? items[1].children : viewHeaderItems) || []; parentChildren.splice(parentChildren.indexOf(item), 1); return } if (isMetric) { item.wordWrapEnabled = cellDescriptions[item.dataIndex].wordWrapEnabled } else { item.wordWrapEnabled = field.wordWrapEnabled } item.isLast = !item.children || !item.children.length; if (item.isLast) { (0, _iterator.each)(options.sortBySummaryPaths, ((_, sortBySummaryPath) => { if (!(0, _type.isDefined)(item.dataIndex)) { sortBySummaryPath = sortBySummaryPath.slice(0); sortBySummaryPath.pop() } if (function(items, sortBySummaryPath) { let path; const item = items[0]; const stringValuesUsed = (0, _type.isString)(sortBySummaryPath[0]); const headerItem = item.dataIndex >= 0 ? items[1] : item; if (stringValuesUsed && -1 !== sortBySummaryPath[0].indexOf("&[") && headerItem.key || !headerItem.key) { path = (0, _m_widget_utils.createPath)(items) } else { path = (0, _iterator.map)(items, (item => item.dataIndex >= 0 ? item.value : item.text)).reverse() } if ("GT" === item.type) { path = path.slice(1) } return path.join("/") === sortBySummaryPath.join("/") }(items, sortBySummaryPath)) { item.sorted = true; return false } return })) } item.text = function(item, description, options) { let { text: text } = item; if ((0, _type.isDefined)(item.displayText)) { text = item.displayText } else if ((0, _type.isDefined)(item.caption)) { text = item.caption } else if ("GT" === item.type) { text = options.texts.grandTotal } if (item.isAdditionalTotal) { text = (0, _string.format)(options.texts.total || "", text) } return text }(item, 0, options) }))).done((() => { if (!viewHeaderItems.length) { viewHeaderItems.push({}) } options.notifyProgress(1); d.resolve(viewHeaderItems) })) })) })); return d }; function createHeaderItem(childrenStack, depth, index) { const parent = childrenStack[depth] = childrenStack[depth] || []; const node = parent[index] = {}; if (childrenStack[depth + 1]) { node.children = childrenStack[depth + 1]; for (let i = depth + 1; i < childrenStack.length; i += 1) { childrenStack[i] = void 0 } childrenStack.length = depth + 1 } return node } const removeEmptyParent = function(items, index) { const parent = items[index + 1]; if (!items[index].children.length && parent && parent.children) { parent.children.splice(parent.children.indexOf(items[index]), 1); removeEmptyParent(items, index + 1) } }; return function(headerItems, headerDescriptions, cellDescriptions, isHorizontal, options) { const info = []; const depthSize = function(headerItems) { let depth = 0; (0, _m_widget_utils.foreachTree)(headerItems, (items => { depth = math.max(depth, items.length) })); return depth }(headerItems) || 1; const d = new _deferred.Deferred; getViewHeaderItems(headerItems, headerDescriptions, cellDescriptions, depthSize, options).done((viewHeaderItems => { ! function(info, viewHeaderItems, depthSize, isHorizontal, isTree) { let lastIndex = 0; let index; let depth; const indexesByDepth = [0]; (0, _m_widget_utils.foreachTree)(viewHeaderItems, (items => { const headerItem = items[0]; depth = headerItem.isMetric ? depthSize : items.length - 1; while (indexesByDepth.length - 1 < depth) { indexesByDepth.push(indexesByDepth[indexesByDepth.length - 1]) } index = indexesByDepth[depth] || 0; lastIndex = addInfoItem(info, { headerItem: headerItem, index: index, lastIndex: lastIndex, depth: depth, isHorizontal: isHorizontal, isTree: isTree }); indexesByDepth.length = depth; indexesByDepth.push(lastIndex) })) }(info, viewHeaderItems, depthSize, isHorizontal, "tree" === options.layout); options.notifyProgress(1); d.resolve(info) })); return d } }(); function createSortPaths(headerFields, dataFields) { const sortBySummaryPaths = []; (0, _iterator.each)(headerFields, ((_, headerField) => { const fieldIndex = (0, _m_widget_utils.findField)(dataFields, headerField.sortBySummaryField); if (fieldIndex >= 0) { sortBySummaryPaths.push((headerField.sortBySummaryPath || []).concat([fieldIndex])) } })); return sortBySummaryPaths } function foreachRowInfo(rowsInfo, callback) { let columnOffset = 0; const columnOffsetResetIndexes = []; for (let i = 0; i < rowsInfo.length; i += 1) { for (let j = 0; j < rowsInfo[i].length; j += 1) { const rowSpanOffset = (rowsInfo[i][j].rowspan || 1) - 1; const visibleIndex = i + rowSpanOffset; if (columnOffsetResetIndexes[i]) { columnOffset -= columnOffsetResetIndexes[i]; columnOffsetResetIndexes[i] = 0 } if (false === callback(rowsInfo[i][j], visibleIndex, i, j, columnOffset)) { break } columnOffsetResetIndexes[i + (rowsInfo[i][j].rowspan || 1)] = (columnOffsetResetIndexes[i + (rowsInfo[i][j].rowspan || 1)] || 0) + 1; columnOffset += 1 } } } function getHeaderIndexedItems(headerItems, options) { let visibleIndex = 0; const indexedItems = []; (0, _m_widget_utils.foreachTree)(headerItems, (items => { const headerItem = items[0]; const path = (0, _m_widget_utils.createPath)(items); if (headerItem.children && false === options.showTotals) { return } const indexedItem = (0, _extend.extend)(true, {}, headerItem, { visibleIndex: visibleIndex += 1, path: path }); if ((0, _type.isDefined)(indexedItem.index)) { indexedItems[indexedItem.index] = indexedItem } else { indexedItems.push(indexedItem) } })); return indexedItems } function createScrollController(dataController, component, dataAdapter) { return new _m_virtual_scrolling_core.default.VirtualScrollController(component, (0, _extend.extend)({ hasKnownLastPage: () => true, pageCount() { return math.ceil(this.totalItemsCount() / this.pageSize()) }, updateLoading() {}, itemsCount() { if (this.pageIndex() < this.pageCount() - 1) { return this.pageSize() } return this.totalItemsCount() % this.pageSize() }, items: () => [], viewportItems: () => [], onChanged() {}, isLoading: () => dataController.isLoading(), changingDuration() { const dataSource = dataController._dataSource; if (dataSource.paginate()) { return 300 } return dataController._changingDuration || 0 } }, dataAdapter)) } const members = { ctor(options) { const that = this; const virtualScrollControllerChanged = that._fireChanged.bind(that); options = that._options = options || {}; that.dataSourceChanged = (0, _callbacks.default)(); that._dataSource = that._createDataSource(options); if (options.component && "virtual" === options.component.option("scrolling.mode")) { that._rowsScrollController = createScrollController(that, options.component, { totalItemsCount: () => that.totalRowCount(), pageIndex: index => that.rowPageIndex(index), pageSize: () => that.rowPageSize(), load() { if (that._rowsScrollController.pageIndex() >= this.pageCount()) { that._rowsScrollController.pageIndex(this.pageCount() - 1) } return that._rowsScrollController.handleDataChanged((function() { if (that._dataSource.paginate()) { that._dataSource.load() } else { virtualScrollControllerChanged.apply(this, arguments) } })) } }); that._columnsScrollController = createScrollController(that, options.component, { totalItemsCount: () => that.totalColumnCount(), pageIndex: index => that.columnPageIndex(index), pageSize: () => that.columnPageSize(), load() { if (that._columnsScrollController.pageIndex() >= this.pageCount()) { that._columnsScrollController.pageIndex(this.pageCount() - 1) } return that._columnsScrollController.handleDataChanged((function() { if (that._dataSource.paginate()) { that._dataSource.load() } else { virtualScrollControllerChanged.apply(this, arguments) } })) } }) } that._stateStoringController = new _m_state_storing_core.default.StateStoringController(options.component).init(); that._columnsInfo = []; that._rowsInfo = []; that._cellsInfo = []; that.expandValueChanging = (0, _callbacks.default)(); that.loadingChanged = (0, _callbacks.default)(); that.progressChanged = (0, _callbacks.default)(); that.scrollChanged = (0, _callbacks.default)(); that.load(); that._update(); that.changed = (0, _callbacks.default)() }, _fireChanged() { const startChanging = new Date; this.changed && !this._lockChanged && this.changed.fire(); this._changingDuration = new Date - startChanging }, _correctSkipsTakes(rowIndex, rowSkip, rowSpan, levels, skips, takes) { const endIndex = rowSpan ? rowIndex + rowSpan - 1 : rowIndex; skips[levels.length] = skips[levels.length] || 0; takes[levels.length] = takes[levels.length] || 0; if (endIndex < rowSkip) { skips[levels.length] += 1 } else { takes[levels.length] += 1 } }, _calculatePagingForRowExpandedPaths(options, skips, takes, rowExpandedSkips, rowExpandedTakes) { const rows = this._rowsInfo; const rowCount = Math.min(options.rowSkip + options.rowTake, rows.length); const { rowExpandedPaths: rowExpandedPaths } = options; let levels = []; const expandedPathIndexes = {}; let i; let j; let path; rowExpandedPaths.forEach(((path, index) => { expandedPathIndexes[path] = index })); for (i = 0; i < rowCount; i += 1) { takes.length = skips.length = levels.length + 1; for (j = 0; j < rows[i].length; j += 1) { const cell = rows[i][j]; if ("D" === cell.type) { this._correctSkipsTakes(i, options.rowSkip, cell.rowspan, levels, skips, takes); path = cell.path || path; const expandIndex = path && path.length > 1 ? expandedPathIndexes[path.slice(0, -1)] : -1; if (expandIndex >= 0) { rowExpandedSkips[expandIndex] = skips[levels.length] || 0; rowExpandedTakes[expandIndex] = takes[levels.length] || 0 } if (cell.rowspan) { levels.push(cell.rowspan) } } } levels = levels.map((level => level - 1)).filter((level => level > 0)) } }, _calculatePagingForColumnExpandedPaths(options, skips, takes, expandedSkips, expandedTakes) { const skipByPath = {}; const takeByPath = {}; (0, _m_virtual_columns_core.foreachColumnInfo)(this._columnsInfo, ((columnInfo, columnIndex) => { if ("D" === columnInfo.type && columnInfo.path && void 0 === columnInfo.dataIndex) { const colspan = columnInfo.colspan || 1; const path = columnInfo.path.slice(0, -1).toString(); skipByPath[path] = skipByPath[path] || 0; takeByPath[path] = takeByPath[path] || 0; if (columnIndex + colspan <= options.columnSkip) { skipByPath[path] += 1 } else if (columnIndex < options.columnSkip + options.columnTake) { takeByPath[path] += 1 } } })); skips[0] = skipByPath[""]; takes[0] = takeByPath[""]; options.columnExpandedPaths.forEach(((path, index) => { const skip = skipByPath[path]; const take = takeByPath[path]; if (void 0 !== skip) { expandedSkips[index] = skip } if (void 0 !== take) { expandedTakes[index] = take } })) }, _processPagingForExpandedPaths(options, area, storeLoadOptions, reload) { const expandedPaths = options[`${area}ExpandedPaths`]; const expandedSkips = expandedPaths.map((() => 0)); const expandedTakes = expandedPaths.map((() => reload ? options.pageSize : 0)); const skips = []; const takes = []; if (!reload) { if ("row" === area) { this._calculatePagingForRowExpandedPaths(options, skips, takes, expandedSkips, expandedTakes) } else { this._calculatePagingForColumnExpandedPaths(options, skips, takes, expandedSkips, expandedTakes) } } this._savePagingForExpandedPaths(options, area, storeLoadOptions, skips[0], takes[0], expandedSkips, expandedTakes) }, _savePagingForExpandedPaths(options, area, storeLoadOptions, skip, take, expandedSkips, expandedTakes) { const expandedPaths = options[`${area}ExpandedPaths`]; options[`${area}ExpandedPaths`] = []; options[`${area}Skip`] = void 0 !== skip ? skip : options[`${area}Skip`]; options[`${area}Take`] = void 0 !== take ? take : options[`${area}Take`]; for (let i = 0; i < expandedPaths.length; i += 1) { if (expandedTakes[i]) { const isOppositeArea = options.area && options.area !== area; storeLoadOptions.push((0, _extend.extend)({ area: area, headerName: `${area}s` }, options, { [`${area}Skip`]: expandedSkips[i], [`${area}Take`]: expandedTakes[i], [isOppositeArea ? "oppositePath" : "path"]: expandedPaths[i] })) } } }, _handleCustomizeStoreLoadOptions(storeLoadOptions, reload) { const options = storeLoadOptions[0]; const rowsScrollController = this._rowsScrollController; if (this._dataSource.paginate() && rowsScrollController) { const rowPageSize = rowsScrollController.pageSize(); if ("rows" === options.headerName) { options.rowSkip = 0; options.rowTake = rowPageSize; options.rowExpandedPaths = [] } else { options.rowSkip = rowsScrollController.beginPageIndex() * rowPageSize; options.rowTake = (rowsScrollController.endPageIndex() - rowsScrollController.beginPageIndex() + 1) * rowPageSize; this._processPagingForExpandedPaths(options, "row", storeLoadOptions, reload) } } const columnsScrollController = this._columnsScrollController; if (this._dataSource.paginate() && columnsScrollController) { const columnPageSize = columnsScrollController.pageSize(); storeLoadOptions.forEach((options => { if ("columns" === options.headerName) { options.columnSkip = 0; options.columnTake = columnPageSize; options.columnExpandedPaths = [] } else { options.columnSkip = columnsScrollController.beginPageIndex() * columnPageSize; options.columnTake = (columnsScrollController.endPageIndex() - columnsScrollController.beginPageIndex() + 1) * columnPageSize; this._processPagingForExpandedPaths(options, "column", storeLoadOptions, reload) } })) } }, load() { const that = this; const stateStoringController = this._stateStoringController; if (stateStoringController.isEnabled() && !stateStoringController.isLoaded()) { stateStoringController.load().always((state => { if (state) { that._dataSource.state(state) } else { that._dataSource.load() } })) } else { that._dataSource.load() } }, calculateVirtualContentParams(contentParams) { const that = this; const rowsScrollController = that._rowsScrollController; const columnsScrollController = that._columnsScrollController; if (rowsScrollController && columnsScrollController) { rowsScrollController.viewportItemSize(contentParams.virtualRowHeight); rowsScrollController.viewportSize(contentParams.viewportHeight / rowsScrollController.viewportItemSize()); rowsScrollController.setContentItemSizes(contentParams.itemHeights); columnsScrollController.viewportItemSize(contentParams.virtualColumnWidth); columnsScrollController.viewportSize(contentParams.viewportWidth / columnsScrollController.viewportItemSize()); columnsScrollController.setContentItemSizes(contentParams.itemWidths); (0, _common.deferUpdate)((() => { columnsScrollController.loadIfNeed(); rowsScrollController.loadIfNeed() })); that.scrollChanged.fire({ left: columnsScrollController.getViewportPosition(), top: rowsScrollController.getViewportPosition() }); return { contentTop: rowsScrollController.getContentOffset(), contentLeft: columnsScrollController.getContentOffset(), width: columnsScrollController.getVirtualContentSize(), height: rowsScrollController.getVirtualContentSize() } } return }, setViewportPosition(left, top) { this._rowsScrollController.setViewportPosition(top || 0); this._columnsScrollController.setViewportPosition(left || 0) }, subscribeToWindowScrollEvents($element) { var _this$_rowsScrollCont; null === (_this$_rowsScrollCont = this._rowsScrollController) || void 0 === _this$_rowsScrollCont || _this$_rowsScrollCont.subscribeToWindowScrollEvents($element) }, updateWindowScrollPosition(position) { var _this$_rowsScrollCont2; null === (_this$_rowsScrollCont2 = this._rowsScrollController) || void 0 === _this$_rowsScrollCont2 || _this$_rowsScrollCont2.scrollTo(position) }, updateViewOptions(options) { (0, _extend.extend)(this._options, options); this._update() }, _handleExpandValueChanging(e) { this.expandValueChanging.fire(e) }, _handleLoadingChanged(isLoading) { this.loadingChanged.fire(isLoading) }, _handleProgressChanged(progress) { this.progressChanged.fire(progress) }, _handleFieldsPrepared(e) { this._options.onFieldsPrepared && this._options.onFieldsPrepared(e) }, _createDataSource(options) { const that = this; const dataSourceOptions = options.dataSource; let dataSource; that._isSharedDataSource = dataSourceOptions instanceof _m_data_source.PivotGridDataSource; if (that._isSharedDataSource) { dataSource = dataSourceOptions } else { dataSource = new _m_data_source.PivotGridDataSource(dataSourceOptions) } that._expandValueChangingHandler = that._handleExpandValueChanging.bind(that); that._loadingChangedHandler = that._handleLoadingChanged.bind(that); that._fieldsPreparedHandler = that._handleFieldsPrepared.bind(that); that._customizeStoreLoadOptionsHandler = that._handleCustomizeStoreLoadOptions.bind(that); that._changedHandler = function() { that._update(); that.dataSourceChanged.fire() }; that._progressChangedHandler = function(progress) { that._handleProgressChanged(.8 * progress) }; dataSource.on("changed", that._changedHandler); dataSource.on("expandValueChanging", that._expandValueChangingHandler); dataSource.on("loadingChanged", that._loadingChangedHandler); dataSource.on("progressChanged", that._progressChangedHandler); dataSource.on("fieldsPrepared", that._fieldsPreparedHandler); dataSource.on("customizeStoreLoadOptions", that._customizeStoreLoadOptionsHandler); return dataSource }, getDataSource() { return this._dataSource }, isLoading() { return this._dataSource.isLoading() }, beginLoading() { this._dataSource.beginLoading() }, endLoading() { this._dataSource.endLoading() }, _update() { const that = this; const dataSource = that._dataSource; const options = that._options; const columnFields = dataSource.getAreaFields("column"); const rowFields = dataSource.getAreaFields("row"); const dataFields = dataSource.getAreaFields("data"); const dataFieldsForRows = "row" === options.dataFieldArea ? dataFields : []; const dataFieldsForColumns = "row" !== options.dataFieldArea ? dataFields : []; const data = dataSource.getData(); const hiddenTotals = function(dataFields) { const result = []; (0, _iterator.each)(dataFields, ((index, field) => { if (false === field.showTotals) { result.push(index) } })); return result }(dataFields); const hiddenValues = function(dataFields) { const result = []; dataFields.forEach(((field, index) => { if (void 0 === field.showValues && false === field.showTotals || false === field.showValues) { result.push(index) } })); return result }(dataFields); const hiddenGrandTotals = function(dataFields, columnFields) { let result = []; (0, _iterator.each)(dataFields, ((index, field) => { if (false === field.showGrandTotals) { result.push(index) } })); if (0 === columnFields.length && result.length === dataFields.length) { result = [] } return result }(dataFields, columnFields); const grandTotalsAreHiddenForNotAllDataFields = dataFields.length > 0 ? hiddenGrandTotals.length !== dataFields.length : true; const commonOptions = { texts: options.texts || {}, hiddenTotals: hiddenTotals, hiddenValues: hiddenValues, hiddenGrandTotals: hiddenGrandTotals, showEmpty: !options.hideEmptySummaryCells, dataFields: dataFields, progress: 0 }; const rowOptions = (0, _extend.extend)({}, commonOptions, { isEmptyGrandTotal: data.isEmptyGrandTotalRow, showTotals: options.showRowTotals, showTotalsPrior: "rows" === options.showTotalsPrior || "both" === options.showTotalsPrior, showGrandTotals: false !== options.showRowGrandTotals && grandTotalsAreHiddenForNotAllDataFields, sortBySummaryPaths: createSortPaths(columnFields, dataFields), layout: options.rowHeaderLayout, fields: rowFields }); const columnOptions = (0, _extend.extend)({}, commonOptions, { isEmptyGrandTotal: data.isEmptyGrandTotalColumn, showTotals: options.showColumnTotals, showTotalsPrior: "columns" === options.showTotalsPrior || "both" === options.showTotalsPrior, showGrandTotals: false !== options.showColumnGrandTotals && grandTotalsAreHiddenForNotAllDataFields, sortBySummaryPaths: createSortPaths(rowFields, dataFields), fields: columnFields }); const notifyProgress = function(progress) { this.progress = progress; that._handleProgressChanged(.8 + .1 * rowOptions.progress + .1 * columnOptions.progress) }; rowOptions.notifyProgress = notifyProgress; columnOptions.notifyProgress = notifyProgress; if (!(0, _type.isDefined)(data.grandTotalRowIndex)) { data.grandTotalRowIndex = getHeaderIndexedItems(data.rows, rowOptions).length } if (!(0, _type.isDefined)(data.grandTotalColumnIndex)) { data.grandTotalColumnIndex = getHeaderIndexedItems(data.columns, columnOptions).length } dataSource._changeLoadingCount(1); (0, _deferred.when)(createHeaderInfo(data.columns, columnFields, dataFieldsForColumns, true, columnOptions), createHeaderInfo(data.rows, rowFields, dataFieldsForRows, false, rowOptions)).always((() => { dataSource._changeLoadingCount(-1) })).done(((columnsInfo, rowsInfo) => { that._columnsInfo = columnsInfo; that._rowsInfo = rowsInfo; if (that._rowsScrollController && that._columnsScrollController && that.changed && !that._dataSource.paginate()) { that._rowsScrollController.reset(true); that._columnsScrollController.reset(true); that._lockChanged = true; that._rowsScrollController.load(); that._columnsScrollController.load(); that._lockChanged = false } })).done((() => { that._fireChanged(); if (that._stateStoringController.isEnabled() && !that._dataSource.isLoading()) { that._stateStoringController.state(that._dataSource.state()); that._stateStoringController.save() } })) }, getRowsInfo(getAllData) { const that = this; const rowsInfo = that._rowsInfo; const scrollController = that._rowsScrollController; let rowspan; if (scrollController && !getAllData) { const startIndex = scrollController.beginPageIndex() * that.rowPageSize(); const endIndex = scrollController.endPageIndex() * that.rowPageSize() + that.rowPageSize(); const summaryFields = that._dataSource.getSummaryFields(); const isRowDataFieldArea = "row" === this._options.dataFieldArea; const newRowsInfo = []; let maxDepth = 1; foreachRowInfo(rowsInfo, ((rowInfo, visibleIndex, rowIndex, _, columnIndex) => { const isVisible = visibleIndex >= startIndex && rowIndex < endIndex; const index = rowIndex < startIndex ? 0 : rowIndex - startIndex; let cell = rowInfo; if (isVisible) { newRowsInfo[index] = newRowsInfo[index] || []; rowspan = rowIndex < startIndex ? rowInfo.rowspan - (startIndex - rowIndex) || 1 : rowInfo.rowspan; if (startIndex + index + rowspan > endIndex) { rowspan = endIndex - (index + startIndex) || 1 } if (rowspan !== rowInfo.rowspan) { cell = (0, _extend.extend)({}, cell, { rowspan: rowspan }) } newRowsInfo[index].push(cell); const isSummaryCell = summaryFields.some((field => field.caption === cell.text)); if (!isRowDataFieldArea || !isSummaryCell) { maxDepth = math.max(maxDepth, columnIndex + 1) } } else { return false } return })); foreachRowInfo(newRowsInfo, ((rowInfo, visibleIndex, rowIndex, columnIndex, realColumnIndex) => { const colspan = rowInfo.colspan || 1; if (realColumnIndex + colspan > maxDepth) { newRowsInfo[rowIndex][columnIndex] = (0, _extend.extend)({}, rowInfo, { colspan: maxDepth - realColumnIndex || 1 }) } })); return newRowsInfo } return rowsInfo }, getColumnsInfo(getAllData) { const that = this; let info = that._columnsInfo; const scrollController = that._columnsScrollController; if (scrollController && !getAllData) { const startIndex = scrollController.beginPageIndex() * that.columnPageSize(); const endIndex = scrollController.endPageIndex() * that.columnPageSize() + that.columnPageSize(); info = (0, _m_virtual_columns_core.createColumnsInfo)(info, startIndex, endIndex) } return info }, totalRowCount() { return this._rowsInfo.length }, rowPageIndex(index) { if (void 0 !== index) { this._rowPageIndex = index } return this._rowPageIndex || 0 }, totalColumnCount() { let count = 0; if (this._columnsInfo && this._columnsInfo.length) { for (let i = 0; i < this._columnsInfo[0].length; i += 1) { count += this._columnsInfo[0][i].colspan || 1 } } return count }, rowPageSize(size) { if (void 0 !== size) { this._rowPageSize = size } return this._rowPageSize || 20 }, columnPageSize(size) { if (void 0 !== size) { this._columnPageSize = size } return this._columnPageSize || 20 }, columnPageIndex(index) { if (void 0 !== index) { this._columnPageIndex = index } return this._columnPageIndex || 0 }, getCellsInfo(getAllData) { const rowsInfo = this.getRowsInfo(getAllData); const columnsInfo = this.getColumnsInfo(getAllData); const data = this._dataSource.getData(); const texts = this._options.texts || {}; return function(rowsInfo, columnsInfo, data, dataFields, dataFieldArea, errorText) { const info = []; const dataFieldAreaInRows = "row" === dataFieldArea; const dataSourceCells = data.values; dataSourceCells.length && foreachRowInfo(rowsInfo, ((rowInfo, rowIndex) => { const row = info[rowIndex] = []; const dataRo