!!!###!!!title=4.4 VTable 状态管理类型——VisActor/VTable 社区贡献者文档!!!###!!!!!!###!!!description=---title: 4.4 VTable 状态管理类型 key words: VisActor,VChart,VTable,VStrory,VMind,VGrammar,VRender,Visualization,Chart,Data,Table,Graph,Gis,LLM--- !!!###!!!

简介

本文将介绍 VTable 的状态管理模块,以及管理模块内部的维护的管理类型。

状态管理模块

状态模块 StateManager负责管理表格的各个交互的状态,包括选中单元格、hover 高亮效果、菜单的显示效果等。

StateManager 中不仅维护了各个状态的值,同时还定义了更新各个状态的方法,当触发对应事件后,会去更新对应的状态。状态发生变化的时候会去更新场景树,重新渲染图表。

下面来重点讲下在 StateManager 中维护了哪些状态以及不同类型状态的应用场景。

状态类型枚举

关于状态类型的枚举,位于 packages\vtable\src\state\state.ts 中
### interactionState
interactionState: InteractionState; // 主交互状态
interactionStateBeforeScroll?: InteractionState; // 滚动前状态缓存    

interactionState 表示表格当前所处的交互,目前有三种状态。

  • default // 默认空闲状态

  • grabing // 拖拽中

  • scrolling // 滚动中

通过 interactionState 的区分,能够避免表格的交互状态出现冲突。

select 单元格选择

select: {
  ranges: (CellRange & { skipBodyMerge?: boolean })[]; // 多选区范围
  highlightScope: HighlightScope; // 高亮模式(单格/整行/整列/十字)
  cellPos: CellPosition;          // 当前聚焦单元格
  disableHeader?: boolean;        // 禁用表头选中
  disableCtrlMultiSelect?: boolean; // 禁用Ctrl多选
  headerSelectMode?: 'inline' | 'cell' | 'body'; // 表头选择模式
  highlightInRange?: boolean;    // 范围内高亮
  selecting: boolean;             // 正在选择中标识
  customSelectRanges?: {          // 自定义样式选区
    range: CellRange;
    style: CustomSelectionStyle;
  }[];
}    

select 状态维护了当前选中单元格的位置与 select 交互的配置,包括 highlightInRange,disableHeader,headerSelectMode 等。

fillHandle

fillHandle: {
  direction?: 'top' | 'bottom' | 'left' | 'right'; // 拖拽方向
  directionRow?: boolean;         // 是否以行方向填充
  isFilling: boolean;             // 正在填充标识
  startX: number;                 // 起始X坐标
  startY: number;                 // 起始Y坐标
  beforeFillMinCol?: number;      // 填充前选区最小列
  beforeFillMinRow?: number;      // 填充前选区最小行
  beforeFillMaxCol?: number;      // 填充前选区最大列
  beforeFillMaxRow?: number;      // 填充前选区最大行
}    

fillHandle 主要维护的是填充柄的状态,用于标识当前填充的方向以及起始位置等。

hover

hover: {
  highlightScope: HighlightScope; // 悬停高亮模式
  disableHeader?: boolean;        // 禁用表头悬停
  cellPos: CellPosition;          // 当前 hover 位置
  cellPosContainHeader?: CellPosition; *// 记录当前hover的位置(在disableHeader时启用,记录真实位置)*
}    

hover 维护了当前鼠标悬停的单元格位置,以及 hover 相关的配置:highlightScopedisableHeader

columnResize

columnResize: {
  col: number;        // 调整列索引
  x: number;          // 相对表格X坐标
  resizing: boolean;  // 调整列宽中的标记
  isRightFrozen?: boolean; // 是否右侧冻结列
}
    

columnResize 维护了拖拽调整列宽的状态, resizing 字段来表示当前是否处于拖拽调整列宽的状态,而 col 记录了当前正在调整的列索引。

rowResize

rowResize: {
  row: number; // 调整行索引
  */** y坐标是相对table内坐标 */*
  y: number; // 相对表格y坐标
  resizing: boolean;  // 调整行高中的标记
  isBottomFrozen?: boolean; // 是否底部冻结列
};    

相对的,rowResize 记录了拖拽调整行高的状态,row 为当前当前行的索引,y 为当前拖拽位置相对于 table 的y 坐标。

columnMove

columnMove: {
  colSource: number;  // 原始列索引
  colTarget: number;  // 目标列索引
  rowSource: number;  // 原始行索引
  rowTarget: number;  // 目标行索引
  x: number;          // 当前X坐标
  y: number;          // 当前Y坐标
  moving: boolean;    // 移动进行中标识
}    

拖拽列换位的状态维护在 columnRemove 中,内部记录了当前鼠标的坐标信息,以及起始行/列和目标行/列的信息。

menu: {
  x: number;           // 菜单显示X坐标
  y: number;           // 菜单显示Y坐标
  isShow: boolean;     // 显示状态
  itemList: MenuListItem[]; // 菜单项列表
  bounds: Bounds;      // 菜单边界范围
  highlightIndex: number; // 高亮项索引
  dropDownMenuHighlight?: DropDownMenuHighlightInfo[]; // 子菜单高亮
}    

menu 负责下拉菜单的信息,维护了菜单显示坐标、显示状态、菜单项、高亮子菜单的配置等信息。

sort

sort: Array<{         // 多列排序状态
  col: number;        // 排序列索引
  row: number;        // 排序列表头的行索引
  field?: string;     // 排序字段
  order: SortOrder;   // 排序方向
  icon?: Icon;        // 排序图标
}>;
    

VTable 内置的排序状态由 sort 进行维护,由于 VTable 中支持多列排序,所以该配置是一个数组。负责存储当前哪些列进行了排序,同时保存了关于排序的 icon 信息与排序方向。

frozen

frozen: {             // 冻结状态
  col: number;        // 冻结列截止索引
  icon?: Icon;        // 冻结操作图标
};    

冻结列的信息维护在 frozen 中,仅会保存该配置所冻结的列数 frozenColCount 。当列数发生变化时,会去更新场景树。

scroll

scroll: {
  horizontalBarPos: number; // 水平滚动条滑块位置(像素)
  verticalBarPos: number;   // 垂直滚动条滑块位置(像素)
};    

scroll 主要负责下面两件事:

  • 记录滚动条实时位置

  • 与虚拟滚动计算可视区域联动

drill

drill: {
  dimensionKey?: string;  // 当前钻取维度字段
  title?: string;         // 钻取路径显示标题
  drillDown?: boolean;    // 是否下钻状态
  drillUp?: boolean;      // 是否上钻状态
  col: number;            // 触发钻取的列坐标
  row: number;           // 触发钻取的行坐标
};    

透视表支持上卷下钻操作,关于当前钻取的信息,主要是维护在 drill 字段中。包括当前钻取的维度字段、钻取显示的标题等信息。

sparkLine

sparkLine: {
  col: number; // 当前hover的迷你图列坐标
  row: number; // 当前hover的迷你图行坐标
};    

sparkline 存储了 hover 到迷你图时的行列值,便于在鼠标移动到其他单元格时清理Sparkline的高亮状态。

结语

VTable 中的状态模块中有多个管理类型,比如选中单元格的状态、hover 状态等。

通过将表格所有的状态进行抽离,统一到一个地方进行维护,能够降低各个模块之间的耦合度。

将交互拆成状态模块、事件模块以及渲染模块,建立一条事件驱动状态、状态驱动渲染的流程,后续在维护和添加新功能方面也能更加清晰的梳理逻辑。

本文档由以下人员提供

taiiiyang(https://github.com/taiiiyang)

本文档由以下人员修正整理

玄魂