diff --git a/packages/s2-core/__tests__/bugs/issue-2385-spec.ts b/packages/s2-core/__tests__/bugs/issue-2385-spec.ts new file mode 100644 index 0000000000..4e3e56430a --- /dev/null +++ b/packages/s2-core/__tests__/bugs/issue-2385-spec.ts @@ -0,0 +1,57 @@ +/** + * @description spec for issue #2385 + * https://github.com/antvis/S2/issues/2385 + */ +import { createPivotSheet, getContainer } from '../util/helpers'; +import * as mockDataConfig from '../data/data-issue-2385.json'; +import type { S2Options } from '../../src'; +import { PivotSheet, TableSheet } from '@/sheet-type'; + +const s2Options: S2Options = { + width: 800, + height: 600, + style: { + cellCfg: { + width: 200, + }, + layoutWidthType: 'compact', + }, +}; + +describe('Compare Layout Tests', () => { + test('should get max col width for pivot sheet', () => { + const s2 = new PivotSheet(getContainer(), mockDataConfig, s2Options); + s2.setTheme({ + dataCell: { + text: { + fontSize: 20, + }, + }, + }); + s2.render(); + + const colLeafNodes = s2.facet.layoutResult.colLeafNodes; + expect(Math.floor(colLeafNodes[0].width)).toBeCloseTo(179); + expect(Math.floor(colLeafNodes[1].width)).toEqual(98); + }); + + test('should get max col width for table sheet', () => { + const s2 = new TableSheet(getContainer(), mockDataConfig, s2Options); + s2.setDataCfg({ + fields: { + columns: ['price'], + }, + }); + s2.setTheme({ + dataCell: { + text: { + fontSize: 20, + }, + }, + }); + s2.render(); + + const colLeafNodes = s2.facet.layoutResult.colLeafNodes; + expect(Math.floor(colLeafNodes[0].width)).toBeCloseTo(165); + }); +}); diff --git a/packages/s2-core/__tests__/data/data-issue-2385.json b/packages/s2-core/__tests__/data/data-issue-2385.json new file mode 100644 index 0000000000..c8ad719d5c --- /dev/null +++ b/packages/s2-core/__tests__/data/data-issue-2385.json @@ -0,0 +1,272 @@ +{ + "data": [ + { + "province": "浙江", + "city": "杭州", + "type": "笔", + "price": "11111111" + }, + { + "province": "浙江", + "city": "杭州", + "type": "纸张", + "price": "2" + }, + { + "province": "浙江", + "city": "舟山", + "type": "笔", + "price": "2" + }, + { + "province": "浙江", + "city": "舟山", + "type": "纸张", + "price": "133.333" + }, + { + "province": "吉林", + "city": "长春", + "type": "笔", + "price": "3" + }, + { + "province": "吉林", + "city": "长春", + "type": "纸张", + "price": "2" + }, + { + "province": "吉林", + "city": "白山", + "type": "笔", + "price": "4" + }, + { + "province": "吉林", + "city": "白山", + "type": "纸张", + "price": "1" + }, + { + "province": "浙江", + "city": "杭州", + "type": "笔", + "price": "11111111111111111" + }, + { + "province": "浙江", + "city": "杭州", + "type": "纸张", + "price": "2" + }, + { + "province": "浙江", + "city": "舟山", + "type": "笔", + "price": "2" + }, + { + "province": "浙江", + "city": "舟山", + "type": "纸张", + "price": "666.333" + }, + { + "province": "吉林", + "city": "长春", + "type": "笔", + "price": "3" + }, + { + "province": "吉林", + "city": "长春", + "type": "纸张", + "price": "2" + }, + { + "province": "吉林", + "city": "白山", + "type": "笔", + "price": "4" + }, + { + "province": "吉林", + "city": "白山", + "type": "纸张", + "price": "1" + }, + { + "province": "浙江", + "city": "杭州", + "type": "笔", + "cost": "33.333" + }, + { + "province": "浙江", + "city": "杭州", + "type": "纸张", + "cost": "1.5" + }, + { + "province": "浙江", + "city": "舟山", + "type": "笔", + "cost": "1.5" + }, + { + "province": "浙江", + "city": "舟山", + "type": "纸张", + "cost": "0.2" + }, + { + "province": "吉林", + "city": "长春", + "type": "笔", + "cost": "2" + }, + { + "province": "吉林", + "city": "长春", + "type": "纸张", + "cost": "1" + }, + { + "province": "吉林", + "city": "白山", + "type": "笔", + "cost": "3" + }, + { + "province": "吉林", + "city": "白山", + "type": "纸张", + "cost": "33.333" + }, + { + "price": "15.5" + }, + { + "province": "浙江", + "price": "5.5" + }, + { + "province": "浙江", + "city": "杭州", + "price": "3" + }, + { + "province": "浙江", + "city": "舟山", + "price": "2.5" + }, + { + "province": "吉林", + "price": "10" + }, + { + "province": "吉林", + "city": "长春", + "price": "5" + }, + { + "province": "吉林", + "city": "白山", + "price": "5" + }, + { + "type": "笔", + "price": "10" + }, + { + "type": "笔", + "province": "浙江", + "price": "3" + }, + { + "type": "笔", + "province": "吉林", + "price": "7" + }, + { + "type": "纸张", + "price": "5.5" + }, + { + "type": "纸张", + "province": "浙江", + "price": "2.5" + }, + { + "type": "纸张", + "province": "吉林", + "price": "3" + }, + { + "cost": "10.2" + }, + { + "province": "浙江", + "cost": "3.7" + }, + { + "province": "浙江", + "city": "杭州", + "cost": "2" + }, + { + "province": "浙江", + "city": "舟山", + "cost": "1.7" + }, + { + "province": "吉林", + "cost": "6.5" + }, + { + "province": "吉林", + "city": "长春", + "cost": "3" + }, + { + "province": "吉林", + "city": "白山", + "cost": "3.5" + }, + { + "type": "笔", + "cost": "7" + }, + { + "type": "笔", + "province": "浙江", + "cost": "2" + }, + { + "type": "笔", + "province": "吉林", + "cost": "5" + }, + { + "type": "纸张", + "cost": "3.2" + }, + { + "type": "纸张", + "province": "浙江", + "cost": "1.7" + }, + { + "type": "纸张", + "province": "吉林", + "cost": "1.5" + } + ], + "fields": { + "rows": ["province", "city"], + "columns": ["type"], + "values": ["price"], + "valueInCols": true + } +} diff --git a/packages/s2-core/src/facet/pivot-facet.ts b/packages/s2-core/src/facet/pivot-facet.ts index c5da151310..8ef0178eb6 100644 --- a/packages/s2-core/src/facet/pivot-facet.ts +++ b/packages/s2-core/src/facet/pivot-facet.ts @@ -294,6 +294,7 @@ export class PivotFacet extends BaseFacet { cell: colCellStyle, icon: colIconStyle, } = this.spreadsheet.theme.colCell; + const { text: dataCellTextStyle } = this.spreadsheet.theme.dataCell; // leaf node rough width const cellFormatter = this.spreadsheet.dataSet.getFieldFormatter( @@ -307,7 +308,10 @@ export class PivotFacet extends BaseFacet { colIconStyle, ); const leafNodeRoughWidth = - this.spreadsheet.measureTextWidthRoughly(leafNodeLabel) + iconWidth; + this.spreadsheet.measureTextWidthRoughly( + leafNodeLabel, + colCellTextStyle, + ) + iconWidth; // 采样 50 个 label,逐个计算找出最长的 label let maxDataLabel: string; @@ -334,8 +338,10 @@ export class PivotFacet extends BaseFacet { cellData[EXTRA_FIELD], )?.(valueData) ?? valueData; const cellLabel = `${formattedValue}`; - const cellLabelWidth = - this.spreadsheet.measureTextWidthRoughly(cellLabel); + const cellLabelWidth = this.spreadsheet.measureTextWidthRoughly( + cellLabel, + dataCellTextStyle, + ); if (cellLabelWidth > maxDataLabelWidth) { maxDataLabel = cellLabel; @@ -345,7 +351,6 @@ export class PivotFacet extends BaseFacet { } } - // compare result const isLeafNodeWidthLonger = leafNodeRoughWidth > maxDataLabelWidth; const maxLabel = isLeafNodeWidthLonger ? leafNodeLabel : maxDataLabel; const appendedWidth = isLeafNodeWidthLonger ? iconWidth : 0; @@ -354,10 +359,20 @@ export class PivotFacet extends BaseFacet { 'Max Label In Col:', col.field, maxLabel, + maxDataLabelWidth, ); + // 取列头/数值字体最大的文本宽度 https://github.com/antvis/S2/issues/2385 + const maxTextWidth = this.spreadsheet.measureTextWidth(maxLabel, { + ...colCellTextStyle, + fontSize: Math.max( + dataCellTextStyle.fontSize, + colCellTextStyle.fontSize, + ), + }); + return ( - this.spreadsheet.measureTextWidth(maxLabel, colCellTextStyle) + + maxTextWidth + colCellStyle.padding?.left + colCellStyle.padding?.right + appendedWidth diff --git a/packages/s2-react/__tests__/data/mock-dataset.json b/packages/s2-react/__tests__/data/mock-dataset.json index d42360ebc8..c807f0b973 100644 --- a/packages/s2-react/__tests__/data/mock-dataset.json +++ b/packages/s2-react/__tests__/data/mock-dataset.json @@ -80,7 +80,7 @@ "sub_type": "沙发" }, { - "number": 632, + "number": 632632632, "province": "浙江省", "city": "绍兴市", "type": "家具", diff --git a/packages/s2-react/playground/config.ts b/packages/s2-react/playground/config.ts index 52719ad7ee..bb2100c9db 100644 --- a/packages/s2-react/playground/config.ts +++ b/packages/s2-react/playground/config.ts @@ -1,5 +1,5 @@ import { isUpDataValue, type Columns } from '@antv/s2'; -import type { S2DataConfig } from '@antv/s2'; +import type { S2DataConfig, ThemeCfg } from '@antv/s2'; import { getBaseSheetComponentOptions } from '@antv/s2-shared'; import type { SliderSingleProps } from 'antd'; import { @@ -114,6 +114,11 @@ export const s2Options: SheetComponentOptions = { }, }; +export const s2ThemeConfig: ThemeCfg = { + name: 'default', + theme: {}, +}; + export const sliderOptions: SliderSingleProps = { min: 0, max: 10, diff --git a/packages/s2-react/playground/index.tsx b/packages/s2-react/playground/index.tsx index cbf99d085b..5d27b80834 100644 --- a/packages/s2-react/playground/index.tsx +++ b/packages/s2-react/playground/index.tsx @@ -67,6 +67,7 @@ import { tableSheetDataCfg, tableSheetMultipleColumns, tableSheetSingleColumns, + s2ThemeConfig, } from './config'; import './index.less'; import { ResizeConfig } from './resize'; @@ -172,9 +173,7 @@ function MainLayout() { const [showPagination, setShowPagination] = React.useState(false); const [showTotals, setShowTotals] = React.useState(false); - const [themeCfg, setThemeCfg] = React.useState({ - name: 'default', - }); + const [themeCfg, setThemeCfg] = React.useState(s2ThemeConfig); const [themeColor, setThemeColor] = React.useState('#FFF'); const [showCustomTooltip, setShowCustomTooltip] = React.useState(false); const [adaptive, setAdaptive] = React.useState(false); diff --git a/s2-site/docs/common/style.zh.md b/s2-site/docs/common/style.zh.md index c0709c5bbf..22f4c3e823 100644 --- a/s2-site/docs/common/style.zh.md +++ b/s2-site/docs/common/style.zh.md @@ -9,7 +9,7 @@ object **必选**,_default:null_ 功能描述:样式设置 | 参数 | 类型 | 必选 | 默认值 | 功能描述 | | --- | --- | --- | --- | --- | -| layoutWidthType | `adaptive` \| `colAdaptive` \| `compact` | | | 单元格宽度布局类型
`adaptive` : 行列等宽,均分整个 `Canvas` 画布宽度
`colAdaptive`:列等宽,行头紧凑布局,列等分画布宽度减去行头宽度的剩余宽度
`compact`:行列紧凑布局,指标维度少的时候无法布满整个画布 | +| layoutWidthType | `adaptive \| colAdaptive \| compact` | | | 单元格宽度布局类型
`adaptive` : 行列等宽,均分整个 `Canvas` 画布宽度
`colAdaptive`:列等宽,行头紧凑布局,列等分画布宽度减去行头宽度的剩余宽度
`compact`:行列紧凑布局,列头宽度为内容实际宽度 (采样列前 50 个数值), 指标维度少的时候无法布满整个画布 | | showTreeLeafNodeAlignDot | `boolean` | | false | 树状模式下叶子节点是否显示层级占位点 | | treeRowsWidth | `number` | | 120 | 树状模式行单元格宽度 (优先级大于 `rowCfg.width` 和 `rowCfg.treeRowsWidth (已废弃)`) | | hierarchyCollapse | `boolean` | | `false` | 在树状结构模式下行头是否默认展开。 | @@ -18,7 +18,7 @@ object **必选**,_default:null_ 功能描述:样式设置 | cellCfg | [CellCfg](#cellcfg) | | | 单元格配置 | | colCfg | [ColCfg](#colcfg) | | | 列样式配置 | | rowCfg | [RowCfg](#rowcfg) | | | 行样式配置 | -| device | `pc` \| `mobile` | | `pc` | 设备类型 | +| device | `pc \| mobile` | | `pc` | 设备类型 | ## CellCfg