UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

1,114 lines (940 loc) • 45.7 kB
"use strict"; var Callbacks = require("../../core/utils/callbacks"), deferredUtils = require("../../core/utils/deferred"), when = deferredUtils.when, Deferred = deferredUtils.Deferred, extend = require("../../core/utils/extend").extend, inArray = require("../../core/utils/array").inArray, iteratorUtils = require("../../core/utils/iterator"), Class = require("../../core/class"), stringUtils = require("../../core/utils/string"), commonUtils = require("../../core/utils/common"), typeUtils = require("../../core/utils/type"), virtualScrolling = require("../grid_core/ui.grid_core.virtual_scrolling_core"), virtualColumnsCore = require("../grid_core/ui.grid_core.virtual_columns_core"), stateStoring = require("../grid_core/ui.grid_core.state_storing_core"), PivotGridDataSource = require("./data_source"), pivotGridUtils = require("./ui.pivot_grid.utils"), foreachTree = pivotGridUtils.foreachTree, foreachTreeAsync = pivotGridUtils.foreachTreeAsync, createPath = pivotGridUtils.createPath, formatValue = pivotGridUtils.formatValue, math = Math, GRAND_TOTAL_TYPE = "GT", TOTAL_TYPE = "T", DATA_TYPE = "D", NOT_AVAILABLE = "#N/A"; var proxyMethod = function proxyMethod(instance, methodName, defaultResult) { if (!instance[methodName]) { instance[methodName] = function () { var dataSource = this._dataSource; return dataSource ? dataSource[methodName].apply(dataSource, arguments) : defaultResult; }; } }; exports.DataController = Class.inherit(function () { function getHeaderItemText(item, description, options) { var text = item.text; if (typeUtils.isDefined(item.displayText)) { text = item.displayText; } else if (typeUtils.isDefined(item.caption)) { text = item.caption; } else if (item.type === GRAND_TOTAL_TYPE) { text = options.texts.grandTotal; } if (item.isAdditionalTotal) { text = stringUtils.format(options.texts.total || '', text); } return text; } function formatCellValue(value, dataField, errorText) { return value === NOT_AVAILABLE ? errorText : formatValue(value, dataField); } var createHeaderInfo = function () { var getHeaderItemsDepth = function getHeaderItemsDepth(headerItems) { var depth = 0; foreachTree(headerItems, function (items) { depth = math.max(depth, items.length); }); return depth; }; var createInfoItem = function createInfoItem(headerItem, breadth, isHorizontal, isTree) { /** * @name dxPivotGridPivotGridCell * @publicName dxPivotGridPivotGridCell * @type object */ var infoItem = { /** * @name dxPivotGridPivotGridCell.type * @publicName type * @acceptValues "D" | "T" | "GT" * @type string */ type: headerItem.type, text: headerItem.text }; if (headerItem.path) { /** * @name dxPivotGridPivotGridCell.path * @publicName path * @type Array<string, number, Date> */ infoItem.path = headerItem.path; } if (headerItem.width) { infoItem.width = headerItem.width; } if (typeUtils.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 (typeUtils.isDefined(headerItem.expanded)) { /** * @name dxPivotGridPivotGridCell.expanded * @publicName expanded * @type boolean */ 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; }; var addInfoItem = function addInfoItem(info, options) { var itemInfo, breadth = options.lastIndex - options.index || 1, addInfoItemCore = function addInfoItemCore(info, infoItem, itemIndex, depthIndex, isHorizontal) { var index = isHorizontal ? depthIndex : itemIndex; while (!info[index]) { info.push([]); } if (isHorizontal) { info[index].push(infoItem); } else { info[index].unshift(infoItem); } }; itemInfo = createInfoItem(options.headerItem, breadth, options.isHorizontal, options.isTree); addInfoItemCore(info, itemInfo, options.index, options.depth, options.isHorizontal); if (!options.headerItem.children || options.headerItem.children.length === 0) { return options.lastIndex + 1; } return options.lastIndex; }; var isItemSorted = function isItemSorted(items, sortBySummaryPath) { var path, item = items[0], stringValuesUsed = typeUtils.isString(sortBySummaryPath[0]), headerItem = item.dataIndex >= 0 ? items[1] : item; if (stringValuesUsed && sortBySummaryPath[0].indexOf("&[") !== -1 && headerItem.key || !headerItem.key) { path = createPath(items); } else { path = iteratorUtils.map(items, function (item) { return item.dataIndex >= 0 ? item.value : item.text; }).reverse(); } if (item.type === GRAND_TOTAL_TYPE) { path = path.slice(1); } return path.join("/") === sortBySummaryPath.join("/"); }; var getViewHeaderItems = function getViewHeaderItems(headerItems, headerDescriptions, cellDescriptions, depthSize, options) { var cellDescriptionsCount = cellDescriptions.length, viewHeaderItems = createViewHeaderItems(headerItems, headerDescriptions), dataFields = options.dataFields, d = new Deferred(); when(viewHeaderItems).done(function (viewHeaderItems) { options.notifyProgress(0.5); if (options.showGrandTotals || headerDescriptions.length === 0) { viewHeaderItems[!options.showTotalsPrior ? "push" : "unshift"]({ type: GRAND_TOTAL_TYPE, isEmpty: options.isEmptyGrandTotal }); } var hideTotals = options.showTotals === false || dataFields.length > 0 && dataFields.length === options.hiddenTotals.length, hideData = dataFields.length > 0 && options.hiddenValues.length === dataFields.length; if (hideData && hideTotals) { depthSize = 1; } if (!hideTotals || options.layout === "tree") { addAdditionalTotalHeaderItems(viewHeaderItems, headerDescriptions, options.showTotalsPrior, options.layout === "tree"); } when(foreachTreeAsync(viewHeaderItems, function (items) { var item = items[0]; if (!item.children || item.children.length === 0) { item.depthSize = depthSize - items.length + 1; } })).done(function () { if (cellDescriptionsCount > 1) { addMetricHeaderItems(viewHeaderItems, cellDescriptions, options); } !options.showEmpty && removeHiddenItems(viewHeaderItems); options.notifyProgress(0.75); when(foreachTreeAsync(viewHeaderItems, function (items) { var item = items[0], isMetric = item.isMetric, field = headerDescriptions[items.length - 1] || {}; if (item.type === DATA_TYPE && !isMetric) { item.width = field.width; } if (hideData === true && item.type === DATA_TYPE) { var parentChildren = (items[1] ? items[1].children : viewHeaderItems) || []; parentChildren.splice(inArray(item, parentChildren), 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) { iteratorUtils.each(options.sortBySummaryPaths, function (index, sortBySummaryPath) { if (!typeUtils.isDefined(item.dataIndex)) { sortBySummaryPath = sortBySummaryPath.slice(0); sortBySummaryPath.pop(); } if (isItemSorted(items, sortBySummaryPath)) { item.sorted = true; return false; } }); } item.text = getHeaderItemText(item, field, options); })).done(function () { if (!viewHeaderItems.length) { viewHeaderItems.push({}); } options.notifyProgress(1); d.resolve(viewHeaderItems); }); }); }); return d; }; function createHeaderItem(childrenStack, depth, index) { var parent = childrenStack[depth] = childrenStack[depth] || [], node = parent[index] = {}; if (childrenStack[depth + 1]) { node.children = childrenStack[depth + 1]; // T541266 for (var i = depth + 1; i < childrenStack.length; i++) { childrenStack[i] = undefined; } childrenStack.length = depth + 1; } return node; } function createViewHeaderItems(headerItems, headerDescriptions) { var headerDescriptionsCount = headerDescriptions && headerDescriptions.length || 0, childrenStack = [], d = new Deferred(), headerItem; when(foreachTreeAsync(headerItems, function (items, index) { var item = items[0], path = createPath(items); headerItem = createHeaderItem(childrenStack, path.length, index); headerItem.type = DATA_TYPE; 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 || item.children.length !== 0)) { headerItem.expanded = !!item.children; } })).done(function () { d.resolve(createHeaderItem(childrenStack, 0, 0).children || []); }); return d; } var addMetricHeaderItems = function addMetricHeaderItems(headerItems, cellDescriptions, options) { foreachTree(headerItems, function (items) { var item = items[0], i; if (!item.children || item.children.length === 0) { item.children = []; for (i = 0; i < cellDescriptions.length; i++) { var isGrandTotal = item.type === GRAND_TOTAL_TYPE, isTotal = item.type === TOTAL_TYPE, isValue = item.type === DATA_TYPE, columnIsHidden = cellDescriptions[i].visible === false || isGrandTotal && inArray(i, options.hiddenGrandTotals) !== -1 || isTotal && inArray(i, options.hiddenTotals) !== -1 || isValue && inArray(i, options.hiddenValues) !== -1; 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] }); } } }); }; var addAdditionalTotalHeaderItems = function addAdditionalTotalHeaderItems(headerItems, headerDescriptions, showTotalsPrior, isTree) { showTotalsPrior = showTotalsPrior || isTree; foreachTree(headerItems, function (items, index) { var item = items[0], parentChildren = (items[1] ? items[1].children : headerItems) || [], dataField = headerDescriptions[items.length - 1]; if (item.type === DATA_TYPE && item.expanded && (dataField.showTotals !== false || isTree)) { index !== -1 && parentChildren.splice(showTotalsPrior ? index : index + 1, 0, extend({}, item, { children: null, type: TOTAL_TYPE, expanded: showTotalsPrior ? true : null, isAdditionalTotal: true })); if (showTotalsPrior) { item.expanded = null; } } }); }; var removeEmptyParent = function removeEmptyParent(items, index) { var parent = items[index + 1]; if (!items[index].children.length && parent && parent.children) { parent.children.splice(inArray(items[index], parent.children), 1); removeEmptyParent(items, index + 1); } }; var removeHiddenItems = function removeHiddenItems(headerItems) { foreachTree([{ children: headerItems }], function (items, index) { var item = items[0], parentChildren = (items[1] ? items[1].children : headerItems) || []; if (item && !item.children && (item.isEmpty && item.isEmpty.length ? item.isEmpty[0] : item.isEmpty)) { parentChildren.splice(index, 1); removeEmptyParent(items, 1); } }); }; var fillHeaderInfo = function fillHeaderInfo(info, viewHeaderItems, depthSize, isHorizontal, isTree) { var lastIndex = 0, index, depth, indexesByDepth = [0]; foreachTree(viewHeaderItems, function (items) { var 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); }); }; return function (headerItems, headerDescriptions, cellDescriptions, isHorizontal, options) { var info = [], depthSize = getHeaderItemsDepth(headerItems) || 1, d = new Deferred(); getViewHeaderItems(headerItems, headerDescriptions, cellDescriptions, depthSize, options).done(function (viewHeaderItems) { fillHeaderInfo(info, viewHeaderItems, depthSize, isHorizontal, options.layout === "tree"); options.notifyProgress(1); d.resolve(info); }); return d; }; }(); function createSortPaths(headerFields, dataFields) { var sortBySummaryPaths = []; iteratorUtils.each(headerFields, function (index, headerField) { var fieldIndex = pivotGridUtils.findField(dataFields, headerField.sortBySummaryField); if (fieldIndex >= 0) { sortBySummaryPaths.push((headerField.sortBySummaryPath || []).concat([fieldIndex])); } }); return sortBySummaryPaths; } function foreachRowInfo(rowsInfo, callback) { var columnOffset = 0, columnOffsetResetIndexes = []; for (var i = 0; i < rowsInfo.length; i++) { for (var j = 0; j < rowsInfo[i].length; j++) { var rowSpanOffset = (rowsInfo[i][j].rowspan || 1) - 1, visibleIndex = i + rowSpanOffset; if (columnOffsetResetIndexes[i]) { columnOffset -= columnOffsetResetIndexes[i]; columnOffsetResetIndexes[i] = 0; } if (callback(rowsInfo[i][j], visibleIndex, i, j, columnOffset) === false) { break; } columnOffsetResetIndexes[i + (rowsInfo[i][j].rowspan || 1)] = (columnOffsetResetIndexes[i + (rowsInfo[i][j].rowspan || 1)] || 0) + 1; columnOffset++; } } } function createCellsInfo(rowsInfo, columnsInfo, data, dataFields, dataFieldArea, errorText) { var info = [], dataFieldAreaInRows = dataFieldArea === "row", dataSourceCells = data.values; dataSourceCells.length && foreachRowInfo(rowsInfo, function (rowInfo, rowIndex) { var row = info[rowIndex] = [], dataRow = dataSourceCells[rowInfo.dataSourceIndex >= 0 ? rowInfo.dataSourceIndex : data.grandTotalRowIndex] || []; rowInfo.isLast && virtualColumnsCore.foreachColumnInfo(columnsInfo, function (columnInfo, columnIndex) { var dataIndex = (dataFieldAreaInRows ? rowInfo.dataIndex : columnInfo.dataIndex) || 0, dataField = dataFields[dataIndex]; if (columnInfo.isLast && dataField) { var cell = dataRow[columnInfo.dataSourceIndex >= 0 ? columnInfo.dataSourceIndex : data.grandTotalColumnIndex], cellValue; if (!Array.isArray(cell)) { cell = [cell]; } cellValue = cell[dataIndex]; row[columnIndex] = { /** * @name dxPivotGridPivotGridCell.text * @publicName text * @type string */ text: formatCellValue(cellValue, dataField, errorText), /** * @name dxPivotGridPivotGridCell.value * @publicName value */ value: cellValue, format: dataField.format, precision: dataField.precision, dataType: dataField.dataType, /** * @name dxPivotGridPivotGridCell.columnType * @publicName columnType * @acceptValues "D" | "T" | "GT" * @type string */ columnType: columnInfo.type, /** * @name dxPivotGridPivotGridCell.rowType * @publicName rowType * @acceptValues "D" | "T" | "GT" * @type string */ rowType: rowInfo.type, /** * @name dxPivotGridPivotGridCell.rowPath * @publicName rowPath * @type Array<string, number, Date> */ rowPath: rowInfo.path || [], /** * @name dxPivotGridPivotGridCell.columnPath * @publicName columnPath * @type Array<string, number, Date> */ columnPath: columnInfo.path || [], /** * @name dxPivotGridPivotGridCell.dataIndex * @publicName dataIndex * @type number */ dataIndex: dataIndex }; if (dataField.width) { row[columnIndex].width = dataField.width; } } }); }); return info; } function getHeaderIndexedItems(headerItems, options) { var visibleIndex = 0, indexedItems = []; foreachTree(headerItems, function (items) { var headerItem = items[0], path = createPath(items); if (headerItem.children && options.showTotals === false) return; var indexedItem = extend(true, {}, headerItem, { visibleIndex: visibleIndex++, path: path }); if (typeUtils.isDefined(indexedItem.index)) { indexedItems[indexedItem.index] = indexedItem; } else { indexedItems.push(indexedItem); } }); return indexedItems; } function createScrollController(dataController, component, dataAdapter) { if (component && component.option("scrolling.mode") === "virtual") { return new virtualScrolling.VirtualScrollController(component, extend({ hasKnownLastPage: function hasKnownLastPage() { return true; }, pageCount: function pageCount() { return math.ceil(this.totalItemsCount() / this.pageSize()); }, updateLoading: function updateLoading() {}, itemsCount: function itemsCount() { if (this.pageIndex() < this.pageCount() - 1) { return this.pageSize(); } else { return this.totalItemsCount() % this.pageSize(); } }, items: function items() { return []; }, viewportItems: function viewportItems() { return []; }, onChanged: function onChanged() {}, isLoading: function isLoading() { return dataController.isLoading(); }, changingDuration: function changingDuration() { return dataController._changingDuration || 0; } }, dataAdapter)); } } function getHiddenTotals(dataFields) { var result = []; iteratorUtils.each(dataFields, function (index, field) { if (field.showTotals === false) { result.push(index); } }); return result; } function getHiddenValues(dataFields) { var result = []; dataFields.forEach(function (field, index) { if (field.showValues === undefined && field.showTotals === false || field.showValues === false) { result.push(index); } }); return result; } function getHiddenGrandTotalsTotals(dataFields, columnFields) { var result = []; iteratorUtils.each(dataFields, function (index, field) { if (field.showGrandTotals === false) { result.push(index); } }); if (columnFields.length === 0 && result.length === dataFields.length) { result = []; } return result; } var members = { ctor: function ctor(options) { var that = this, virtualScrollControllerChanged = that._fireChanged.bind(that); options = that._options = options || {}; that.dataSourceChanged = Callbacks(); that._dataSource = that._createDataSource(options); that._rowsScrollController = createScrollController(that, options.component, { totalItemsCount: function totalItemsCount() { return that.totalRowCount(); }, pageIndex: function pageIndex(index) { return that.rowPageIndex(index); }, pageSize: function pageSize() { return that.rowPageSize(); }, load: function load() { if (that._rowsScrollController.pageIndex() >= this.pageCount()) { that._rowsScrollController.pageIndex(this.pageCount() - 1); } return that._rowsScrollController.handleDataChanged(virtualScrollControllerChanged); } }); that._columnsScrollController = createScrollController(that, options.component, { totalItemsCount: function totalItemsCount() { return that.totalColumnCount(); }, pageIndex: function pageIndex(index) { return that.columnPageIndex(index); }, pageSize: function pageSize() { return that.columnPageSize(); }, load: function load() { if (that._columnsScrollController.pageIndex() >= this.pageCount()) { that._columnsScrollController.pageIndex(this.pageCount() - 1); } return that._columnsScrollController.handleDataChanged(virtualScrollControllerChanged); } }); that._stateStoringController = new stateStoring.StateStoringController(options.component).init(); that._columnsInfo = []; that._rowsInfo = []; that._cellsInfo = []; that.expandValueChanging = Callbacks(); that.loadingChanged = Callbacks(); that.progressChanged = Callbacks(); that.scrollChanged = Callbacks(); that.load(); that._update(); that.changed = Callbacks(); }, _fireChanged: function _fireChanged() { var that = this, startChanging = new Date(); that.changed && !that._lockChanged && that.changed.fire(); that._changingDuration = new Date() - startChanging; }, load: function load() { var that = this, stateStoringController = this._stateStoringController; if (stateStoringController.isEnabled() && !stateStoringController.isLoaded()) { stateStoringController.load().always(function (state) { if (state) { that._dataSource.state(state); } else { that._dataSource.load(); } }); } else { that._dataSource.load(); } }, calculateVirtualContentParams: function calculateVirtualContentParams(contentParams) { var that = this, rowsScrollController = that._rowsScrollController, columnsScrollController = that._columnsScrollController, rowViewportItemSize = contentParams.contentHeight / contentParams.rowCount, columnViewportItemSize = contentParams.contentWidth / contentParams.columnCount, oldColumnViewportItemSize, oldRowViewportItemSize, newLeftPosition, newTopPosition; if (rowsScrollController && columnsScrollController) { oldColumnViewportItemSize = columnsScrollController.viewportItemSize(); oldRowViewportItemSize = rowsScrollController.viewportItemSize(); rowsScrollController.viewportItemSize(rowViewportItemSize); columnsScrollController.viewportItemSize(columnViewportItemSize); rowsScrollController.viewportSize(contentParams.viewportHeight / rowsScrollController.viewportItemSize()); rowsScrollController.setContentSize(contentParams.contentHeight); columnsScrollController.viewportSize(contentParams.viewportWidth / columnsScrollController.viewportItemSize()); columnsScrollController.setContentSize(contentParams.contentWidth); commonUtils.deferUpdate(function () { columnsScrollController.loadIfNeed(); rowsScrollController.loadIfNeed(); }); newLeftPosition = columnsScrollController.getViewportPosition() * columnViewportItemSize / oldColumnViewportItemSize; newTopPosition = rowsScrollController.getViewportPosition() * rowViewportItemSize / oldRowViewportItemSize; that.setViewportPosition(newLeftPosition, newTopPosition); that.scrollChanged.fire({ left: newLeftPosition, top: newTopPosition }); return { contentTop: rowsScrollController.getContentOffset(), contentLeft: columnsScrollController.getContentOffset(), width: columnsScrollController.getVirtualContentSize(), height: rowsScrollController.getVirtualContentSize() }; } }, setViewportPosition: function setViewportPosition(left, top) { this._rowsScrollController.setViewportPosition(top || 0); this._columnsScrollController.setViewportPosition(left || 0); }, subscribeToWindowScrollEvents: function subscribeToWindowScrollEvents($element) { this._rowsScrollController && this._rowsScrollController.subscribeToWindowScrollEvents($element); }, updateWindowScrollPosition: function updateWindowScrollPosition(position) { this._rowsScrollController && this._rowsScrollController.scrollTo(position); }, updateViewOptions: function updateViewOptions(options) { extend(this._options, options); this._update(); }, _handleExpandValueChanging: function _handleExpandValueChanging(e) { this.expandValueChanging.fire(e); }, _handleLoadingChanged: function _handleLoadingChanged(isLoading) { this.loadingChanged.fire(isLoading); }, _handleProgressChanged: function _handleProgressChanged(progress) { this.progressChanged.fire(progress); }, _handleFieldsPrepared: function _handleFieldsPrepared(e) { this._options.onFieldsPrepared && this._options.onFieldsPrepared(e); }, _createDataSource: function _createDataSource(options) { var that = this, dataSourceOptions = options.dataSource, dataSource; that._isSharedDataSource = dataSourceOptions instanceof PivotGridDataSource; if (that._isSharedDataSource) { dataSource = dataSourceOptions; } else { dataSource = new PivotGridDataSource(dataSourceOptions); } that._expandValueChangingHandler = that._handleExpandValueChanging.bind(that); that._loadingChangedHandler = that._handleLoadingChanged.bind(that); that._progressChangedHandler = function (progress) { that._handleProgressChanged(progress * 0.8); }; that._fieldsPreparedHandler = that._handleFieldsPrepared.bind(that); that._changedHandler = function () { that._update(); that.dataSourceChanged.fire(); }; 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); return dataSource; }, getDataSource: function getDataSource() { return this._dataSource; }, isLoading: function isLoading() { return this._dataSource.isLoading(); }, beginLoading: function beginLoading() { this._dataSource.beginLoading(); }, endLoading: function endLoading() { this._dataSource.endLoading(); }, isEmpty: function isEmpty() { var dataFields = this._dataSource.getAreaFields("data"), data = this._dataSource.getData(); return !dataFields.length || !data.values.length; }, _update: function _update() { var that = this, dataSource = that._dataSource, options = that._options, columnFields = dataSource.getAreaFields("column"), rowFields = dataSource.getAreaFields("row"), dataFields = dataSource.getAreaFields("data"), dataFieldsForRows = options.dataFieldArea === "row" ? dataFields : [], dataFieldsForColumns = options.dataFieldArea !== "row" ? dataFields : [], data = dataSource.getData(), hiddenTotals = getHiddenTotals(dataFields), hiddenValues = getHiddenValues(dataFields), hiddenGrandTotals = getHiddenGrandTotalsTotals(dataFields, columnFields), grandTotalsAreHiddenForNotAllDataFields = dataFields.length > 0 ? hiddenGrandTotals.length !== dataFields.length : true, notifyProgress = function notifyProgress(progress) { this.progress = progress; that._handleProgressChanged(0.8 + 0.1 * rowOptions.progress + 0.1 * columnOptions.progress); }, rowOptions = { isEmptyGrandTotal: data.isEmptyGrandTotalRow, texts: options.texts || {}, hiddenTotals: hiddenTotals, hiddenValues: hiddenValues, hiddenGrandTotals: [], showTotals: options.showRowTotals, showGrandTotals: options.showRowGrandTotals !== false && grandTotalsAreHiddenForNotAllDataFields, sortBySummaryPaths: createSortPaths(columnFields, dataFields), showTotalsPrior: options.showTotalsPrior === "rows" || options.showTotalsPrior === "both", showEmpty: !options.hideEmptySummaryCells, layout: options.rowHeaderLayout, fields: rowFields, dataFields: dataFields, progress: 0, notifyProgress: notifyProgress }, columnOptions = { isEmptyGrandTotal: data.isEmptyGrandTotalColumn, texts: options.texts || {}, hiddenTotals: hiddenTotals, hiddenValues: hiddenValues, hiddenGrandTotals: hiddenGrandTotals, showTotals: options.showColumnTotals, showTotalsPrior: options.showTotalsPrior === "columns" || options.showTotalsPrior === "both", showGrandTotals: options.showColumnGrandTotals !== false && grandTotalsAreHiddenForNotAllDataFields, sortBySummaryPaths: createSortPaths(rowFields, dataFields), showEmpty: !options.hideEmptySummaryCells, fields: columnFields, dataFields: dataFields, progress: 0, notifyProgress: notifyProgress }; if (!typeUtils.isDefined(data.grandTotalRowIndex)) { data.grandTotalRowIndex = getHeaderIndexedItems(data.rows, rowOptions).length; } if (!typeUtils.isDefined(data.grandTotalColumnIndex)) { data.grandTotalColumnIndex = getHeaderIndexedItems(data.columns, columnOptions).length; } dataSource._changeLoadingCount(1); when(createHeaderInfo(data.columns, columnFields, dataFieldsForColumns, true, columnOptions), createHeaderInfo(data.rows, rowFields, dataFieldsForRows, false, rowOptions)).always(function () { dataSource._changeLoadingCount(-1); }).done(function (columnsInfo, rowsInfo) { that._columnsInfo = columnsInfo; that._rowsInfo = rowsInfo; if (that._rowsScrollController && that._columnsScrollController && that.changed) { that._rowsScrollController.reset(); that._columnsScrollController.reset(); that._lockChanged = true; that._rowsScrollController.load(); that._columnsScrollController.load(); that._lockChanged = false; } }).done(function () { that._fireChanged(); if (that._stateStoringController.isEnabled() && !that._dataSource.isLoading()) { that._stateStoringController.state(that._dataSource.state()); that._stateStoringController.save(); } }); }, getRowsInfo: function getRowsInfo(getAllData) { var that = this, rowsInfo = that._rowsInfo, scrollController = that._rowsScrollController, rowspan, i; if (scrollController && !getAllData) { var startIndex = scrollController.beginPageIndex() * that.rowPageSize(), endIndex = scrollController.endPageIndex() * that.rowPageSize() + that.rowPageSize(), newRowsInfo = [], maxDepth = 1; foreachRowInfo(rowsInfo, function (rowInfo, visibleIndex, rowIndex, _, columnIndex) { var isVisible = visibleIndex >= startIndex && rowIndex < endIndex, index = rowIndex < startIndex ? 0 : rowIndex - startIndex, 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 = extend({}, cell, { rowspan: rowspan }); } newRowsInfo[index].push(cell); maxDepth = math.max(maxDepth, columnIndex + 1); } else if (i > endIndex) { return false; } }); foreachRowInfo(newRowsInfo, function (rowInfo, visibleIndex, rowIndex, columnIndex, realColumnIndex) { var colspan = rowInfo.colspan || 1; if (realColumnIndex + colspan > maxDepth) { newRowsInfo[rowIndex][columnIndex] = extend({}, rowInfo, { colspan: maxDepth - realColumnIndex || 1 }); } }); return newRowsInfo; } return rowsInfo; }, getColumnsInfo: function getColumnsInfo(getAllData) { var that = this, info = that._columnsInfo, scrollController = that._columnsScrollController; if (scrollController && !getAllData) { var startIndex = scrollController.beginPageIndex() * that.columnPageSize(), endIndex = scrollController.endPageIndex() * that.columnPageSize() + that.columnPageSize(); info = virtualColumnsCore.createColumnsInfo(info, startIndex, endIndex); } return info; }, totalRowCount: function totalRowCount() { return this._rowsInfo.length; }, rowPageIndex: function rowPageIndex(index) { if (index !== undefined) { this._rowPageIndex = index; } return this._rowPageIndex || 0; }, totalColumnCount: function totalColumnCount() { var count = 0; if (this._columnsInfo && this._columnsInfo.length) { for (var i = 0; i < this._columnsInfo[0].length; i++) { count += this._columnsInfo[0][i].colspan || 1; } } return count; }, rowPageSize: function rowPageSize(size) { if (size !== undefined) { this._rowPageSize = size; } return this._rowPageSize || 20; }, columnPageSize: function columnPageSize(size) { if (size !== undefined) { this._columnPageSize = size; } return this._columnPageSize || 20; }, columnPageIndex: function columnPageIndex(index) { if (index !== undefined) { this._columnPageIndex = index; } return this._columnPageIndex || 0; }, getCellsInfo: function getCellsInfo(getAllData) { var rowsInfo = this.getRowsInfo(getAllData), columnsInfo = this.getColumnsInfo(getAllData), data = this._dataSource.getData(), texts = this._options.texts || {}; return createCellsInfo(rowsInfo, columnsInfo, data, this._dataSource.getAreaFields("data"), this._options.dataFieldArea, texts.dataNotAvailable); }, dispose: function dispose() { var that = this; if (that._isSharedDataSource) { that._dataSource.off("changed", that._changedHandler); that._dataSource.off("expandValueChanging", that._expandValueChangingHandler); that._dataSource.off("loadingChanged", that._loadingChangedHandler); that._dataSource.off("progressChanged", that._progressChangedHandler); } else { that._dataSource.dispose(); } that._columnsScrollController && that._columnsScrollController.dispose(); that._rowsScrollController && that._rowsScrollController.dispose(); that._stateStoringController.dispose(); that.expandValueChanging.empty(); that.changed.empty(); that.loadingChanged.empty(); that.progressChanged.empty(); that.scrollChanged.empty(); that.dataSourceChanged.empty(); } }; proxyMethod(members, "applyPartialDataSource"); proxyMethod(members, "collapseHeaderItem"); proxyMethod(members, "expandHeaderItem"); proxyMethod(members, "getData"); return members; }());