diff --git a/library/src/main/resources/rawfile/vtable_util.js b/library/src/main/resources/rawfile/vtable_util.js index 78865f9997e345ded0d0825465f1e8c7edd20f66..29f46c716f162f25df82a7d39a83de5b92bc8e8d 100644 --- a/library/src/main/resources/rawfile/vtable_util.js +++ b/library/src/main/resources/rawfile/vtable_util.js @@ -100,12 +100,8 @@ var eventCallback = (type, data) => { let aa = window.tableInstance.getSelectedCellInfos() if (aa[0][0].col !== aa[aa.length - 1][aa[0].length - 1].col || aa[0][0].row !== aa[aa.length - 1][aa[0].length - 1].row) { console.log("=====> getSelectedCellInfos", JSON.stringify(aa[0][0].col)) - // console.log("=====> getSelectedCellInfos", JSON.stringify(aa[0][0].row)) - // console.log("=====> getSelectedCellInfos", JSON.stringify(aa[1][1].col)) - // console.log("=====> getSelectedCellInfos", JSON.stringify(aa[1][1].row)) window.tableInstance.unmergeCells(aa[0][0].col, aa[0][0].row, aa[aa.length - 1][aa[0].length - 1].col, aa[aa.length - 1][aa[0].length - 1].row) window.tableInstance.mergeCells(aa[0][0].col, aa[0][0].row, aa[aa.length - 1][aa[0].length - 1].col, aa[aa.length - 1][aa[0].length - 1].row) - // renderWithRecreateCells() } } } @@ -132,6 +128,10 @@ function frozenRow(index) { // 合并指定范围的单元格 function mergeCell(startCol, startRow, endCol, endRow) { + if (startCol == endCol && startRow == endRow) { + return; + } + if (!window.tableInstance) { console.error('表格实例未找到'); return; @@ -198,8 +198,10 @@ function unmergeCells(startCol, startRow, endCol, endRow) { } window.tableInstance.unmergeCells(a.start.col, a.start.row, a.end.col, a.end.row); // } + deleteDiagonal(startCol, startRow, endCol, endRow) } } + // 自定义渲染 function customRender(startCol, startRow, endCol, endRow, id, style) { const newcolumn = { @@ -468,70 +470,198 @@ function setDiagonal(startCol, startRow, endCol, endRow) { console.log("=====> unmergeCells", JSON.stringify(hasMergeCells)) if (!hasMergeCells) { - const newColumns = window.tableInstance.options.columns; - - const keySet = new Set(arr.map(item => `${item.col},${item.row}`)); - - for (let i = startCol; i <= endCol; i++) { - for (let j = startRow; j <= endRow; j++) { - const key = `${i},${j}`; - if (!keySet.has(key)) { - keySet.add(key); - arr.push({ col: i, row: j }); + newColumns.map((item) => { + item.customRender = (args) => { + colRow_ = { col: args.col, row: args.row } + + const exactExists = arr.some(item => + item.col === colRow_.col && item.row === colRow_.row + ); + + if (exactExists) { + return { + elements: [ + { + type: 'line', + elementKey: 'diagonal-line', + x: 0, + y: 0, + points: [ + { x: 0, y: 0 }, + { x: args.rect.width, y: args.rect.height } + ], + stroke: '#ff0000', + lineWidth: 2, + pickable: false, + cursor: 'default' + } + ], + renderDefault: true + } + } else { + return { + renderDefault: true } } } + window.tableInstance.updateColumns(newColumns, { clearColWidthCache: true }); - console.log("=====> setDiagonal", arr) - - - newColumns.map((item) => { - item.customRender = (args) => { - colRow_ = { col: args.col, row: args.row } - - const exactExists = arr.some(item => - item.col === colRow_.col && item.row === colRow_.row - ); - - if (exactExists) { - return { - elements: [ - { - type: 'line', - elementKey: 'diagonal-line', - x: 0, - y: 0, - points: [ - { x: 0, y: 0 }, - { x: args.rect.width, y: args.rect.height } - ], - stroke: '#ff0000', - lineWidth: 2, - pickable: false, - cursor: 'default' - } - ], - renderDefault: true - } - } else { - return { - renderDefault: true - } - } - } - }) + const options = window.tableInstance.options; + const mergeCells = options?.customMergeCell; + if (!mergeCells) return; + + const diagonalRender = args => ({ + elements: [{ + type: 'line', + elementKey: 'diagonal-line', + x: 0, y: 0, + points: [{ x: 0, y: 2 }, { x: args.rect.width, y: args.rect.height }], + stroke: '#ff0000', + lineWidth: 2, + pickable: false, + cursor: 'default' + }], + renderDefault: true + }); + + for (let i = 0, len = mergeCells.length; i < len; i++) { + const item = mergeCells[i]; + const start = item.range.start; + const end = item.range.end; + + if (start.col < startCol || start.row < startRow) continue; + if (end.col > endCol || end.row > endRow) continue; - window.tableInstance.updateColumns(newColumns, { clearColWidthCache: true }); + item.customRender = diagonalRender; } + + renderWithRecreateCells(); } function deleteDiagonal(startCol, startRow, endCol, endRow) { + const oldLength = arr.length; arr = arr.filter(item => { - const inRange = item.col >= startCol && item.col <= endCol && - item.row >= startRow && item.row <= endRow; - return !inRange; + return item.col < startCol || item.col > endCol || + item.row < startRow || item.row > endRow; }); - + + if (arr.length === oldLength) { + return; + } + + const diagonalSet = new Set(); + for (const item of arr) { + diagonalSet.add(`${item.col},${item.row}`); + } + + const diagonalRenderCache = (() => { + const cache = new Map(); + return (width, height) => { + const key = `${width},${height}`; + if (!cache.has(key)) { + cache.set(key, { + elements: [{ + type: 'line', + elementKey: 'diagonal-line', + x: 0, y: 0, + points: [{ x: 0, y: 0 }, { x: width, y: height }], + stroke: '#ff0000', + lineWidth: 2, + pickable: false, + cursor: 'default' + }], + renderDefault: true + }); + } + return cache.get(key); + }; + })(); + + const newColumns = window.tableInstance.options.columns; + const startColIdx = Math.max(0, startCol); + const endColIdx = Math.min(newColumns.length - 1, endCol); + + for (let colIndex = startColIdx; colIndex <= endColIdx; colIndex++) { + const column = newColumns[colIndex]; + if (!column) continue; + + let needUpdate = false; + for (let row = startRow; row <= endRow; row++) { + if (diagonalSet.has(`${colIndex},${row}`)) { + needUpdate = true; + break; + } + } + + if (needUpdate) { + const originalRender = column.customRender; + + column.customRender = (function (oriRender, colIdx) { + return (args) => { + const key = `${args.col},${args.row}`; + if (diagonalSet.has(key)) { + return diagonalRenderCache(args.rect.width, args.rect.height); + } + return oriRender ? oriRender(args) : { renderDefault: true }; + }; + })(originalRender, colIndex); + } + } + + const options = window.tableInstance.options; + const mergeCells = options?.customMergeCell; + + if (mergeCells) { + const mergedDiagonalRender = args => ({ + elements: [{ + type: 'line', + elementKey: 'diagonal-line-merged', + x: 0, y: 0, + points: [{ x: 0, y: 2 }, { x: args.rect.width, y: args.rect.height }], + stroke: '#ff0000', + lineWidth: 2, + pickable: false, + cursor: 'default' + }], + renderDefault: true + }); + + for (let i = 0, len = mergeCells.length; i < len; i++) { + const item = mergeCells[i]; + const start = item.range.start; + const end = item.range.end; + + if (start.col > endCol || end.col < startCol || + start.row > endRow || end.row < startRow) { + continue; + } + + const overlapStartCol = Math.max(start.col, startCol); + const overlapEndCol = Math.min(end.col, endCol); + const overlapStartRow = Math.max(start.row, startRow); + const overlapEndRow = Math.min(end.row, endRow); + + if (overlapStartCol <= overlapEndCol && overlapStartRow <= overlapEndRow) { + let hasDiagonal = false; + + for (let col = overlapStartCol; col <= overlapEndCol && !hasDiagonal; col++) { + for (let row = overlapStartRow; row <= overlapEndRow && !hasDiagonal; row++) { + if (diagonalSet.has(`${col},${row}`)) { + hasDiagonal = true; + } + } + } + + if (hasDiagonal) { + item.customRender = mergedDiagonalRender; + } else { + delete item.customRender; + } + } + } + } + + window.tableInstance.updateColumns(newColumns, { clearColWidthCache: true }); renderWithRecreateCells(); } \ No newline at end of file