chore: put formulaCache into context and optimize code

This commit is contained in:
zyc9012 2022-05-06 10:39:19 +08:00
parent 1d7b03361a
commit 2d09db9c76
11 changed files with 325 additions and 761 deletions

View File

@ -1,5 +1,6 @@
import _ from "lodash";
import { SheetConfig } from ".";
import { FormulaCache } from "./modules";
import { normalizeSelection } from "./modules/selection";
import { Sheet, Selection, Cell, CommentBox, Rect, Image } from "./types";
import { getSheetIndex } from "./utils";
@ -123,6 +124,9 @@ export type Context = {
// 默认单元格
defaultCell: Cell;
groupValuesRefreshData: any[];
formulaCache: FormulaCache;
};
export function defaultContext(): Context {
@ -237,6 +241,9 @@ export function defaultContext(): Context {
m: "",
v: "",
},
groupValuesRefreshData: [],
formulaCache: new FormulaCache(), // class will not be frozen by immer, can be mutated at any time.
};
}

View File

@ -4,7 +4,6 @@ import { Context, getFlowdata } from "../context";
import {
cancelActiveImgItem,
cancelPaintModel,
formulaCache,
functionHTMLGenerate,
israngeseleciton,
rangeHightlightselected,
@ -323,10 +322,10 @@ export function handleCellAreaMouseDown(
// 公式相关
if (ctx.luckysheetCellUpdate.length > 0) {
if (
formulaCache.rangestart ||
formulaCache.rangedrag_column_start ||
formulaCache.rangedrag_row_start ||
israngeseleciton()
ctx.formulaCache.rangestart ||
ctx.formulaCache.rangedrag_column_start ||
ctx.formulaCache.rangedrag_row_start ||
israngeseleciton(ctx)
) {
// 公式选区
let rowseleted = [row_index, row_index_ed];
@ -338,7 +337,7 @@ export function handleCellAreaMouseDown(
let height = row - row_pre - 1;
if (e.shiftKey) {
const last = formulaCache.func_selectedrange;
const last = ctx.formulaCache.func_selectedrange;
top = 0;
height = 0;
@ -437,7 +436,7 @@ export function handleCellAreaMouseDown(
last.top_move = top;
last.height_move = height;
formulaCache.func_selectedrange = last;
ctx.formulaCache.func_selectedrange = last;
} else if (
e.ctrlKey &&
_.last(cellInput.querySelectorAll("span"))?.innerText !== ","
@ -462,7 +461,7 @@ export function handleCellAreaMouseDown(
// all browsers, except IE before version 9
const currSelection = window.getSelection();
if (currSelection == null) return;
formulaCache.functionRangeIndex = [
ctx.formulaCache.functionRangeIndex = [
_.indexOf(
currSelection.anchorNode?.parentNode?.parentNode?.childNodes,
// @ts-ignore
@ -474,7 +473,7 @@ export function handleCellAreaMouseDown(
// Internet Explorer before version 9
// @ts-ignore
const textRange = document.selection.createRange();
formulaCache.functionRangeIndex = textRange;
ctx.formulaCache.functionRangeIndex = textRange;
}
/* 在显示前重新 + 右侧的圆括号) */
@ -484,17 +483,17 @@ export function handleCellAreaMouseDown(
createRangeHightlight(ctx, vText);
}
formulaCache.rangestart = false;
formulaCache.rangedrag_column_start = false;
formulaCache.rangedrag_row_start = false;
ctx.formulaCache.rangestart = false;
ctx.formulaCache.rangedrag_column_start = false;
ctx.formulaCache.rangedrag_row_start = false;
fxInput.innerHTML = vText;
rangeHightlightselected(ctx, cellInput);
// 再进行 选区的选择
israngeseleciton();
formulaCache.func_selectedrange = {
israngeseleciton(ctx);
ctx.formulaCache.func_selectedrange = {
left,
width,
top,
@ -509,7 +508,7 @@ export function handleCellAreaMouseDown(
column_focus: col_index,
};
} else {
formulaCache.func_selectedrange = {
ctx.formulaCache.func_selectedrange = {
left,
width,
top,
@ -527,13 +526,13 @@ export function handleCellAreaMouseDown(
rangeSetValue(ctx, cellInput, { row: rowseleted, column: columnseleted });
formulaCache.rangestart = true;
formulaCache.rangedrag_column_start = false;
formulaCache.rangedrag_row_start = false;
ctx.formulaCache.rangestart = true;
ctx.formulaCache.rangedrag_column_start = false;
ctx.formulaCache.rangedrag_row_start = false;
formulaCache.selectingRangeIndex = formulaCache.rangechangeindex;
ctx.formulaCache.selectingRangeIndex = ctx.formulaCache.rangechangeindex!;
createFormulaRangeSelect(ctx, {
rangeIndex: formulaCache.rangechangeindex,
rangeIndex: ctx.formulaCache.rangechangeindex || 0,
left,
top,
width,
@ -1188,10 +1187,10 @@ export function handleCellAreaDoubleClick(
if (!flowdata) return;
if (
(ctx.luckysheetCellUpdate.length > 0 && formulaCache.rangestart) ||
formulaCache.rangedrag_column_start ||
formulaCache.rangedrag_row_start ||
israngeseleciton()
(ctx.luckysheetCellUpdate.length > 0 && ctx.formulaCache.rangestart) ||
ctx.formulaCache.rangedrag_column_start ||
ctx.formulaCache.rangedrag_row_start ||
israngeseleciton(ctx)
) {
return;
}
@ -1808,7 +1807,7 @@ function mouseRender(
// }!${range}`;
// }
// $("#luckysheet-dataVerificationRange-dialog input").val(range);
} else if (formulaCache.rangestart) {
} else if (ctx.formulaCache.rangestart) {
rangeDrag(
ctx,
e,
@ -4187,10 +4186,10 @@ export function handleRowHeaderMouseDown(
if (!_.isEmpty(ctx.luckysheetCellUpdate)) {
if (
formulaCache.rangestart ||
formulaCache.rangedrag_column_start ||
formulaCache.rangedrag_row_start ||
israngeseleciton()
ctx.formulaCache.rangestart ||
ctx.formulaCache.rangedrag_column_start ||
ctx.formulaCache.rangedrag_row_start ||
israngeseleciton(ctx)
// ||$("#luckysheet-ifFormulaGenerator-multiRange-dialog").is(":visible")
) {
// 公式选区
@ -4217,7 +4216,7 @@ export function handleRowHeaderMouseDown(
}
if (e.shiftKey) {
const last = formulaCache.func_selectedrange;
const last = ctx.formulaCache.func_selectedrange;
top = 0;
height = 0;
@ -4281,7 +4280,7 @@ export function handleRowHeaderMouseDown(
last.top_move = top;
last.height_move = height;
formulaCache.func_selectedrange = last;
ctx.formulaCache.func_selectedrange = last;
} else if (
e.ctrlKey &&
_.last(cellInput.querySelectorAll("span"))?.innerText !== ","
@ -4295,7 +4294,7 @@ export function handleRowHeaderMouseDown(
// all browsers, except IE before version 9
const currSelection = window.getSelection();
if (currSelection == null) return;
formulaCache.functionRangeIndex = [
ctx.formulaCache.functionRangeIndex = [
_.indexOf(
currSelection.anchorNode?.parentNode?.parentNode?.childNodes,
// @ts-ignore
@ -4307,7 +4306,7 @@ export function handleRowHeaderMouseDown(
// Internet Explorer before version 9
// @ts-ignore
const textRange = document.selection.createRange();
formulaCache.functionRangeIndex = textRange;
ctx.formulaCache.functionRangeIndex = textRange;
}
cellInput.innerHTML = vText;
@ -4315,16 +4314,16 @@ export function handleRowHeaderMouseDown(
createRangeHightlight(ctx, vText);
}
formulaCache.rangestart = false;
formulaCache.rangedrag_column_start = false;
formulaCache.rangedrag_row_start = false;
ctx.formulaCache.rangestart = false;
ctx.formulaCache.rangedrag_column_start = false;
ctx.formulaCache.rangedrag_row_start = false;
fxInput.innerHTML = vText;
rangeHightlightselected(ctx, cellInput);
// 再进行 选区的选择
israngeseleciton();
formulaCache.func_selectedrange = {
israngeseleciton(ctx);
ctx.formulaCache.func_selectedrange = {
left: colLocationByIndex(0, ctx.visibledatacolumn)[0],
width:
colLocationByIndex(0, ctx.visibledatacolumn)[1] -
@ -4342,7 +4341,7 @@ export function handleRowHeaderMouseDown(
column_focus: 0,
};
} else {
formulaCache.func_selectedrange = {
ctx.formulaCache.func_selectedrange = {
left: colLocationByIndex(0, ctx.visibledatacolumn)[0],
width:
colLocationByIndex(0, ctx.visibledatacolumn)[1] -
@ -4362,10 +4361,10 @@ export function handleRowHeaderMouseDown(
}
if (
formulaCache.rangestart ||
formulaCache.rangedrag_column_start ||
formulaCache.rangedrag_row_start ||
israngeseleciton()
ctx.formulaCache.rangestart ||
ctx.formulaCache.rangedrag_column_start ||
ctx.formulaCache.rangedrag_row_start ||
israngeseleciton(ctx)
) {
rangeSetValue(ctx, cellInput, {
row: rowseleted,
@ -4384,9 +4383,9 @@ export function handleRowHeaderMouseDown(
// $("#luckysheet-ifFormulaGenerator-multiRange-dialog input").val(range);
// }
formulaCache.rangedrag_row_start = true;
formulaCache.rangestart = false;
formulaCache.rangedrag_column_start = false;
ctx.formulaCache.rangedrag_row_start = true;
ctx.formulaCache.rangestart = false;
ctx.formulaCache.rangedrag_column_start = false;
// $("#fortune-formula-functionrange-select")
// .css({
@ -4607,10 +4606,10 @@ export function handleColumnHeaderMouseDown(
// 公式相关
if (!_.isEmpty(ctx.luckysheetCellUpdate)) {
if (
formulaCache.rangestart ||
formulaCache.rangedrag_column_start ||
formulaCache.rangedrag_row_start ||
israngeseleciton()
ctx.formulaCache.rangestart ||
ctx.formulaCache.rangedrag_column_start ||
ctx.formulaCache.rangedrag_row_start ||
israngeseleciton(ctx)
// ||
// $("#luckysheet-ifFormulaGenerator-multiRange-dialog").is(":visible")
) {
@ -4635,7 +4634,7 @@ export function handleColumnHeaderMouseDown(
}
if (e.shiftKey) {
const last = formulaCache.func_selectedrange;
const last = ctx.formulaCache.func_selectedrange;
left = 0;
width = 0;
@ -4696,7 +4695,7 @@ export function handleColumnHeaderMouseDown(
last.left_move = left;
last.width_move = width;
formulaCache.func_selectedrange = last;
ctx.formulaCache.func_selectedrange = last;
} else if (
e.ctrlKey &&
_.last(cellInput.querySelectorAll("span"))?.innerText !== ","
@ -4710,7 +4709,7 @@ export function handleColumnHeaderMouseDown(
// all browsers, except IE before version 9
const currSelection = window.getSelection();
if (currSelection == null) return;
formulaCache.functionRangeIndex = [
ctx.formulaCache.functionRangeIndex = [
_.indexOf(
currSelection.anchorNode?.parentNode?.parentNode?.childNodes,
// @ts-ignore
@ -4722,7 +4721,7 @@ export function handleColumnHeaderMouseDown(
// Internet Explorer before version 9
// @ts-ignore
const textRange = document.selection.createRange();
formulaCache.functionRangeIndex = textRange;
ctx.formulaCache.functionRangeIndex = textRange;
}
cellInput.innerHTML = vText;
@ -4731,16 +4730,16 @@ export function handleColumnHeaderMouseDown(
createRangeHightlight(ctx, vText);
}
formulaCache.rangestart = false;
formulaCache.rangedrag_column_start = false;
formulaCache.rangedrag_row_start = false;
ctx.formulaCache.rangestart = false;
ctx.formulaCache.rangedrag_column_start = false;
ctx.formulaCache.rangedrag_row_start = false;
fxInput.innerHTML = vText;
rangeHightlightselected(ctx, cellInput);
// 再进行 选区的选择
israngeseleciton();
formulaCache.func_selectedrange = {
israngeseleciton(ctx);
ctx.formulaCache.func_selectedrange = {
left,
width,
top: rowLocationByIndex(0, ctx.visibledatarow)[0],
@ -4758,7 +4757,7 @@ export function handleColumnHeaderMouseDown(
column_focus: col_index,
};
} else {
formulaCache.func_selectedrange = {
ctx.formulaCache.func_selectedrange = {
left,
width,
top: rowLocationByIndex(0, ctx.visibledatarow)[0],
@ -4778,10 +4777,10 @@ export function handleColumnHeaderMouseDown(
}
if (
formulaCache.rangestart ||
formulaCache.rangedrag_column_start ||
formulaCache.rangedrag_row_start ||
israngeseleciton()
ctx.formulaCache.rangestart ||
ctx.formulaCache.rangedrag_column_start ||
ctx.formulaCache.rangedrag_row_start ||
israngeseleciton(ctx)
) {
rangeSetValue(ctx, cellInput, {
row: [null, null],
@ -4800,9 +4799,9 @@ export function handleColumnHeaderMouseDown(
// $("#luckysheet-ifFormulaGenerator-multiRange-dialog input").val(range);
// }
formulaCache.rangedrag_column_start = true;
formulaCache.rangestart = false;
formulaCache.rangedrag_row_start = false;
ctx.formulaCache.rangedrag_column_start = true;
ctx.formulaCache.rangestart = false;
ctx.formulaCache.rangedrag_row_start = false;
// $("#fortune-formula-functionrange-select")
// .css({

View File

@ -5,7 +5,6 @@ import {
delFunctionGroup,
execfunction,
execFunctionGroup,
formulaCache,
functionCopy,
} from "../modules/formula";
import { getdatabyselection, getQKBorder } from "../modules/cell";
@ -25,7 +24,7 @@ function postPasteCut(
) {
// 单元格数据更新联动
const execF_rc: any = {};
formulaCache.execFunctionExist = [];
ctx.formulaCache.execFunctionExist = [];
// clearTimeout(refreshCanvasTimeOut);
for (let r = source.range.row[0]; r <= source.range.row[1]; r += 1) {
for (let c = source.range.column[0]; c <= source.range.column[1]; c += 1) {
@ -34,7 +33,7 @@ function postPasteCut(
}
execF_rc[`${r}_${c}_${source.sheetId}`] = 0;
formulaCache.execFunctionExist.push({ r, c, i: source.sheetId });
ctx.formulaCache.execFunctionExist.push({ r, c, i: source.sheetId });
}
}
@ -45,7 +44,7 @@ function postPasteCut(
}
execF_rc[`${r}_${c}_${target.sheetId}`] = 0;
formulaCache.execFunctionExist.push({ r, c, i: target.sheetId });
ctx.formulaCache.execFunctionExist.push({ r, c, i: target.sheetId });
}
}
@ -154,10 +153,10 @@ function postPasteCut(
ctx.luckysheetfile[getSheetIndex(ctx, target.sheetId)!].dataVerification =
target.curDataVerification;
formulaCache.execFunctionExist.reverse();
ctx.formulaCache.execFunctionExist.reverse();
// @ts-ignore
execFunctionGroup(ctx, null, null, null, null, target.curData);
formulaCache.execFunctionGlobalData = null;
ctx.formulaCache.execFunctionGlobalData = null;
// const index = getSheetIndex(ctx, ctx.currentSheetId);
// const file = ctx.luckysheetfile[index];

View File

@ -13,7 +13,6 @@ import {
execfunction,
execFunctionGroup,
functionHTMLGenerate,
formulaCache,
} from "./formula";
import {
convertSpanToShareString,
@ -627,7 +626,7 @@ export function mergeMoveMain(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export function cancelFunctionrangeSelected(ctx: Context) {
if (formulaCache.selectingRangeIndex === -1) {
if (ctx.formulaCache.selectingRangeIndex === -1) {
ctx.formulaRangeSelect = undefined;
}
// $("#luckysheet-row-count-show, #luckysheet-column-count-show").hide();
@ -645,9 +644,9 @@ export function cancelNormalSelected(ctx: Context) {
// $("#luckysheet-input-box-index").hide();
// $("#luckysheet-wa-functionbox-cancel, #luckysheet-wa-functionbox-confirm").removeClass("luckysheet-wa-calculate-active");
formulaCache.rangestart = false;
formulaCache.rangedrag_column_start = false;
formulaCache.rangedrag_row_start = false;
ctx.formulaCache.rangestart = false;
ctx.formulaCache.rangedrag_column_start = false;
ctx.formulaCache.rangedrag_row_start = false;
}
// formula.updatecell
@ -1042,7 +1041,7 @@ export function updateCell(
// );
// }, 0);
formulaCache.execFunctionGlobalData = null;
ctx.formulaCache.execFunctionGlobalData = null;
/*
if (isRefresh) {
jfrefreshgrid(

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ import {
getStyleByCell,
mergeBorder,
} from "./cell";
import { delFunctionGroup, formulaCache } from "./formula";
import { delFunctionGroup } from "./formula";
import clipboard from "./clipboard";
import { getBorderInfoCompute } from "./border";
import { getSheetIndex, replaceHtml } from "../utils";
@ -674,7 +674,7 @@ export function moveHighlightCell(
// TODO pivotTable.pivotclick(row_index, col_index);
// TODO formula.fucntionboxshow(row_index, col_index);
} else if (type === "rangeOfFormula") {
const last = formulaCache.func_selectedrange;
const last = ctx.formulaCache.func_selectedrange;
if (!last) return;
let curR;
@ -783,7 +783,7 @@ export function moveHighlightCell(
return;
}
formulaCache.func_selectedrange = {
ctx.formulaCache.func_selectedrange = {
left: col_pre,
width: col - col_pre - 1,
top: row_pre,

View File

@ -15,7 +15,6 @@ import { genarate, is_date, update } from "./format";
import {
execfunction,
execFunctionGroup,
formulaCache,
israngeseleciton,
rangeSetValue,
setCaretPosition,
@ -357,7 +356,7 @@ function activeFormulaInput(
cellInput.innerHTML = formulaTxt;
const spanList = cellInput.querySelectorAll("span");
setCaretPosition(spanList[spanList.length - 2], 0, 1);
setCaretPosition(ctx, spanList[spanList.length - 2], 0, 1);
return;
}
@ -377,13 +376,13 @@ function activeFormulaInput(
)}</span><span dir="auto" class="luckysheet-formula-text-color">)</span>`;
cellInput.innerHTML = formulaTxt;
israngeseleciton();
formulaCache.rangestart = true;
formulaCache.rangedrag_column_start = false;
formulaCache.rangedrag_row_start = false;
formulaCache.rangechangeindex = 0;
israngeseleciton(ctx);
ctx.formulaCache.rangestart = true;
ctx.formulaCache.rangedrag_column_start = false;
ctx.formulaCache.rangedrag_row_start = false;
ctx.formulaCache.rangechangeindex = 0;
rangeSetValue(ctx, cellInput, { row: rowh, column: columnh });
formulaCache.func_selectedrange = {
ctx.formulaCache.func_selectedrange = {
left: col_pre,
width: col - col_pre - 1,
top: row_pre,
@ -397,7 +396,7 @@ function activeFormulaInput(
};
createFormulaRangeSelect(ctx, {
rangeIndex: formulaCache.rangeIndex,
rangeIndex: ctx.formulaCache.rangeIndex || 0,
left: col_pre,
width: col - col_pre - 1,
top: row_pre,
@ -433,7 +432,8 @@ function backFormulaInput(
const v = execfunction(ctx, f, r, c);
const value = { v: v[1], f: v[2] };
setCellValue(ctx, r, c, d, value);
formulaCache.execFunctionExist.push({
ctx.formulaCache.execFunctionExist ||= [];
ctx.formulaCache.execFunctionExist.push({
r,
c,
i: ctx.currentSheetId,
@ -668,7 +668,7 @@ export function autoSelectionFormula(
if (flowdata == null) return;
// const nullfindnum = 40;
let isfalse = true;
formulaCache.execFunctionExist = [];
ctx.formulaCache.execFunctionExist = [];
function execFormulaInput_c(
d: CellMatrix,
@ -836,10 +836,10 @@ export function autoSelectionFormula(
}
if (!isfalse) {
formulaCache.execFunctionExist.reverse();
ctx.formulaCache.execFunctionExist.reverse();
// @ts-ignore
execFunctionGroup(ctx, null, null, null, null, flowdata);
formulaCache.execFunctionGlobalData = null;
ctx.formulaCache.execFunctionGlobalData = null;
}
}

View File

@ -6,7 +6,7 @@ import {
handleWithCtrlOrMetaKey,
} from "../../src/events/keyboard";
import { getFlowdata } from "../../src/context";
import { formulaCache, groupValuesRefresh } from "../../src";
import { groupValuesRefresh } from "../../src";
describe("keyboard", () => {
const keypressWithCtrlPressed = (key) => {
@ -232,8 +232,7 @@ describe("keyboard", () => {
cellInput.innerText = item.newCell;
ctx.luckysheetCellUpdate = [0, 1];
handleGlobalEnter(ctx, cellInput, keyboardEvent);
const refreshData = formulaCache.groupValuesRefreshData;
groupValuesRefresh(ctx, refreshData);
groupValuesRefresh(ctx);
expect(getFlowdata(ctx)[0][2].v).toBe(item.v3);
expect(getFlowdata(ctx)[0][3].v).toBe(item.v4);
});

View File

@ -1,4 +1,4 @@
import { Context } from "../../src";
import { Context, FormulaCache } from "../../src";
export function selectionFactory(
row: number[],
@ -60,6 +60,8 @@ export function contextFactory({
scrollTop: 0,
luckysheet_shiftkeydown: false,
zoomRatio: 1,
groupValuesRefreshData: [],
formulaCache: new FormulaCache(),
...params,
};
}

View File

@ -5,7 +5,6 @@ import {
updateContextWithSheetData,
groupValuesRefresh,
handleGlobalWheel,
formulaCache,
initFreeze,
Sheet as SheetType,
} from "@fortune-sheet/core";
@ -87,12 +86,8 @@ const Sheet: React.FC<Props> = ({ sheet }) => {
*/
useEffect(() => {
// update formula chains value first if not empty
if (formulaCache.groupValuesRefreshData.length > 0) {
const refreshData = formulaCache.groupValuesRefreshData;
formulaCache.groupValuesRefreshData = [];
setContext((draftCtx) => {
groupValuesRefresh(draftCtx, refreshData);
});
if (context.groupValuesRefreshData.length > 0) {
// wait for it to be refreshed
return;
}
const tableCanvas = new Canvas(canvasRef.current!, context);
@ -224,6 +219,17 @@ const Sheet: React.FC<Props> = ({ sheet }) => {
}
}, [context, refs.globalCache.freezen, setContext, sheet.id]);
/**
* Apply the calculation results
*/
useEffect(() => {
if (context.groupValuesRefreshData.length > 0) {
setContext((draftCtx) => {
groupValuesRefresh(draftCtx);
});
}
}, [context.groupValuesRefreshData.length, setContext]);
const onWheel = useCallback(
(e: WheelEvent) => {
setContext((draftCtx) => {

View File

@ -1,4 +1,3 @@
import { formulaCache } from "@fortune-sheet/core";
import React, { useContext } from "react";
import WorkbookContext from "../../../context";
import "./index.css";
@ -7,7 +6,7 @@ const FormulaHint: React.FC<React.HTMLAttributes<HTMLDivElement>> = (props) => {
const { context } = useContext(WorkbookContext);
if (!context.functionHint) return null;
const fn = formulaCache.functionlistMap[context.functionHint];
const fn = context.formulaCache.functionlistMap[context.functionHint];
if (!fn) return null;
return (