Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 链接字段高亮下划线过长 #1652

Merged
merged 6 commits into from
Aug 9, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 68 additions & 51 deletions packages/s2-core/__tests__/unit/utils/text-spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { createPivotSheet } from 'tests/util/helpers';
import {
getEllipsisText,
getEllipsisTextInner,
isUpDataValue,
measureTextWidth,
getCellWidth,
getEmptyPlaceholder,
} from '@/utils/text';
Expand All @@ -16,74 +16,91 @@ describe('Text Utils Tests', () => {
fontWeight: 'normal',
} as unknown as CSSStyleDeclaration;

test('should get correct text', () => {
const text = getEllipsisText({
text: '12',
maxWidth: 200,
placeholder: '--',
describe('Test Widths Tests', () => {
let measureTextWidth: (text: number | string, font: unknown) => number;

beforeEach(() => {
measureTextWidth = createPivotSheet(
{},
{ useSimpleData: true },
).measureTextWidth;
});

expect(text).toEqual('12');
});
test('should get correct text', () => {
const text = getEllipsisText({
measureTextWidth,
text: '12',
maxWidth: 200,
placeholder: '--',
});

test('should get correct text ellipsis', () => {
const text = getEllipsisText({
text: '12121212121212121212',
maxWidth: 20,
placeholder: '--',
expect(text).toEqual('12');
});

expect(text).toEndWith('...');
expect(text.length).toBeLessThanOrEqual(5);
});
test('should get correct text ellipsis', () => {
const text = getEllipsisText({
measureTextWidth,
text: '12121212121212121212',
maxWidth: 20,
placeholder: '--',
});

test('should get correct placeholder text with ""', () => {
const text = getEllipsisText({
text: '',
maxWidth: 20,
placeholder: '--',
expect(text).toEndWith('...');
expect(text.length).toBeLessThanOrEqual(5);
});
expect(text).toEqual('--');
});

test('should get correct placeholder text with 0', () => {
const text = getEllipsisText({
text: 0 as unknown as string,
maxWidth: 20,
placeholder: '--',
test('should get correct placeholder text with ""', () => {
const text = getEllipsisText({
measureTextWidth,
text: '',
maxWidth: 20,
placeholder: '--',
});
expect(text).toEqual('--');
});

expect(text).toEqual('0');
});
test('should get correct placeholder text with 0', () => {
const text = getEllipsisText({
measureTextWidth,
text: 0 as unknown as string,
maxWidth: 20,
placeholder: '--',
});

test('should get correct placeholder text with null', () => {
const text = getEllipsisText({
text: null,
maxWidth: 20,
placeholder: '--',
expect(text).toEqual('0');
});

expect(text).toEqual('--');
});
test('should get correct placeholder text with null', () => {
const text = getEllipsisText({
measureTextWidth,
text: null,
maxWidth: 20,
placeholder: '--',
});

test('should get correct ellipsis text', () => {
const text = getEllipsisText({
text: '长度测试',
maxWidth: 24,
expect(text).toEqual('--');
});

expect(text).toEndWith('...');
expect(text.length).toBeLessThanOrEqual(4);
});
test('should get correct ellipsis text', () => {
const text = getEllipsisText({
measureTextWidth,
text: '长度测试',
maxWidth: 24,
});

test('should get correct text width', () => {
const width = measureTextWidth('test', font);
expect(Math.floor(width)).toEqual(isHD ? 21 : 16);
});
expect(text).toEndWith('...');
expect(text.length).toBeLessThanOrEqual(4);
});

test('should get correct ellipsis text inner', () => {
const text = getEllipsisTextInner('test', 15, font);
expect(text).toEqual('t...');
test('should get correct text width', () => {
const width = measureTextWidth('test', font);
expect(Math.floor(width)).toEqual(isHD ? 21 : 16);
});

test('should get correct ellipsis text inner', () => {
const text = getEllipsisTextInner(measureTextWidth, 'test', 15, font);
expect(text).toEqual('t...');
});
});

test.each`
Expand Down
16 changes: 8 additions & 8 deletions packages/s2-core/src/cell/base-cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,7 @@ import {
} from '../utils/cell/cell';
import { renderLine, renderText, updateShapeAttr } from '../utils/g-renders';
import { isMobile } from '../utils/is-mobile';
import {
getEllipsisText,
getEmptyPlaceholder,
measureTextWidth,
} from '../utils/text';
import { getEllipsisText, getEmptyPlaceholder } from '../utils/text';

export abstract class BaseCell<T extends SimpleBBox> extends Group {
// cell's data meta info
Expand Down Expand Up @@ -201,9 +197,13 @@ export abstract class BaseCell<T extends SimpleBBox> extends Group {
const { formattedValue } = this.getFormattedFieldValue();
const maxTextWidth = this.getMaxTextWidth();
const textStyle = this.getTextStyle();
const { placeholder } = this.spreadsheet.options;
const {
options: { placeholder },
measureTextWidth,
} = this.spreadsheet;
const emptyPlaceholder = getEmptyPlaceholder(this, placeholder);
const ellipsisText = getEllipsisText({
measureTextWidth,
text: formattedValue,
maxWidth: maxTextWidth,
fontParam: textStyle,
Expand Down Expand Up @@ -233,13 +233,13 @@ export abstract class BaseCell<T extends SimpleBBox> extends Group {
const device = this.spreadsheet.options.style.device;
// 配置了链接跳转
if (!isMobile(device)) {
const { minX, maxX, maxY }: BBox = this.textShape.getBBox();
const { minX, maxY }: BBox = this.textShape.getBBox();
this.linkFieldShape = renderLine(
this,
{
x1: minX,
y1: maxY + 1,
x2: maxX,
x2: minX + this.actualTextWidth, // 不用 bbox 的 maxX,因为 g-base 文字宽度预估偏差较大
y2: maxY + 1,
},
{ stroke: linkFillColor, lineWidth: 1 },
Expand Down
9 changes: 4 additions & 5 deletions packages/s2-core/src/cell/corner-cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,7 @@ import {
getResizeAreaAttrs,
} from '../utils/interaction/resize';
import { isIPhoneX } from '../utils/is-mobile';
import {
getEllipsisText,
getEmptyPlaceholder,
measureTextWidth,
} from '../utils/text';
import { getEllipsisText, getEmptyPlaceholder } from '../utils/text';
import { i18n } from './../common/i18n';
import { shouldAddResizeArea } from './../utils/interaction/resize';
import { HeaderCell } from './header-cell';
Expand Down Expand Up @@ -86,7 +82,9 @@ export class CornerCell extends HeaderCell {
this.meta,
this.spreadsheet.options.placeholder,
);
const { measureTextWidth } = this.spreadsheet;
lcx-seima marked this conversation as resolved.
Show resolved Hide resolved
const text = getEllipsisText({
measureTextWidth,
text: cornerText,
maxWidth,
fontParam: textStyle,
Expand All @@ -106,6 +104,7 @@ export class CornerCell extends HeaderCell {
secondLine = cornerText.slice(lastIndex);
// 第二行重新计算...逻辑
secondLine = getEllipsisText({
measureTextWidth,
text: secondLine,
maxWidth,
fontParam: textStyle,
Expand Down
12 changes: 5 additions & 7 deletions packages/s2-core/src/facet/header/series-number.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
import type { Group, IGroup, IShape } from '@antv/g-canvas';
import { each } from 'lodash';
import {
CellBorderPosition,
type Padding,
type ViewMeta,
} from '../../common/interface';
import { CellBorderPosition, type Padding } from '../../common/interface';
import type { SpreadSheet } from '../../sheet-type/index';
import { getBorderPositionAndStyle } from '../../utils/cell/cell';
import { renderLine, renderRect } from '../../utils/g-renders';
import { measureTextWidth } from '../../utils/text';
import { getAdjustPosition } from '../../utils/text-absorption';
import type { PanelBBox } from '../bbox/panelBBox';
import { Node } from '../layout/node';
Expand Down Expand Up @@ -198,7 +193,10 @@ export class SeriesNumberHeader extends BaseHeader<BaseHeaderConfig> {

private getTextPadding(text: string, cellWidth: number): Padding {
const rowCellTheme = this.getStyle();
const textWidth = measureTextWidth(text, rowCellTheme.seriesText);
const textWidth = this.headerConfig.spreadsheet.measureTextWidth(
text,
rowCellTheme.seriesText,
);
const padding = Math.max(Math.abs((cellWidth - textWidth) / 2), 4);
return {
...rowCellTheme.cell.padding,
Expand Down
25 changes: 8 additions & 17 deletions packages/s2-core/src/facet/pivot-facet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
get,
isArray,
isEmpty,
isFunction,
isNil,
keys,
last,
Expand All @@ -14,14 +13,10 @@ import {
size,
} from 'lodash';
import {
DEFAULT_STYLE,
DEFAULT_TREE_ROW_WIDTH,
LAYOUT_SAMPLE_COUNT,
type CellCustomWidth,
type ColCfg,
type IconTheme,
type MultiData,
type RowCfg,
} from '../common';
import { EXTRA_FIELD, LayoutWidthTypes, VALUE_FIELD } from '../common/constant';
import { CellTypes } from '../common/constant/interaction';
Expand All @@ -34,12 +29,7 @@ import {
getIndexRangeWithOffsets,
getSubTotalNodeWidthOrHeightByLevel,
} from '../utils/facet';
import {
getCellWidth,
measureTextWidth,
measureTextWidthRoughly,
safeJsonParse,
} from '../utils/text';
import { getCellWidth, safeJsonParse } from '../utils/text';
import { BaseFacet } from './base-facet';
import { buildHeaderHierarchy } from './layout/build-header-hierarchy';
import type { Hierarchy } from './layout/hierarchy';
Expand Down Expand Up @@ -290,7 +280,7 @@ export class PivotFacet extends BaseFacet {
colIconStyle,
);
const leafNodeRoughWidth =
measureTextWidthRoughly(leafNodeLabel) + iconWidth;
this.spreadsheet.measureTextWidthRoughly(leafNodeLabel) + iconWidth;

// 采样 50 个 label,逐个计算找出最长的 label
let maxDataLabel: string;
Expand All @@ -314,7 +304,8 @@ export class PivotFacet extends BaseFacet {
cellData,
filterDisplayDataItem,
)}`;
const cellLabelWidth = measureTextWidthRoughly(cellLabel);
const cellLabelWidth =
this.spreadsheet.measureTextWidthRoughly(cellLabel);

if (cellLabelWidth > maxDataLabelWidth) {
maxDataLabel = cellLabel;
Expand All @@ -336,7 +327,7 @@ export class PivotFacet extends BaseFacet {
);

return (
measureTextWidth(maxLabel, colCellTextStyle) +
this.spreadsheet.measureTextWidth(maxLabel, colCellTextStyle) +
colCellStyle.padding?.left +
colCellStyle.padding?.right +
appendedWidth
Expand Down Expand Up @@ -751,7 +742,7 @@ export class PivotFacet extends BaseFacet {
this.spreadsheet.theme.cornerCell;
// 初始化角头时,保证其在树形模式下不换行,给与两个icon的宽度空余(tree icon 和 action icon),减少复杂的 action icon 判断
const maxLabelWidth =
measureTextWidth(treeHeaderLabel, cornerCellTextStyle) +
this.spreadsheet.measureTextWidth(treeHeaderLabel, cornerCellTextStyle) +
cornerIconStyle.size * 2 +
cornerIconStyle.margin?.left +
cornerIconStyle.margin?.right +
Expand Down Expand Up @@ -808,7 +799,7 @@ export class PivotFacet extends BaseFacet {
);
const maxLabel = maxBy(allLabels, (label) => `${label}`.length);
const rowNodeWidth =
measureTextWidth(maxLabel, rowTextStyle) +
spreadsheet.measureTextWidth(maxLabel, rowTextStyle) +
rowIconWidth +
rowCellStyle.padding.left +
rowCellStyle.padding.right;
Expand All @@ -821,7 +812,7 @@ export class PivotFacet extends BaseFacet {
cornerIconStyle,
);
const fieldNameNodeWidth =
measureTextWidth(fieldName, cornerTextStyle) +
spreadsheet.measureTextWidth(fieldName, cornerTextStyle) +
cornerIconWidth +
cornerCellStyle.padding.left +
cornerCellStyle.padding.right;
Expand Down
18 changes: 13 additions & 5 deletions packages/s2-core/src/facet/table-facet.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import type { Group, IElement, IGroup } from '@antv/g-canvas';
import { get, isBoolean, isNil, last, maxBy, set, values } from 'lodash';
import {
get,
isBoolean,
isNil,
last,
maxBy,
set,
spread,
values,
} from 'lodash';
import { TableSeriesCell } from '../cell';
import {
FRONT_GROUND_GROUP_COL_FROZEN_Z_INDEX,
Expand Down Expand Up @@ -35,7 +44,6 @@ import {
} from '../utils/grid';
import type { PanelIndexes } from '../utils/indexes';
import { getValidFrozenOptions } from '../utils/layout/frozen';
import { measureTextWidth, measureTextWidthRoughly } from '../utils/text';
import { BaseFacet } from './base-facet';
import { CornerBBox } from './bbox/cornerBBox';
import type { SeriesNumberHeader } from './header';
Expand Down Expand Up @@ -375,7 +383,7 @@ export class TableFacet extends BaseFacet {
datas?.map((data) => `${data[col.key]}`)?.slice(0, 50) || []; // 采样取了前50
allLabels.push(colLabel);
const maxLabel = maxBy(allLabels, (label) =>
measureTextWidthRoughly(label),
spreadsheet.measureTextWidthRoughly(label),
);

const { bolderText: colCellTextStyle } = spreadsheet.theme.colCell;
Expand All @@ -391,7 +399,7 @@ export class TableFacet extends BaseFacet {
// 最长的 Label 如果是列名,按列名的标准计算宽度
if (colLabel === maxLabel) {
colWidth =
measureTextWidth(maxLabel, colCellTextStyle) +
spreadsheet.measureTextWidth(maxLabel, colCellTextStyle) +
getOccupiedWidthForTableCol(
this.spreadsheet,
col,
Expand All @@ -401,7 +409,7 @@ export class TableFacet extends BaseFacet {
// 额外添加一像素余量,防止 maxLabel 有多个同样长度情况下,一些 label 不能展示完全
const EXTRA_PIXEL = 1;
colWidth =
measureTextWidth(maxLabel, dataCellTextStyle) +
spreadsheet.measureTextWidth(maxLabel, dataCellTextStyle) +
cellStyle.padding.left +
cellStyle.padding.right +
EXTRA_PIXEL;
Expand Down
Loading