Skip to content

Commit

Permalink
fix: 修复角头存在多行文本时未自动撑开列头高度的问题 (#3010)
Browse files Browse the repository at this point in the history
* fix: 修复角头存在多行文本时为自动撑开列头高度的问题

* test: 修复单测

* fix: 增加容错
  • Loading branch information
lijinke666 authored Dec 4, 2024
1 parent c95d646 commit 0b79f27
Show file tree
Hide file tree
Showing 18 changed files with 5,624 additions and 1,613 deletions.
6,745 changes: 5,239 additions & 1,506 deletions packages/s2-core/__tests__/spreadsheet/__snapshots__/multi-line-text-spec.ts.snap

Large diffs are not rendered by default.

120 changes: 110 additions & 10 deletions packages/s2-core/__tests__/spreadsheet/multi-line-text-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from '../../src';
import type {
CellTextWordWrapStyle,
Meta,
S2CellType,
S2Options,
} from '../../src/common';
Expand Down Expand Up @@ -138,6 +139,13 @@ describe('SpreadSheet Multi Line Text Tests', () => {
},
};

const cornerMetaList: Meta[] = [
{ field: 'type', name: '类别\n类别' },
{ field: 'sub_type', name: '子类别\n子类别\n子类别' },
{ field: 'number', name: '数量\n数量\n数量\n数量' },
{ field: 'city', name: '城市\n城市' },
];

beforeEach(async () => {
s2 = new PivotSheet(
getContainer(),
Expand All @@ -161,15 +169,15 @@ describe('SpreadSheet Multi Line Text Tests', () => {
await s2.render(false);

matchCellStyleSnapshot();
expectColHierarchyHeight(142, 96, 46);
expectColHierarchyHeight(144, 96, 48);
});

test('should render three max text lines', async () => {
updateStyle(3);
await s2.render(false);

matchCellStyleSnapshot();
expectColHierarchyHeight(189, 128, 61);
expectColHierarchyHeight(192, 128, 64);
});

test('should render custom text overflow text', async () => {
Expand Down Expand Up @@ -220,7 +228,7 @@ describe('SpreadSheet Multi Line Text Tests', () => {
expectColHierarchyHeight(90);
});

test('should not adaptive adjust cell height if custom cell style less than actual text height by rowCell.height', async () => {
test('should not adaptive adjust cell height, but should adjust maxLines if custom cell style less than actual text height by rowCell.height', async () => {
updateStyle(2);

s2.setOptions({
Expand All @@ -236,7 +244,7 @@ describe('SpreadSheet Multi Line Text Tests', () => {
matchCellStyleSnapshot();
});

test('should not adaptive adjust cell height if custom cell style less than actual text height by rowCell.height()', async () => {
test('should not adaptive adjust cell height, but should adjust maxLines if custom cell style less than actual text height by rowCell.height()', async () => {
updateStyle(2);

s2.setOptions({
Expand Down Expand Up @@ -337,7 +345,7 @@ describe('SpreadSheet Multi Line Text Tests', () => {
await s2.render(false);

matchCellStyleSnapshot();
expectColHierarchyHeight(142, 96, 46);
expectColHierarchyHeight(144, 96, 48);
});

test('should not adaptive adjust cell height if custom cell style more than actual text height', async () => {
Expand Down Expand Up @@ -388,7 +396,7 @@ describe('SpreadSheet Multi Line Text Tests', () => {
updateStyle(3);
await s2.render(false);

expectColHierarchyHeight(173, 112, 61);
expectColHierarchyHeight(176, 112, 64);
});

test('should render correctly layout if only enable grand totals', async () => {
Expand Down Expand Up @@ -445,7 +453,7 @@ describe('SpreadSheet Multi Line Text Tests', () => {

// 省份 4行文本, 叶子节点 (城市) 3行文本, 省份应该和城市高度一致, 才能展示所有文本 (maxLines: 4)
expectRowHierarchyHeight(400, 0, 80);
expectColHierarchyHeight(236, 160, 76);
expectColHierarchyHeight(240, 160, 80);
});

test('should render three max text lines for tree mode', async () => {
Expand Down Expand Up @@ -539,7 +547,10 @@ describe('SpreadSheet Multi Line Text Tests', () => {
updateStyle(maxLines);

s2.changeSheetSize(800, 600);
s2.setDataCfg(SimpleDataCfg);
s2.setDataCfg({
...SimpleDataCfg,
meta: [],
});
await s2.render();

// 不管设置了多少行的文本, 如果实际文本未换行, 高度不应该自适应, 以默认高度为准.
Expand Down Expand Up @@ -602,6 +613,95 @@ describe('SpreadSheet Multi Line Text Tests', () => {

matchCellStyleSnapshot();
});

test('should adjust corner cell max lines by custom col height', async () => {
s2.changeSheetSize(800, 600);
s2.setDataCfg({
meta: cornerMetaList,
});
s2.setOptions({
style: {
cornerCell: {
maxLines: 10,
},
colCell: {
height: 20,
maxLines: 2,
},
},
});
await s2.render();

matchCellStyleSnapshot();
expectColHierarchyHeight(60, 40, 20);
});

test('should adjust col cell height if corner cell height > col cell height', async () => {
s2.changeSheetSize(800, 600);
s2.setDataCfg({
meta: cornerMetaList,
});
s2.setOptions({
style: {
cornerCell: {
maxLines: 10,
},
colCell: {
maxLines: 1,
},
},
});
await s2.render();

matchCellStyleSnapshot();
expectColHierarchyHeight(160, 112, 48);
});

test('should adjust col cell height if corner cell height > col cell height by tree mode', async () => {
s2.changeSheetSize(800, 600);
s2.setDataCfg({
meta: cornerMetaList,
});
s2.setOptions({
hierarchyType: 'tree',
style: {
cornerCell: {
maxLines: 10,
},
colCell: {
maxLines: 1,
},
},
});
await s2.render();

matchCellStyleSnapshot();
expectColHierarchyHeight(192, 112, 80);
});

test('should adjust col cell height if corner cell height > col cell height by "valueInCols: false"', async () => {
s2.changeSheetSize(800, 600);
s2.setDataCfg({
meta: cornerMetaList,
fields: {
valueInCols: false,
},
});
s2.setOptions({
style: {
cornerCell: {
maxLines: 10,
},
colCell: {
maxLines: 1,
},
},
});
await s2.render();

matchCellStyleSnapshot();
expectColHierarchyHeight(96, 48, 48, 2);
});
});

describe('TableSheet', () => {
Expand Down Expand Up @@ -690,7 +790,7 @@ describe('SpreadSheet Multi Line Text Tests', () => {
});
});

test('should not force adaptive adjust cell height if custom cell style less than actual text height by colCell.height', async () => {
test('should not force adaptive adjust cell height, but should adjust maxLines if custom cell style less than actual text height by colCell.height', async () => {
s2.setOptions({
style: {
colCell: {
Expand All @@ -706,7 +806,7 @@ describe('SpreadSheet Multi Line Text Tests', () => {
expectColHierarchyHeight(20, 0, 20, 1);
});

test('should not adaptive adjust cell height if custom cell style more than actual text height', async () => {
test('should not adaptive adjust cell height, but should adjust maxLines if custom cell style more than actual text height', async () => {
const CUSTOM_CELL_HEIGHT = 70;

s2.setOptions({
Expand Down
1 change: 1 addition & 0 deletions packages/s2-core/__tests__/util/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ export const createMockCellInfo = (
updateByState: jest.fn(),
isTextOverflowing: jest.fn(),
getTextLineHeight: jest.fn(() => 16),
getMaxLinesByCustomHeight: jest.fn(() => 1),
} as unknown as S2CellType;

const getNode = () => mockCellViewMeta as unknown as Node;
Expand Down
39 changes: 37 additions & 2 deletions packages/s2-core/src/cell/base-cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
import {
CellType,
DEFAULT_FONT_COLOR,
DEFAULT_TEXT_LINE_HEIGHT,
InteractionStateName,
REVERSE_FONT_COLOR,
SHAPE_ATTRS_MAP,
Expand Down Expand Up @@ -302,10 +303,13 @@ export abstract class BaseCell<T extends SimpleBBox> extends Group {
}

/**
* 获取文本包围盒
* 获取文本行高
*/
public getTextLineHeight() {
return this.textShape?.parsedStyle?.metrics?.lineHeight;
return (
this.textShape?.parsedStyle?.metrics?.lineHeight ||
DEFAULT_TEXT_LINE_HEIGHT
);
}

/**
Expand Down Expand Up @@ -825,4 +829,35 @@ export abstract class BaseCell<T extends SimpleBBox> extends Group {
backgroundColor: this.getStyle().cell.backgroundColor,
};
}

public getMaxLinesByCustomHeight(options: {
targetCell?: S2CellType;
displayHeight?: number;
isCustomHeight?: boolean;
}) {
const {
targetCell = this,
displayHeight = this.meta.height,
isCustomHeight = false,
} = options;
const cell = targetCell || this;
const cellStyle = this.spreadsheet.options.style?.[cell.cellType];
const isEnableHeightAdaptive =
cellStyle?.maxLines! > 1 && cellStyle?.wordWrap;

if (!isEnableHeightAdaptive || !isCustomHeight) {
return;
}

const { cell: cellTheme } = cell?.getStyle() as DefaultCellTheme;
const padding = cellTheme!.padding!.top! + cellTheme!.padding!.bottom!;
const lineHeight = cell?.getTextLineHeight()!;

const maxLines = Math.max(
1,
Math.floor((displayHeight - padding) / lineHeight),
);

return maxLines;
}
}
9 changes: 8 additions & 1 deletion packages/s2-core/src/cell/col-cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -583,12 +583,19 @@ export class ColCell extends HeaderCell<ColHeaderConfig> {
return isNextSiblingNodeHidden && isPrevSiblingNodeHidden;
}

/**
* 以下场景根据当前高度动态计算 maxLines, 保证文本展示合理性
* 1.手动拖拽 2.预设高度
*/
protected getResizedTextMaxLines() {
const { colCell } = this.spreadsheet.options.style!;

return (
colCell?.maxLinesByField?.[this.meta.id] ??
colCell?.maxLinesByField?.[this.meta.field]
colCell?.maxLinesByField?.[this.meta.field] ??
this.getMaxLinesByCustomHeight({
isCustomHeight: this.meta.extra?.isCustomHeight,
})
);
}
}
5 changes: 4 additions & 1 deletion packages/s2-core/src/cell/corner-cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,10 @@ export class CornerCell extends HeaderCell<CornerHeaderConfig> {

return (
colCell?.maxLinesByField?.[this.meta.id] ??
colCell?.maxLinesByField?.[this.meta.field]
colCell?.maxLinesByField?.[this.meta.field] ??
this.getMaxLinesByCustomHeight({
isCustomHeight: this.meta.extra?.isCustomHeight,
})
);
}
}
6 changes: 5 additions & 1 deletion packages/s2-core/src/cell/data-cell.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { PointLike } from '@antv/g';
import { find, first, get, isEmpty, isEqual, isObject, merge } from 'lodash';
import { BaseCell } from '../cell/base-cell';
import { DEFAULT_STYLE } from '../common';
import { EMPTY_PLACEHOLDER } from '../common/constant/basic';
import {
CellType,
Expand Down Expand Up @@ -515,7 +516,10 @@ export class DataCell extends BaseCell<ViewMeta> {
// 数值和行高保持一致, 同时兼容明细表
return (
rowCell?.maxLinesByField?.[this.meta.id] ??
rowCell?.maxLinesByField?.[this.meta.rowId!]
rowCell?.maxLinesByField?.[this.meta.rowId!] ??
this.getMaxLinesByCustomHeight({
isCustomHeight: this.meta.height !== DEFAULT_STYLE.dataCell?.height,
})
);
}
}
5 changes: 4 additions & 1 deletion packages/s2-core/src/cell/row-cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,10 @@ export class RowCell extends HeaderCell<RowHeaderConfig> {

return (
rowCell?.maxLinesByField?.[this.meta.id] ??
rowCell?.maxLinesByField?.[this.meta.field]
rowCell?.maxLinesByField?.[this.meta.field] ??
this.getMaxLinesByCustomHeight({
isCustomHeight: this.meta.extra?.isCustomHeight,
})
);
}
}
14 changes: 14 additions & 0 deletions packages/s2-core/src/cell/table-data-cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
ResizeDirectionType,
} from '../common/constant';
import { CustomRect, type SimpleBBox } from '../engine';
import type { TableFacet } from '../facet';
import type { FrozenFacet } from '../facet/frozen-facet';
import { isFrozenRow, isFrozenTrailingRow } from '../facet/utils';
import {
Expand Down Expand Up @@ -155,4 +156,17 @@ export class TableDataCell extends DataCell {
protected isDisableHover(cellMeta: CellMeta) {
return cellMeta?.type === CellType.COL_CELL;
}

protected getResizedTextMaxLines() {
const { rowCell } = this.spreadsheet.options.style!;

return (
rowCell?.maxLinesByField?.[this.meta.id] ??
rowCell?.maxLinesByField?.[this.meta.rowId!] ??
this.getMaxLinesByCustomHeight({
isCustomHeight: (this.spreadsheet.facet as TableFacet)
?.customRowHeightStatusMap?.[this.meta.rowIndex],
})
);
}
}
2 changes: 2 additions & 0 deletions packages/s2-core/src/common/constant/basic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,5 @@ export const getDefaultCornerText = () => i18n('指标');

// 省略号
export const ELLIPSIS_SYMBOL = '...';

export const DEFAULT_TEXT_LINE_HEIGHT = 16;
Loading

0 comments on commit 0b79f27

Please sign in to comment.