Skip to content

Commit 09e2a94

Browse files
author
李杨枚
committed
feat: column header of the ListTable supports folding
1 parent 49a2964 commit 09e2a94

4 files changed

Lines changed: 63 additions & 12 deletions

File tree

packages/vtable/src/ListTable.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import { computeColWidth } from './scenegraph/layout/compute-col-width';
3636
import { computeRowHeight } from './scenegraph/layout/compute-row-height';
3737
import { defaultOrderFn } from './tools/util';
3838
import type { IEditor } from '@visactor/vtable-editors';
39-
import type { ColumnData, ColumnDefine } from './ts-types/list-table/layout-map/api';
39+
import type { ColumnData, ColumnDefine, HeaderData } from './ts-types/list-table/layout-map/api';
4040
import { getCellRadioState, setCellRadioState } from './state/radio/radio';
4141
import { cloneDeepSpec } from '@visactor/vutils-extension';
4242
import { getGroupCheckboxState, setCellCheckboxState } from './state/checkbox/checkbox';
@@ -839,6 +839,9 @@ export class ListTable extends BaseTable implements ListTableAPI {
839839
* @returns
840840
*/
841841
getHierarchyState(col: number, row: number) {
842+
if (this.isHeader(col, row)) {
843+
return (this._getHeaderLayoutMap(col, row) as HeaderData)?.hierarchyState;
844+
}
842845
if (!this.options.groupBy || (isArray(this.options.groupBy) && this.options.groupBy.length === 0)) {
843846
const define = this.getBodyColumnDefine(col, row) as ColumnDefine;
844847
if (!define.tree) {
@@ -857,6 +860,34 @@ export class ListTable extends BaseTable implements ListTableAPI {
857860
toggleHierarchyState(col: number, row: number, recalculateColWidths: boolean = true) {
858861
this.stateManager.updateHoverIcon(col, row, undefined, undefined);
859862
const hierarchyState = this.getHierarchyState(col, row);
863+
if (this.isHeader(col, row)) {
864+
// 表头的展开和收起
865+
const headerTreeNode = this.internalProps.layoutMap.getHeader(col, row) as any;
866+
const { hierarchyState: rawHierarchyState, define: columnDefine } = headerTreeNode;
867+
if (![HierarchyState.collapse, HierarchyState.expand].includes(rawHierarchyState) || !columnDefine) {
868+
return;
869+
}
870+
const children = columnDefine.columns;
871+
// 有子节点才需要自动展开和折叠
872+
if (!!Array.isArray(children) && children.length > 0) {
873+
const hierarchyState =
874+
rawHierarchyState === HierarchyState.expand ? HierarchyState.collapse : HierarchyState.expand;
875+
headerTreeNode.hierarchyState = hierarchyState;
876+
headerTreeNode.define.hierarchyState = hierarchyState;
877+
// 全量更新
878+
this.updateColumns(this.internalProps.columns);
879+
}
880+
881+
this.fireListeners(TABLE_EVENT_TYPE.TREE_HIERARCHY_STATE_CHANGE, {
882+
col,
883+
row,
884+
hierarchyState,
885+
originData: headerTreeNode,
886+
cellLocation: this.getCellLocation(col, row)
887+
});
888+
return;
889+
}
890+
860891
if (hierarchyState === HierarchyState.expand) {
861892
this._refreshHierarchyState(col, row, recalculateColWidths);
862893
this.fireListeners(TABLE_EVENT_TYPE.TREE_HIERARCHY_STATE_CHANGE, {

packages/vtable/src/layout/simple-header-layout.ts

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
import { isValid, merge } from '@visactor/vutils';
33
import type { ListTable } from '../ListTable';
44
import { DefaultSparklineSpec } from '../tools/global';
5-
import type {
6-
CellAddress,
7-
CellRange,
8-
CellLocation,
9-
IListTableCellHeaderPaths,
10-
LayoutObjectId,
11-
AggregationType,
12-
Aggregation,
13-
IRowSeriesNumber
5+
import {
6+
type CellAddress,
7+
type CellRange,
8+
type CellLocation,
9+
type IListTableCellHeaderPaths,
10+
type LayoutObjectId,
11+
type Aggregation,
12+
type IRowSeriesNumber,
13+
HierarchyState
1414
} from '../ts-types';
1515
import type { ChartColumnDefine, ColumnsDefine } from '../ts-types/list-table/define';
1616
import type {
@@ -66,6 +66,10 @@ export class SimpleHeaderLayoutMap implements LayoutMapAPI {
6666
_hasAggregationOnBottomCount: number = 0;
6767
/**层级维度结构显示形式 */
6868
rowHierarchyType?: 'grid' | 'tree';
69+
/** 列表头树形展示模式 */
70+
columnHierarchyType?: 'grid-tree';
71+
/** 列表头默认展开层级 */
72+
columnExpandLevel?: number;
6973
// 缓存行号列号对应的cellRange 需要注意当表头位置拖拽后 这个缓存的行列号已不准确 进行重置
7074
_cellRangeMap: Map<string, CellRange>; //存储单元格的行列号范围 针对解决是否为合并单元格情况
7175
constructor(table: ListTable, columns: ColumnsDefine, showHeader: boolean, hierarchyIndent: number) {
@@ -77,7 +81,14 @@ export class SimpleHeaderLayoutMap implements LayoutMapAPI {
7781
this._headerCellIds = [];
7882
this.hierarchyIndent = hierarchyIndent ?? 20;
7983
this.hierarchyTextStartAlignment = table.options.hierarchyTextStartAlignment;
80-
this.columnTree = new DimensionTree(columns as any, { seqId: 0 }, null); //seqId这里没有利用上 所有顺便传了0
84+
this.columnHierarchyType = table.options.columnHierarchyType;
85+
this.columnExpandLevel = table.options.columnExpandLevel ?? 1;
86+
this.columnTree = new DimensionTree(
87+
columns as any,
88+
{ seqId: 0 },
89+
this.columnHierarchyType,
90+
this.columnHierarchyType === 'grid-tree' ? this.columnExpandLevel : undefined
91+
); //seqId这里没有利用上 所有顺便传了0
8192
this._headerObjectsIncludeHided = this._addHeaders(0, columns, []);
8293
// this._headerObjectMapIncludeHided = this._headerObjectsIncludeHided.reduce((o, e) => {
8394
// o[e.id as number] = e;
@@ -989,6 +1000,8 @@ export class SimpleHeaderLayoutMap implements LayoutMapAPI {
9891000
headerType: hd.headerType ?? 'text',
9901001
dropDownMenu: hd.dropDownMenu,
9911002
define: hd,
1003+
// 展开/折叠状态
1004+
hierarchyState: (hd as HeaderData).hierarchyState,
9921005
columnWidthComputeMode: hd.columnWidthComputeMode
9931006
// iconPositionList:[]
9941007
};
@@ -1002,7 +1015,9 @@ export class SimpleHeaderLayoutMap implements LayoutMapAPI {
10021015
} else if (this._headerCellIds[row - 1]) {
10031016
rowCells[col] = this._headerCellIds[row - 1][col];
10041017
}
1005-
if (hd.columns) {
1018+
// 当前节点是展开状态才需要添加子节点
1019+
const expand = (hd as HeaderData).hierarchyState === HierarchyState.expand;
1020+
if (!!hd.columns && !!expand) {
10061021
const isAllHided = hd.columns.every((c: any) => c.hide);
10071022
!isAllHided &&
10081023
this._addHeaders(

packages/vtable/src/ts-types/events.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ export interface TableEventHandlersEventArgumentMap {
203203
dimensionInfo?: IDimensionInfo[];
204204
/**整条数据-原始数据 */
205205
originData?: any;
206+
cellLocation?: CellLocation;
206207
};
207208
vchart_event_type: {
208209
eventName: string;

packages/vtable/src/ts-types/table-engine.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,10 @@ export interface ListTableConstructorOptions extends BaseTableConstructorOptions
239239
hierarchyExpandLevel?: number;
240240
/** 同层级的结点是否按文字对齐 如没有收起展开图标的节点和有图标的节点文字对齐 默认false */
241241
hierarchyTextStartAlignment?: boolean;
242+
/** 列表头树形展示模式(设置成 'grid-tree' 则支持展开和折叠) */
243+
columnHierarchyType?: 'grid-tree';
244+
/** 列表头默认展开层级(columnHierarchyType 为 'grid-tree' 时有效) */
245+
columnExpandLevel?: number;
242246
/** 分页配置 */
243247
pagination?: IPagination;
244248

0 commit comments

Comments
 (0)