mirror of
https://github.com/dream-num/univer.git
synced 2026-09-01 15:29:43 +08:00
fix(engine-render): fix some issues when hiding the first row of merged cells (#5904)
This commit is contained in:
@@ -47,14 +47,19 @@ export class Custom extends SheetExtension {
|
||||
if (!worksheet.getRowVisible(row) || !worksheet.getColVisible(col)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let primaryWithCoord = skeleton.getCellWithCoordByIndex(row, col, false);
|
||||
const { mergeInfo } = primaryWithCoord;
|
||||
|
||||
let cellData = worksheet.getCell(row, col);
|
||||
if (primaryWithCoord.isMerged) {
|
||||
cellData = worksheet.getCell(mergeInfo.startRow, mergeInfo.startColumn);
|
||||
}
|
||||
|
||||
if (!cellData?.customRender) {
|
||||
return;
|
||||
}
|
||||
|
||||
let primaryWithCoord = skeleton.getCellWithCoordByIndex(row, col, false);
|
||||
|
||||
const { mergeInfo } = primaryWithCoord;
|
||||
if (!this.isRenderDiffRangesByRow(mergeInfo.startRow, mergeInfo.endRow, diffRanges)) {
|
||||
return true;
|
||||
}
|
||||
@@ -69,16 +74,7 @@ export class Custom extends SheetExtension {
|
||||
}
|
||||
|
||||
if (primaryWithCoord.isMerged) {
|
||||
const mainCell = {
|
||||
row: mergeInfo.startRow,
|
||||
col: mergeInfo.startColumn,
|
||||
};
|
||||
cellData = worksheet.getCell(mainCell.row, mainCell.col);
|
||||
if (!cellData?.customRender) {
|
||||
return;
|
||||
}
|
||||
|
||||
primaryWithCoord = skeleton.getCellWithCoordByIndex(mainCell.row, mainCell.col, false);
|
||||
primaryWithCoord = skeleton.getCellWithCoordByIndex(mergeInfo.startRow, mergeInfo.startColumn, false);
|
||||
}
|
||||
|
||||
const renderInfo = {
|
||||
|
||||
@@ -28,6 +28,11 @@ export const defaultPlaceholderColor = '#000';
|
||||
|
||||
const EXTENSION_Z_INDEX = 34;
|
||||
|
||||
const stringifyRange = (range: IRange) => {
|
||||
const { startRow, endRow, startColumn, endColumn } = range;
|
||||
return `${startRow}-${endRow}-${startColumn}-${endColumn}`;
|
||||
};
|
||||
|
||||
export class DataBar extends SheetExtension {
|
||||
private _paddingRightAndLeft = 2;
|
||||
private _paddingTopAndBottom = 2;
|
||||
@@ -44,77 +49,88 @@ export class DataBar extends SheetExtension {
|
||||
diffRanges: IRange[]
|
||||
) {
|
||||
const { worksheet } = spreadsheetSkeleton;
|
||||
|
||||
if (!worksheet) {
|
||||
return false;
|
||||
}
|
||||
const mergeCellRendered = new Set<string>();
|
||||
ctx.save();
|
||||
// ctx.globalCompositeOperation = 'destination-over';
|
||||
Range.foreach(spreadsheetSkeleton.rowColumnSegment, (row, col) => {
|
||||
if (!worksheet.getRowVisible(row) || !worksheet.getColVisible(col)) {
|
||||
return;
|
||||
}
|
||||
const cellData = worksheet.getCell(row, col) as IDataBarCellData;
|
||||
if (cellData && cellData.dataBar) {
|
||||
const { color, value, startPoint, isGradient } = cellData.dataBar;
|
||||
const cellInfo = spreadsheetSkeleton.getCellWithCoordByIndex(row, col, false);
|
||||
let { isMerged, isMergedMainCell, mergeInfo, startY, endY, startX, endX } = cellInfo;
|
||||
if (isMerged) {
|
||||
return;
|
||||
}
|
||||
if (isMergedMainCell) {
|
||||
startY = mergeInfo.startY;
|
||||
endY = mergeInfo.endY;
|
||||
startX = mergeInfo.startX;
|
||||
endX = mergeInfo.endX;
|
||||
}
|
||||
if (!this.isRenderDiffRangesByCell(mergeInfo, diffRanges)) {
|
||||
return;
|
||||
}
|
||||
const borderWidth = endX - startX;
|
||||
const borderHeight = (endY + FIX_ONE_PIXEL_BLUR_OFFSET) - startY;
|
||||
const width = borderWidth - this._paddingRightAndLeft * 2;
|
||||
const height = borderHeight - this._paddingTopAndBottom * 2;
|
||||
if (value > 0) {
|
||||
// Width less than 1, almost invisible
|
||||
const dataBarWidth = Math.max(width * (1 - startPoint / 100) * value / 100, 1);
|
||||
const x0 = startX + this._paddingRightAndLeft + (startPoint / 100) * width;
|
||||
const y0 = startY + this._paddingTopAndBottom;
|
||||
if (isGradient) {
|
||||
const gradient = ctx.createLinearGradient(x0, y0, x0 + dataBarWidth, y0);
|
||||
gradient.addColorStop(0, color);
|
||||
gradient.addColorStop(1, 'rgb(255 255 255)');
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.strokeStyle = color;
|
||||
ctx.lineWidth = 1;
|
||||
} else {
|
||||
ctx.fillStyle = color;
|
||||
}
|
||||
|
||||
this._drawRectWithRoundedCorner(ctx, x0, y0, dataBarWidth, height, false, true, true, false);
|
||||
if (isGradient) {
|
||||
ctx.stroke();
|
||||
}
|
||||
const primaryWithCoord = spreadsheetSkeleton.getCellWithCoordByIndex(row, col, false);
|
||||
const { isMerged, isMergedMainCell, mergeInfo } = primaryWithCoord;
|
||||
|
||||
let cellData = worksheet.getCell(row, col) as IDataBarCellData;
|
||||
if (isMerged) {
|
||||
cellData = worksheet.getCell(mergeInfo.startRow, mergeInfo.startColumn) as IDataBarCellData;
|
||||
}
|
||||
|
||||
if (!cellData?.dataBar) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.isRenderDiffRangesByCell(mergeInfo, diffRanges)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isMerged || isMergedMainCell) {
|
||||
const rangeStr = stringifyRange(mergeInfo);
|
||||
if (mergeCellRendered.has(rangeStr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mergeCellRendered.add(rangeStr);
|
||||
}
|
||||
|
||||
const { color, value, startPoint, isGradient } = cellData.dataBar;
|
||||
const { startX, endX, startY, endY } = (isMerged || isMergedMainCell) ? mergeInfo : primaryWithCoord;
|
||||
const borderWidth = endX - startX;
|
||||
const borderHeight = (endY + FIX_ONE_PIXEL_BLUR_OFFSET) - startY;
|
||||
const width = borderWidth - this._paddingRightAndLeft * 2;
|
||||
const height = borderHeight - this._paddingTopAndBottom * 2;
|
||||
|
||||
if (value > 0) {
|
||||
// Width less than 1, almost invisible
|
||||
const dataBarWidth = Math.max(width * (1 - startPoint / 100) * value / 100, 1);
|
||||
const x0 = startX + this._paddingRightAndLeft + (startPoint / 100) * width;
|
||||
const y0 = startY + this._paddingTopAndBottom;
|
||||
if (isGradient) {
|
||||
const gradient = ctx.createLinearGradient(x0, y0, x0 + dataBarWidth, y0);
|
||||
gradient.addColorStop(0, color);
|
||||
gradient.addColorStop(1, 'rgb(255 255 255)');
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.strokeStyle = color;
|
||||
ctx.lineWidth = 1;
|
||||
} else {
|
||||
// Width less than 1, almost invisible
|
||||
const dataBarWidth = Math.max(width * startPoint / 100 * Math.abs(value) / 100, 1);
|
||||
const x0 = startX + this._paddingRightAndLeft + (startPoint / 100) * width - dataBarWidth;
|
||||
const y0 = startY + this._paddingTopAndBottom;
|
||||
if (isGradient) {
|
||||
const gradient = ctx.createLinearGradient(x0, y0, x0 + dataBarWidth, y0);
|
||||
gradient.addColorStop(0, 'rgb(255 255 255)');
|
||||
gradient.addColorStop(1, color);
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.strokeStyle = color;
|
||||
ctx.lineWidth = 1;
|
||||
} else {
|
||||
ctx.fillStyle = color;
|
||||
}
|
||||
ctx.fillStyle = color;
|
||||
}
|
||||
|
||||
this._drawRectWithRoundedCorner(ctx, x0, y0, dataBarWidth, height, true, false, false, true);
|
||||
if (isGradient) {
|
||||
ctx.stroke();
|
||||
}
|
||||
this._drawRectWithRoundedCorner(ctx, x0, y0, dataBarWidth, height, false, true, true, false);
|
||||
if (isGradient) {
|
||||
ctx.stroke();
|
||||
}
|
||||
} else {
|
||||
// Width less than 1, almost invisible
|
||||
const dataBarWidth = Math.max(width * startPoint / 100 * Math.abs(value) / 100, 1);
|
||||
const x0 = startX + this._paddingRightAndLeft + (startPoint / 100) * width - dataBarWidth;
|
||||
const y0 = startY + this._paddingTopAndBottom;
|
||||
if (isGradient) {
|
||||
const gradient = ctx.createLinearGradient(x0, y0, x0 + dataBarWidth, y0);
|
||||
gradient.addColorStop(0, 'rgb(255 255 255)');
|
||||
gradient.addColorStop(1, color);
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.strokeStyle = color;
|
||||
ctx.lineWidth = 1;
|
||||
} else {
|
||||
ctx.fillStyle = color;
|
||||
}
|
||||
|
||||
this._drawRectWithRoundedCorner(ctx, x0, y0, dataBarWidth, height, true, false, false, true);
|
||||
if (isGradient) {
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -27,6 +27,11 @@ const EXTENSION_Z_INDEX = 35;
|
||||
export const DEFAULT_WIDTH = 15;
|
||||
export const DEFAULT_PADDING = 2;
|
||||
|
||||
const stringifyRange = (range: IRange) => {
|
||||
const { startRow, endRow, startColumn, endColumn } = range;
|
||||
return `${startRow}-${endRow}-${startColumn}-${endColumn}`;
|
||||
};
|
||||
|
||||
export class ConditionalFormattingIcon extends SheetExtension {
|
||||
private _paddingRightAndLeft = DEFAULT_PADDING;
|
||||
|
||||
@@ -52,45 +57,59 @@ export class ConditionalFormattingIcon extends SheetExtension {
|
||||
if (!worksheet) {
|
||||
return false;
|
||||
}
|
||||
const mergeCellRendered = new Set<string>();
|
||||
ctx.save();
|
||||
// ctx.globalCompositeOperation = 'destination-over';
|
||||
Range.foreach(spreadsheetSkeleton.rowColumnSegment, (row, col) => {
|
||||
if (!worksheet.getRowVisible(row) || !worksheet.getColVisible(col)) {
|
||||
return;
|
||||
}
|
||||
const cellData = worksheet.getCell(row, col) as IIconSetCellData;
|
||||
if (cellData?.iconSet) {
|
||||
const { iconType, iconId } = cellData.iconSet;
|
||||
if (iconType === EMPTY_ICON_TYPE) {
|
||||
return;
|
||||
}
|
||||
const icon = this._imageMap.get(this._createKey(iconType, iconId));
|
||||
if (!icon) {
|
||||
return;
|
||||
}
|
||||
const cellInfo = spreadsheetSkeleton.getCellWithCoordByIndex(row, col, false);
|
||||
let { isMerged, isMergedMainCell, mergeInfo, startY, endY, startX, endX } = cellInfo;
|
||||
if (isMerged) {
|
||||
return;
|
||||
}
|
||||
if (isMergedMainCell) {
|
||||
startY = mergeInfo.startY;
|
||||
endY = mergeInfo.endY;
|
||||
startX = mergeInfo.startX;
|
||||
endX = mergeInfo.endX;
|
||||
}
|
||||
if (!this.isRenderDiffRangesByCell(mergeInfo, diffRanges)) {
|
||||
return;
|
||||
}
|
||||
const borderWidth = endX - startX;
|
||||
const borderHeight = endY - startY;
|
||||
if (this._width > borderHeight || this._width > borderWidth + this._paddingRightAndLeft * 2) {
|
||||
return;
|
||||
}
|
||||
// Highly centered processing
|
||||
const y = (borderHeight - this._width) / 2 + startY;
|
||||
ctx.drawImage(icon, startX + this._paddingRightAndLeft, y, this._width, this._width);
|
||||
|
||||
const primaryWithCoord = spreadsheetSkeleton.getCellWithCoordByIndex(row, col, false);
|
||||
const { isMerged, isMergedMainCell, mergeInfo } = primaryWithCoord;
|
||||
|
||||
let cellData = worksheet.getCell(row, col) as IIconSetCellData;
|
||||
if (isMerged) {
|
||||
cellData = worksheet.getCell(mergeInfo.startRow, mergeInfo.startColumn) as IIconSetCellData;
|
||||
}
|
||||
|
||||
if (!cellData?.iconSet) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { iconType, iconId } = cellData.iconSet;
|
||||
if (iconType === EMPTY_ICON_TYPE) {
|
||||
return;
|
||||
}
|
||||
|
||||
const icon = this._imageMap.get(this._createKey(iconType, iconId));
|
||||
if (!icon) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.isRenderDiffRangesByCell(mergeInfo, diffRanges)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isMerged || isMergedMainCell) {
|
||||
const rangeStr = stringifyRange(mergeInfo);
|
||||
if (mergeCellRendered.has(rangeStr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mergeCellRendered.add(rangeStr);
|
||||
}
|
||||
|
||||
const { startX, endX, startY, endY } = (isMerged || isMergedMainCell) ? mergeInfo : primaryWithCoord;
|
||||
const borderWidth = endX - startX;
|
||||
const borderHeight = endY - startY;
|
||||
if (this._width > borderHeight || this._width > borderWidth + this._paddingRightAndLeft * 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Highly centered processing
|
||||
const y = (borderHeight - this._width) / 2 + startY;
|
||||
ctx.drawImage(icon, startX + this._paddingRightAndLeft, y, this._width, this._width);
|
||||
});
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
@@ -87,7 +87,9 @@ export class DropdownMultipleWidget implements IBaseDataValidationWidget {
|
||||
|
||||
const map = this._ensureMap(subUnitId);
|
||||
const key = this._generateKey(row, col);
|
||||
const rule = this._dataValidationModel.getRuleByLocation(info.unitId, info.subUnitId, row, col);
|
||||
const _row = primaryWithCoord.isMergedMainCell ? primaryWithCoord.mergeInfo.startRow : row;
|
||||
const _col = primaryWithCoord.isMergedMainCell ? primaryWithCoord.mergeInfo.startColumn : col;
|
||||
const rule = this._dataValidationModel.getRuleByLocation(info.unitId, info.subUnitId, _row, _col);
|
||||
if (!rule) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -149,7 +149,9 @@ export class DropdownWidget implements IBaseDataValidationWidget {
|
||||
drawWith(ctx: UniverRenderingContext2D, info: ICellRenderContext, skeleton: SpreadsheetSkeleton): void {
|
||||
const { primaryWithCoord, row, col, style, data, subUnitId } = info;
|
||||
const _cellBounding = primaryWithCoord.isMergedMainCell ? primaryWithCoord.mergeInfo : primaryWithCoord;
|
||||
const rule = this._dataValidationModel.getRuleByLocation(info.unitId, info.subUnitId, row, col);
|
||||
const _row = primaryWithCoord.isMergedMainCell ? primaryWithCoord.mergeInfo.startRow : row;
|
||||
const _col = primaryWithCoord.isMergedMainCell ? primaryWithCoord.mergeInfo.startColumn : col;
|
||||
const rule = this._dataValidationModel.getRuleByLocation(info.unitId, info.subUnitId, _row, _col);
|
||||
if (!rule) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -535,12 +535,27 @@ export class SheetFindModel extends FindModel {
|
||||
const { startX, startY } = startPosition;
|
||||
const { endX, endY } = endPosition;
|
||||
|
||||
const rowHidden = !worksheet.getRowRawVisible(startRow);
|
||||
const columnHidden = !worksheet.getColVisible(startColumn);
|
||||
let isAllRowHidden = true;
|
||||
|
||||
const inHiddenRange = rowHidden || columnHidden;
|
||||
const width = columnHidden ? 2 : endX - startX;
|
||||
const height = rowHidden ? 2 : endY - startY;
|
||||
for (let row = startRow; row <= endRow; row++) {
|
||||
if (worksheet.getRowRawVisible(row)) {
|
||||
isAllRowHidden = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let isAllColHidden = true;
|
||||
|
||||
for (let col = startColumn; col <= endColumn; col++) {
|
||||
if (worksheet.getColVisible(col)) {
|
||||
isAllColHidden = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const inHiddenRange = isAllRowHidden || isAllColHidden;
|
||||
const width = isAllColHidden ? 2 : endX - startX;
|
||||
const height = isAllRowHidden ? 2 : endY - startY;
|
||||
|
||||
const props: ISheetFindReplaceHighlightShapeProps = {
|
||||
left: startX,
|
||||
|
||||
Reference in New Issue
Block a user