Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,5 @@ packages/vtable/nodejs/*.png
.rollup.cache/
tsconfig.tsbuildinfo

.history
.history
.trae/
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"comment": "fix: radio cell type with rowseriesnumber error\n\n",
"type": "none",
"packageName": "@visactor/vtable"
}
],
"packageName": "@visactor/vtable",
"email": "892739385@qq.com"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"comment": "fix: degrade radio/checkbox cells to text in aggregation rows",
"type": "patch",
"packageName": "@visactor/vtable"
}
],
"packageName": "@visactor/vtable",
"email": "2779428708@qq.com"
}
4 changes: 4 additions & 0 deletions packages/vtable/examples/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,10 @@ export const menus = [
path: 'type',
name: 'radio'
},
{
path: 'type',
name: 'radio-aggregation'
},
{
path: 'type',
name: 'switch'
Expand Down
110 changes: 110 additions & 0 deletions packages/vtable/examples/type/radio-aggregation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import * as VTable from '../../src';
import { AggregationType } from '../../src/ts-types';
import { bindDebugTool } from '../../src/scenegraph/debug-tool';
const ListTable = VTable.ListTable;
const CONTAINER_ID = 'vTable';

/**
* 验证场景:合计行中 radio 单元格应降级为文本单元格,与 checkbox 行为保持一致。
* 对应 issue: https://github.com/VisActor/VTable/issues/4027
*
* 复现步骤(修复前):
* 1. 表格配置了 bottomFrozenRowCount 和 aggregation(合计行)
* 2. 某列配置 cellType: 'radio'
* 3. 修复前:合计行中 radio 渲染异常,可能导致表格整体空白
* 4. 修复后:合计行中 radio 列正确降级为纯文本显示,表格正常渲染
*/
export function createTable() {
const data = [
{ percent: '100%', value: 20, check: { text: 'unchecked', checked: false, disable: false } },
{ percent: '80%', value: 18, check: { text: 'checked', checked: true, disable: false } },
{ percent: '20%', value: 12, check: { text: 'unchecked', checked: false, disable: false } },
{ percent: '0%', value: 10, check: { text: 'checked', checked: false, disable: false } },
{ percent: '60%', value: 16, check: { text: 'disable', checked: true, disable: true } },
{ percent: '40%', value: 14, check: { text: 'disable', checked: false, disable: true } },
{ percent: '0%', value: -10, check: true },
{ percent: '0%', value: -10, check: ['选中', '选中'] }
];
let records: any[] = [];
for (let i = 0; i < 10; i++) {
records = records.concat(data);
}

const columns: VTable.ColumnsDefine = [
{
field: 'percent',
title: 'percent',
width: 120,
sort: true
},
{
field: 'value',
title: 'value',
width: 100,
aggregation: [
{
aggregationType: AggregationType.SUM,
formatFun(value) {
return '合计: ' + Math.round(value);
}
}
]
},
{
field: 'percent',
title: 'column radio',
width: 120,
cellType: 'radio'
},
{
field: 'check',
title: 'cell radio',
width: 200,
cellType: 'radio',
radioCheckType: 'cell',
radioDirectionInCell: 'vertical',
style: {
spaceBetweenRadio: 10
}
},
{
field: 'percent',
title: 'checkbox',
width: 120,
cellType: 'checkbox',
disable: true,
checked: true
}
];

const option: VTable.ListTableConstructorOptions = {
container: document.getElementById(CONTAINER_ID),
columns,
records,
widthMode: 'standard',
heightMode: 'autoHeight',
bottomFrozenRowCount: 1,
rowSeriesNumber: {
width: 50,
cellType: 'radio'
},
theme: VTable.themes.DEFAULT.extends({
bottomFrozenStyle: {
fontWeight: 500
}
})
};

const instance = new ListTable(option);

bindDebugTool(instance.scenegraph.stage as any, {
customGrapicKeys: ['role', '_updateTag']
});

const { RADIO_STATE_CHANGE } = VTable.ListTable.EVENT_TYPE;
instance.on(RADIO_STATE_CHANGE, e => {
console.log('Radio state changed:', e.col, e.row, e.radioIndexInCell);
});

(window as any).tableInstance = instance;
}
6 changes: 5 additions & 1 deletion packages/vtable/src/core/BaseTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3765,7 +3765,11 @@ export abstract class BaseTable extends EventTarget implements BaseTableAPI {
getCellType(col: number, row: number): ColumnTypeOption {
let cellType;
if (this.isSeriesNumberInHeader(col, row)) {
return (this.internalProps.layoutMap as SimpleHeaderLayoutMap).getSeriesNumberHeader(col, row).cellType;
const seriesHeaderCellType = (this.internalProps.layoutMap as SimpleHeaderLayoutMap).getSeriesNumberHeader(
col,
row
).cellType;
return seriesHeaderCellType === 'radio' ? 'text' : seriesHeaderCellType;
} else if (this.isHeader(col, row)) {
cellType = (this.internalProps.layoutMap.getHeader(col, row) as HeaderData).headerType;
} else {
Expand Down
2 changes: 2 additions & 0 deletions packages/vtable/src/header-helper/header-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,8 @@ export class HeaderHelper {
return TextHeaderStyle;
case 'checkbox':
return CheckboxStyle;
default:
return TextHeaderStyle;
}
}

Expand Down
68 changes: 47 additions & 21 deletions packages/vtable/src/scenegraph/group-creater/cell-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -374,8 +374,7 @@ export function createCell(
} else if (type === 'checkbox') {
const isAggregation =
'isAggregation' in table.internalProps.layoutMap && table.internalProps.layoutMap.isAggregation(col, row);
const isSeriesNumber = table.internalProps.layoutMap.isSeriesNumber(col, row);
if (isAggregation && isSeriesNumber) {
if (isAggregation) {
const createTextCellGroup = Factory.getFunction('createTextCellGroup') as CreateTextCellGroup;
cellGroup = createTextCellGroup(
table,
Expand Down Expand Up @@ -423,25 +422,52 @@ export function createCell(
);
}
} else if (type === 'radio') {
const createRadioCellGroup = Factory.getFunction('createRadioCellGroup') as CreateRadioCellGroup;
cellGroup = createRadioCellGroup(
null,
columnGroup,
0,
y,
col,
row,
colWidth,
cellWidth,
cellHeight,
padding,
textAlign,
textBaseline,
table,
cellTheme,
define as RadioColumnDefine,
range
);
const isAggregation =
'isAggregation' in table.internalProps.layoutMap && table.internalProps.layoutMap.isAggregation(col, row);
if (isAggregation) {
const createTextCellGroup = Factory.getFunction('createTextCellGroup') as CreateTextCellGroup;
cellGroup = createTextCellGroup(
table,
value,
columnGroup,
0,
y,
col,
row,
colWidth,
cellWidth,
cellHeight,
padding,
textAlign,
textBaseline,
false,
undefined,
true,
cellTheme,
range,
isAsync
);
} else {
const createRadioCellGroup = Factory.getFunction('createRadioCellGroup') as CreateRadioCellGroup;
cellGroup = createRadioCellGroup(
null,
columnGroup,
0,
y,
col,
row,
colWidth,
cellWidth,
cellHeight,
padding,
textAlign,
textBaseline,
table,
cellTheme,
define as RadioColumnDefine,
range
);
}
} else if (type === 'switch') {
const createSwitchCellGroup = Factory.getFunction('createSwitchCellGroup') as CreateSwitchCellGroup;
cellGroup = createSwitchCellGroup(
Expand Down
Loading