mirror of
https://github.com/dream-num/univer.git
synced 2026-08-29 07:13:59 +08:00
perf(selection): formula and selection (#6197)
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { IDefinedNameMap } from '../../services/defined-names.service';
|
||||
import { Disposable, Inject } from '@univerjs/core';
|
||||
import { IFormulaCurrentConfigService } from '../../services/current-data.service';
|
||||
import { IDefinedNamesService } from '../../services/defined-names.service';
|
||||
@@ -29,6 +30,11 @@ export class Lexer extends Disposable {
|
||||
}
|
||||
|
||||
treeBuilder(formulaString: string, transformSuffix = true) {
|
||||
const definedNames = this._definedNamesService.getAllDefinedNames();
|
||||
if (this._isDeepDefinedNameMapEmpty(definedNames)) {
|
||||
return this._lexerTreeBuilder.treeBuilder(formulaString, transformSuffix);
|
||||
}
|
||||
|
||||
return this._lexerTreeBuilder.treeBuilder(formulaString, transformSuffix, {
|
||||
unitId: this._formulaCurrentConfigService.getExecuteUnitId(),
|
||||
getValueByName: this._definedNamesService.getValueByName.bind(this._definedNamesService),
|
||||
@@ -36,4 +42,13 @@ export class Lexer extends Disposable {
|
||||
getSheetName: this._formulaCurrentConfigService.getSheetName.bind(this._formulaCurrentConfigService),
|
||||
});
|
||||
}
|
||||
|
||||
private _isDeepDefinedNameMapEmpty(map: IDefinedNameMap): boolean {
|
||||
for (const unitId in map) {
|
||||
if (Object.keys(map[unitId]).length > 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,33 +184,31 @@ export class ReferenceNodeFactory extends BaseAstNodeFactory {
|
||||
const currentConfigService = this._currentConfigService;
|
||||
const runtimeService = this._formulaRuntimeService;
|
||||
|
||||
const tableMap = this._getTableMap();
|
||||
const isSuperTableDirect = tableMap?.has(tokenTrim) ?? false;
|
||||
|
||||
const isCellRange = regexTestSingeRange(tokenTrim);
|
||||
const parentIsUnion = isLexerNode && this._checkParentIsUnionOperator(param as LexerNode);
|
||||
const isRowRef = parentIsUnion && regexTestSingleRow(tokenTrim);
|
||||
const isColRef = parentIsUnion && regexTestSingleColumn(tokenTrim);
|
||||
|
||||
const makeRef = (type: ReferenceObjectType) =>
|
||||
new ReferenceNode(currentConfigService, runtimeService, tokenTrim, type, isPrepareMerge);
|
||||
|
||||
if (isSuperTableDirect) {
|
||||
return this._getTableReferenceNode(tokenTrim, isLexerNode, isPrepareMerge, true);
|
||||
}
|
||||
|
||||
const isCellRange = regexTestSingeRange(tokenTrim);
|
||||
if (isCellRange) {
|
||||
return makeRef(ReferenceObjectType.CELL);
|
||||
}
|
||||
const parentIsUnion = isLexerNode && this._checkParentIsUnionOperator(param as LexerNode);
|
||||
const isRowRef = parentIsUnion && regexTestSingleRow(tokenTrim);
|
||||
|
||||
if (isRowRef) {
|
||||
return makeRef(ReferenceObjectType.ROW);
|
||||
}
|
||||
const isColRef = parentIsUnion && regexTestSingleColumn(tokenTrim);
|
||||
|
||||
if (isColRef) {
|
||||
return makeRef(ReferenceObjectType.COLUMN);
|
||||
}
|
||||
|
||||
const tableMap = this._getTableMap();
|
||||
const isSuperTableDirect = tableMap?.has(tokenTrim) ?? false;
|
||||
if (isSuperTableDirect) {
|
||||
return this._getTableReferenceNode(tokenTrim, isLexerNode, isPrepareMerge, true);
|
||||
}
|
||||
|
||||
return this._getTableReferenceNode(tokenTrim, isLexerNode, isPrepareMerge, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -570,6 +570,7 @@ export class FormulaDependencyGenerator extends Disposable {
|
||||
const treeId = this._dependencyManagerService.getFormulaDependency(unitId, sheetId, row, column);
|
||||
if (treeId != null) {
|
||||
FDtree.treeId = treeId;
|
||||
FDtree.isCache = true;
|
||||
} else {
|
||||
this._dependencyManagerService.addFormulaDependency(unitId, sheetId, row, column, FDtree);
|
||||
this._dependencyManagerService.addFormulaDependencyByDefinedName(FDtree);
|
||||
@@ -604,6 +605,7 @@ export class FormulaDependencyGenerator extends Disposable {
|
||||
const treeId = this._dependencyManagerService.getFormulaDependency(unitId, sheetId, row, column);
|
||||
if (treeId != null) {
|
||||
FDtree.treeId = treeId;
|
||||
FDtree.isCache = true;
|
||||
} else {
|
||||
this._dependencyManagerService.addFormulaDependency(unitId, sheetId, row, column, FDtree);
|
||||
this._dependencyManagerService.addFormulaDependencyByDefinedName(FDtree);
|
||||
|
||||
@@ -124,7 +124,8 @@ export class BaseReferenceObject extends ObjectClassType {
|
||||
|
||||
getRangePosition() {
|
||||
const { x, y } = this.getRefOffset();
|
||||
let { startRow, startColumn, endRow, endColumn } = moveRangeByOffset(this.getRangeData(), x, y);
|
||||
const rangeData = this.getRangeData();
|
||||
let { startRow, startColumn, endRow, endColumn } = moveRangeByOffset(rangeData, x, y);
|
||||
|
||||
if (Number.isNaN(startRow)) {
|
||||
startRow = 0;
|
||||
@@ -143,7 +144,6 @@ export class BaseReferenceObject extends ObjectClassType {
|
||||
}
|
||||
|
||||
return {
|
||||
...this.getRangeData(),
|
||||
startRow,
|
||||
endRow,
|
||||
startColumn,
|
||||
|
||||
@@ -21,22 +21,20 @@ import { prefixToken } from '../../basics/token';
|
||||
import { FUNCTION_NAMES_META } from '../../functions/meta/function-names';
|
||||
import { PrefixNode } from '../ast-node/prefix-node';
|
||||
|
||||
const minusRegExp = new RegExp(prefixToken.MINUS, 'g');
|
||||
const atRegExp = new RegExp(prefixToken.AT, 'g');
|
||||
// const minusRegExp = new RegExp(prefixToken.MINUS, 'g');
|
||||
// const atRegExp = new RegExp(prefixToken.AT, 'g');
|
||||
|
||||
export function prefixHandler(tokenTrimParam: string, functionService: IFunctionService, runtimeService: IFormulaRuntimeService) {
|
||||
let minusPrefixNode: Nullable<PrefixNode>;
|
||||
let atPrefixNode: Nullable<PrefixNode>;
|
||||
let tokenTrim = tokenTrimParam;
|
||||
const prefix = tokenTrim.slice(0, 2);
|
||||
const prefix = tokenTrim[0];
|
||||
let sliceLength = 0;
|
||||
if (prefix[0] === prefixToken.MINUS) {
|
||||
if (prefix === prefixToken.MINUS) {
|
||||
const functionExecutor = functionService.getExecutor(FUNCTION_NAMES_META.MINUS);
|
||||
minusPrefixNode = new PrefixNode(runtimeService, prefixToken.MINUS, functionExecutor);
|
||||
sliceLength++;
|
||||
}
|
||||
|
||||
if (prefix[0] === prefixToken.AT) {
|
||||
} else if (prefix === prefixToken.AT) {
|
||||
atPrefixNode = new PrefixNode(runtimeService, prefixToken.AT);
|
||||
if (minusPrefixNode) {
|
||||
// minusPrefixNode.addChildren(atPrefixNode);
|
||||
|
||||
@@ -258,6 +258,10 @@ export class Transformer extends Disposable implements ITransformerConfig {
|
||||
}
|
||||
|
||||
clearSelectedObjects() {
|
||||
if (this._selectedObjectMap.size === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._selectedObjectMap.clear();
|
||||
this._cancelFocusSubscription?.unsubscribe();
|
||||
this._cancelFocusSubscription = null;
|
||||
|
||||
@@ -38,8 +38,8 @@ export class DataValidationCacheService extends Disposable {
|
||||
}
|
||||
|
||||
private _initDirtyRanges() {
|
||||
this.disposeWithMe(this._commandService.onCommandExecuted((commandInfo) => {
|
||||
if (commandInfo.id === SetRangeValuesMutation.id) {
|
||||
this.disposeWithMe(this._commandService.onCommandExecuted((commandInfo, options) => {
|
||||
if (commandInfo.id === SetRangeValuesMutation.id && !options?.onlyLocal) {
|
||||
const { cellValue, unitId, subUnitId } = commandInfo.params as ISetRangeValuesMutationParams;
|
||||
if (cellValue) {
|
||||
const range = new ObjectMatrix(cellValue).getDataRange();
|
||||
|
||||
@@ -174,7 +174,7 @@ export class FormulaEditorShowController extends Disposable implements IRenderMo
|
||||
}
|
||||
|
||||
private _displayArrayFormulaRangeShape(matrixRange: IObjectMatrixPrimitiveType<IRange>, row: number, col: number, unitId: string, subUnitId: string, worksheet: Worksheet, cellInfo: Nullable<ICellDataForSheetInterceptor>): Nullable<ICellDataForSheetInterceptor> {
|
||||
const sheetFormulaData = this._formulaDataModel.getSheetFormulaData(unitId, subUnitId);
|
||||
// const sheetFormulaData = this._formulaDataModel.getSheetFormulaData(unitId, subUnitId);
|
||||
|
||||
new ObjectMatrix(matrixRange).forValue((rowIndex, columnIndex, range) => {
|
||||
if (range == null) {
|
||||
@@ -188,19 +188,13 @@ export class FormulaEditorShowController extends Disposable implements IRenderMo
|
||||
if (row >= startRow && row <= endRow && col >= startColumn && col <= endColumn) {
|
||||
const mainCellValue = worksheet.getCell(startRow, startColumn);
|
||||
|
||||
if (mainCellValue?.v === ErrorType.SPILL) {
|
||||
if (mainCellValue?.v === ErrorType.SPILL || mainCellValue?.f == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const formulaDataItem = sheetFormulaData?.[rowIndex]?.[columnIndex];
|
||||
|
||||
if (formulaDataItem == null || formulaDataItem.f == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cellInfo == null) {
|
||||
cellInfo = {
|
||||
f: formulaDataItem.f,
|
||||
f: mainCellValue.f,
|
||||
isInArrayFormulaRange: true,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -449,6 +449,10 @@ export class SheetRenderController extends RxDisposable implements IRenderModule
|
||||
}
|
||||
|
||||
private _markUnitDirty(command: ICommandInfo) {
|
||||
if (command.id.substring(0, 3) === 'doc') {
|
||||
return;
|
||||
}
|
||||
|
||||
const { mainComponent: spreadsheet, scene } = this._context;
|
||||
|
||||
if (command.id === SetFormulaCalculationNotificationMutation.id) {
|
||||
|
||||
@@ -395,7 +395,7 @@ export class EditorBridgeService extends Disposable implements IEditorBridgeServ
|
||||
ed: body.dataStream.length - 2,
|
||||
ts: {
|
||||
cl: {
|
||||
rgb: this._themeService.getColorFromTheme('gray.600'),
|
||||
rgb: this._themeService.getColorFromTheme('gray.300'),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user