Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pivot] New sheet names for show-details. #3630

Merged
merged 8 commits into from
Jul 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions cell/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -7038,15 +7038,17 @@ var editor;
if (!pivotTable) {
return false;
}
this._addWorksheets([this.asc_createSheetName()], this.wbModel.getActive(), function(worksheets){
const indexes = pivotTable.getItemsIndexesByActiveCell(activeCell.row, activeCell.col);
const itemMapArray = pivotTable.getNoFilterItemFieldsMapArray(indexes.rowItemIndex, indexes.colItemIndex)
this._addWorksheets([pivotTable.getShowDetailsSheetName(itemMapArray)], this.wbModel.getActive(), function(worksheets){
let ws = worksheets[0];
if (!ws) {
return;
}
History.Create_NewPoint();
History.StartTransaction();

let lengths = pivotTable.showDetails(ws, activeCell.row, activeCell.col);
let lengths = pivotTable.showDetails(ws, itemMapArray);

let range = new Asc.Range(0, 0, lengths.colLength, lengths.rowLength);
let ref = range.getAbsName();
Expand Down
181 changes: 133 additions & 48 deletions cell/model/PivotTables.js
Original file line number Diff line number Diff line change
Expand Up @@ -2598,7 +2598,7 @@ CT_PivotCacheRecords.prototype.updateCacheData = function() {
};
/**
* @param {Worksheet} ws
* @param {Map.<number, Map<number, number>} itemMap
* @param {PivotItemFieldsMap} itemMap
* @param {CT_CacheFields} cacheFields
* @return {boolean[]}
*/
Expand All @@ -2624,7 +2624,7 @@ CT_PivotCacheRecords.prototype.getRowMapByItemMap = function(itemMap, cacheField
* @param {Worksheet} ws
* @param {Map<number, number>} rowMap rows to copy
* @param {CT_CacheFields} cacheFields
* @return {Object}
* @return {FillPivotDetailsLengths}
*/
CT_PivotCacheRecords.prototype.copyRowsToWorksheet = function(ws, rowMap, cacheFields) {
let rowsAddedByMap = 0;
Expand Down Expand Up @@ -2658,11 +2658,16 @@ CT_PivotCacheRecords.prototype.copyRowsToWorksheet = function(ws, rowMap, cacheF
colLength: this._cols.length - 1,
};
};
/**
* @typedef FillPivotDetailsLengths
* @property {number} rowLength
* @property {number} colLength
*/
/**
* @param {Worksheet} ws
* @param {Map.<number, Map<number, number>} itemMap
* @param {PivotItemFieldsMap} itemMap
* @param {CT_CacheFields} cacheFields
* @return {Object} lengths
* @return {FillPivotDetailsLengths} lengths
*/
CT_PivotCacheRecords.prototype.fillPivotDetails = function(ws, itemMap, cacheFields) {
let cacheFieldsWithoutGroups = cacheFields.filter(function(field, index) {
Expand Down Expand Up @@ -3871,11 +3876,16 @@ CT_pivotTableDefinition.prototype.getPivotTableButtons = function (range, button
}
this._getPivotLabelButtons(range, buttons);
};
/**
* @typedef ItemsIndexesByActiveCell
* @property {number} rowItemIndex
* @property {number} colItemIndex
*/
/**
* Returns the rowItems and colItems indexes in the pivot table for the active cell (row, column)
* @param {number} row cell's row in editor
* @param {number} col cell's col in editor
* @return {Object}
* @return {ItemsIndexesByActiveCell | null}
*/
CT_pivotTableDefinition.prototype.getItemsIndexesByActiveCell = function(row, col) {
let pivotRange = this.getRange();
Expand Down Expand Up @@ -6938,79 +6948,148 @@ CT_pivotTableDefinition.prototype._groupDiscreteAddFields = function(fld, parFld
}
}
};

/**
* @typedef {[number, number][]} PivotItemFieldsMapArray
* [pivotFieldIndex, fieldItemIndex] array which describes the item by the all fields of the pivot table
*/
/**
* Returns an array that stores the Map<pivotFieldIndex, Map<fieldItem.x, number>(Set-like map)>,
* which describes the values of this item in each field
* @param {number} rowItemIndex item index rowItems array.
* @param {number} colItemIndex item index colItems array.
* @return {Map.<number, Map<number, number>}
* @param {number} rowItemIndex
* @param {number} colItemIndex
* @return {PivotItemFieldsMapArray} [pivotFieldIndex, fieldItem.x] array
*/
CT_pivotTableDefinition.prototype.getItemFieldsMap = function(rowItemIndex, colItemIndex) {
let rowItems = this.getRowItems();
let colItems = this.getColItems();
let rowFields = this.asc_getRowFields();
let colFields = this.asc_getColumnFields();
let filterMaps = this.getFilterMaps({});
let searchRowItem = rowItems && rowItems[rowItemIndex];
let searchColItem = colItems && colItems[colItemIndex];
let pivotFields = this.asc_getPivotFields();
let result = new Map();
filterMaps.labelFilters.forEach(function (filter) {
result.set(filter.index, filter.map);
});
CT_pivotTableDefinition.prototype.getNoFilterItemFieldsMapArray = function(rowItemIndex, colItemIndex) {
const rowItems = this.getRowItems();
const colItems = this.getColItems();
const rowFields = this.asc_getRowFields();
const colFields = this.asc_getColumnFields();
const searchRowItem = rowItems && rowItems[rowItemIndex];
const searchColItem = colItems && colItems[colItemIndex];
const pivotFields = this.asc_getPivotFields();
const result = [];

function getRowColFieldsMap(searchItemIndex, rowColFields, items) {
let searchItem = items[searchItemIndex];
const searchItem = items[searchItemIndex];
let r = null;

function getIndexes(item, length) {
for (let i = 0; i < item.x.length && i < length; i+= 1) {
let x = item.x[i];
let pivotFieldIndex = rowColFields[item.getR() + i].asc_getIndex();
for (let i = length - 1; i >= 0; i -= 1) {
const x = item.x[i];
const pivotFieldIndex = rowColFields[item.getR() + i].asc_getIndex();
if (pivotFieldIndex !== AscCommonExcel.st_VALUES) {
let res = new Map();
let fieldItem = pivotFields[pivotFieldIndex].getItem(x.getV());
res.set(fieldItem.x, 1);
result.set(pivotFieldIndex, res);
const fieldItem = pivotFields[pivotFieldIndex].getItem(x.getV());
result.unshift([pivotFieldIndex, fieldItem.x]);
}
}
r = item.getR() - 1;
}
getIndexes(searchItem, searchItem.x.length);
for (let i = searchItemIndex - 1; i >= 0 && r >= 0; i-= 1) {
let item = items[i];
const item = items[i];
if (item.getR() <= r) {
getIndexes(item, r - item.getR() + 1);
}
}
}
if (searchColItem && searchColItem.t !== Asc.c_oAscItemType.Grand) {
getRowColFieldsMap(colItemIndex, colFields, colItems);
}
if (searchRowItem && searchRowItem.t !== Asc.c_oAscItemType.Grand) {
getRowColFieldsMap(rowItemIndex, rowFields, rowItems);
}
if (searchColItem && searchColItem.t !== Asc.c_oAscItemType.Grand) {
getRowColFieldsMap(colItemIndex, colFields, colItems);
return result;
}
/** @typedef {Map<number, Map<number, number>} PivotItemFieldsMap */
/**
* Returns Map<pivotFieldIndex, Map<fieldItem.x, number>(Set-like map)>,
* which describes the values of this item in each field with filters.
* @param {PivotItemFieldsMapArray} itemFieldsMapArray
* @return {PivotItemFieldsMap}
*/
CT_pivotTableDefinition.prototype.getItemFieldsMap = function(itemFieldsMapArray) {
const filterMaps = this.getFilterMaps({});
const result = new Map();
filterMaps.labelFilters.forEach(function (filter) {
result.set(filter.index, filter.map);
});
for(let i = 0; i < itemFieldsMapArray.length; i += 1) {
const value = itemFieldsMapArray[i];
const pivotFieldIndex = value[0];
const fieldItemIndex = value[1];
const res = new Map();
res.set(fieldItemIndex, 1);
result.set(pivotFieldIndex, res);
}
return result;
};
/**
* @param {Worksheet} ws
* @param {number} row
* @param {number} col
* @param {PivotItemFieldsMapArray} arrayFieldItemsMap
* @return {Object}
*/
CT_pivotTableDefinition.prototype.showDetails = function(ws, row, col) {
let rowItems = this.getRowItems();
let colItems = this.getColItems();
let indexes = this.getItemsIndexesByActiveCell(row, col);
if (indexes === null || rowItems[indexes.rowItemIndex].t === Asc.c_oAscItemType.Blank || colItems[indexes.colItemIndex].t === Asc.c_oAscItemType.Blank) {
return false;
}
let itemMap = this.getItemFieldsMap(indexes.rowItemIndex, indexes.colItemIndex);
let cacheFields = this.asc_getCacheFields();
let records = this.getRecords();
CT_pivotTableDefinition.prototype.showDetails = function(ws, arrayFieldItemsMap) {
const itemMap = this.getItemFieldsMap(arrayFieldItemsMap);
const cacheFields = this.asc_getCacheFields();
const records = this.getRecords();
return records.fillPivotDetails(ws, itemMap, cacheFields);
};

/**
* @param {PivotItemFieldsMapArray} arrayFieldItemsMap
* @return {string} sheetName
*/
CT_pivotTableDefinition.prototype.getShowDetailsSheetName = function(arrayFieldItemsMap) {
/**
* @param {RegExp} re
* @param {string[]} arr
* @return {number}
*/
function reIndexOf(re, arr) {
for(let i = 0; i < arr.length; i += 1) {
const str = arr[i];
if (re.test(str)) {
return i;
}
}
return -1;
}
const cacheFields = this.asc_getCacheFields();
const workbook = this.worksheet.workbook;
const api = workbook.oApi;
const translatedInfoString = AscCommon.translateManager.getValue('Info');
let postfix = '';
arrayFieldItemsMap.forEach(function(value) {
const fieldIndex = value[0];
const itemIndex = value[1];
const cacheField = cacheFields[fieldIndex];
const sharedItem = cacheField.getGroupOrSharedItem(itemIndex);
if (sharedItem) {
const cellValue = sharedItem.getCellValue();
const numFormat = cacheField.num && cacheField.num.getNumFormat();
let res = cellValue.getTextValue();
if (numFormat && cellValue.type === AscCommon.CellValueType.Number) {
res = numFormat.formatToMathInfo(cellValue.number, AscCommon.CellValueType.Number, AscCommon.gc_nMaxDigCountView);
}
postfix += '-' + res;
}
});
const sheetNames = [];
const wc = api.asc_getWorksheetsCount();
for(let i = 0; i < wc; i += 1) {
sheetNames.push(api.asc_getWorksheetName(i));
}
let prefix;
for (let i = 1; ; i += 1) {
prefix = translatedInfoString + String(i);
const re = new RegExp('^' + prefix + '(-|$)');
if (reIndexOf(re, sheetNames) === -1) {
break;
}
}
let result = prefix + postfix;
if (result.length > AscCommonExcel.g_nSheetNameMaxLength) {
result = result.substring(0, AscCommonExcel.g_nSheetNameMaxLength);
}
return result;
}
CT_pivotTableDefinition.prototype.asc_canShowDetails = function(row, col) {
let indexes = this.getItemsIndexesByActiveCell(row, col);
if (indexes === null) {
Expand Down Expand Up @@ -9859,9 +9938,15 @@ CT_CacheField.prototype.getSharedItem = function (index) {
CT_CacheField.prototype.getSharedSize = function () {
return this.sharedItems && this.sharedItems.Items.getSize() || 0;
};
/**
* @return {CT_SharedItems | CT_FieldGroup | null}
*/
CT_CacheField.prototype.getGroupOrSharedItems = function () {
return (this.fieldGroup && this.fieldGroup.groupItems) || this.sharedItems;
};
/**
* @return {PivotRecords | CT_FieldGroup | null}
*/
CT_CacheField.prototype.getGroupOrSharedItem = function (index) {
var sharedItems = this.getGroupOrSharedItems();
return sharedItems && sharedItems.Items.get(index);
Expand Down
3 changes: 2 additions & 1 deletion cell/model/Workbook.js
Original file line number Diff line number Diff line change
Expand Up @@ -2809,7 +2809,7 @@
return -1;
};
Workbook.prototype.checkValidSheetName=function(name){
return (name && name.length < g_nSheetNameMaxLength);
return (name && name.length <= g_nSheetNameMaxLength);
};
Workbook.prototype.getUniqueSheetNameFrom=function(name, bCopy){
var nIndex = 1;
Expand Down Expand Up @@ -19114,6 +19114,7 @@

window['AscCommonExcel'] = window['AscCommonExcel'] || {};
window['AscCommonExcel'].g_nVerticalTextAngle = g_nVerticalTextAngle;
window['AscCommonExcel'].g_nSheetNameMaxLength = g_nSheetNameMaxLength;
window['AscCommonExcel'].oDefaultMetrics = oDefaultMetrics;
window['AscCommonExcel'].g_nAllColIndex = g_nAllColIndex;
window['AscCommonExcel'].g_nAllRowIndex = g_nAllRowIndex;
Expand Down
4 changes: 3 additions & 1 deletion tests/cell/spreadsheet-calculation/PivotTests.js
Original file line number Diff line number Diff line change
Expand Up @@ -5981,7 +5981,9 @@ var wb, ws, wsData, pivotStyle, tableName, defNameName, defNameLocalName, report
undoStandard[i].fill("");
}
let res = checkHistoryOperation2(assert, pivot, standard, message, undoStandard, function () {
pivot.showDetails(wsDetails, row, col);
const indexes = pivot.getItemsIndexesByActiveCell(row, col);
const arrayItemFieldsMap = pivot.getNoFilterItemFieldsMapArray(indexes.rowItemIndex, indexes.colItemIndex)
pivot.showDetails(wsDetails, arrayItemFieldsMap);
}, function (assert, pivot, standard, message) {
let cells = [];
for (let i = 0; i < standard.length; i += 1) {
Expand Down
Loading