普通视图

发现新文章,点击刷新页面。
昨天以前首页

传说中的表中表:VTable 主从表功能正式上线

作者 玄魂
2025年10月17日 17:42

VTable 主从表插件


本文作者:

薯片(github.com/Violet2314) 广东财经大学


导读

VTable 主从表插件(MasterDetailPlugin)是基于 VisActor VTable 开发的企业级数据可视化组件,专门解决复杂业务场景中的层次化数据展示需求。该插件突破了传统表格的平面化限制,实现了在主表行内嵌入完整子表格的创新交互模式,为用户提供了直观、高效的数据钻取和详情查看体验

image.png核心能力

  • 支持在主表行内嵌入完整的子表格,让复杂数据结构一目了然
  • 支持静态配置和动态函数配置,满足各种业务场景
  • 支持懒加载机制,优化大数据量场景下的性能表现

典型业务场景

业务场景 主表数据 子表数据
订单管理 订单基本信息 商品清单、物流详情
项目管理 项目概览 任务列表、成员分工
财务管理 汇总数据 明细账目、凭证信息
库存管理 产品类别 SKU详情、库存动态
客户管理 客户基本信息 联系记录、交易历史

快速上手

获取NPM包

首先,你需要在项目根目录下使用以下命令安装:

 # 使用 npm 安装
npm install @visactor/vtable @visactor/vtable-plugins

# 使用 yarn 安装
yarn add @visactor/vtable @visactor/vtable-plugins

引入主从表插件

通过 NPM 包引入

import * as VTable from '@visactor/vtable';
import { MasterDetailPlugin } from '@visactor/vtable-plugins';

function generateData(count) {
  const depts = ['Engineering', 'Marketing', 'Sales', 'HR', 'Finance'];
  return Array.from({ length: count }).map(( _ , i) => ({
    id: i + 1,
    rowNo: i + 1,
    name: `姓名 ${i + 1}`,
    department: depts[i % depts.length],
    score: Math.floor(Math.random() * 100),
    amount: Math.floor(Math.random() * 10000) / 100,
    children:
      i % 4 === 0
        ? [
            { task: `子任务 A-${i + 1}`, status: 'open' },
            { task: `子任务 B-${i + 1}`, status: 'done' }
          ]
        : undefined
  }));
}

const records = generateData(11);
 const masterDetailPlugin = new VTablePlugins.MasterDetailPlugin({
id: 'master-detail-static-3',
detailTableOptions: {
  columns: [
    { field: 'task', title: '任务名', width: 220 },
    { field: 'status', title: '状态', width: 120 }
  ],
  defaultRowHeight: 30,
  defaultHeaderRowHeight: 30,
  style: { margin: 12, height: 160 },
  theme: VTable.themes.BRIGHT
}
});

const columns = [
{ field: 'id', title: 'ID', width: 70, sort: true },
{ field: 'rowNo', title: '#', width: 60, headerType: 'text', cellType: 'text' },
{ field: 'name', title: '姓名', width: 140, sort: true },
{ field: 'department', title: '部门', width: 140, sort: true },
{ field: 'score', title: '分数', width: 100, sort: true },
{
  field: 'amount',
  title: '金额',
  width: 120,
  sort: true,
  fieldFormat: (v) => {
    if (typeof v === 'number' && !isNaN(v)) {
      return `$${v.toFixed(2)}`;
    }
    return v === undefined || v === null ? '' : String(v);
  }
}
];

const option = {
  container: document.getElementById(CONTAINER_ID),
  columns,
  records,
  autoFillWidth: true,
  hierarchyTextStartAlignment: true,
  plugins: [masterDetailPlugin]
};

const tableInstance = new VTable.ListTable(option);

运行后效果:

image.png

参数配置

参数名称 类型 默认值 功能说明
id string master-detail-${timestamp} 插件实例的全局唯一标识符,用于区分多个插件实例
enableCheckboxCascade boolean true 是否启用主从表之间的checkbox级联功能,主表中的复选框选择会自动与相应的子表同步
detailTableOptions DetailTableOptions Function 子表配置选项,支持静态对象配置或基于数据的动态配置函数

动态配置示例

const masterDetailPlugin = new MasterDetailPlugin({
  id: 'employee-detail-plugin',
  detailTableOptions: ({ data, bodyRowIndex }) => {
    if (bodyRowIndex === 0) {
      return {
        columns: [
        //......
        ],
        theme: VTable.themes.BRIGHT,
        style: {
          margin: 20,
          height: 300
        }
      };
    }
    return {
      columns: [
      //......
      ],
      theme: VTable.themes.DARK,
      style: {
        margin: 20,
        height: 300
      }
    };
  }
});

主从表插件的主要能力

展开行和渲染子表

当用户点击表格行的展开图标时,系统会在该行下方动态创建一个完整的子表格实例。子表格具备独立的配置、数据源和交互能力,与主表形成层次化的数据展示结构。

20250924002026_rec_.gif

当用户点击展开图标时,会触发以下处理链:

用户点击展开图标
    ↓
EventManager.handleIconClick()
    ↓ 
MasterDetailPlugin.expandRow(rowIndex, colIndex)
    ↓
检查行是否已展开 (isRowExpanded)
    ↓
获取记录数据 (getRecordByRowIndex)
    ↓
MasterDetailPlugin.getChildren()
    ↓
ConfigManager.getDetailConfigForRecord()
    ↓
updateRowHeightForExpand()
    ↓
updateContainerHeight()
    ↓
SubTableManager.renderSubTable()
    ↓
recalculateAllSubTablePositions(bodyRowIndex + 1)
    ↓
drawUnderlineForRow()
    ↓
refreshRowIcon()

技术特性

  • 独立 实例: 每个子表都是完整的VTable实例,支持所有表格功能
  • 动态行高: 主表行高自动适配子表内容,支持自适应和固定高度
  • 位置同步: 主表滚动时子表位置实时跟随,保持视觉连贯性
  • 内存管理: 收起时自动销毁子表实例,展开时重新创建

生命周期管理

创建阶段: 主表行展开 → 解析配置 → 实例化子表

运行阶段: 位置同步 → 事件处理 → 数据更新

销毁阶段: 行收起 → 清理事件 → 销毁实例 → 回收内存

滚动同步机制

主表滚动时,所有子表会实时跟随滚动,保持视觉上的一体化效果。同时优化了滚动事件的触发机制,并且还有主子表的滚动分离机制,即当鼠标在子表内滚动时并且没有滚动到上下边界的时候,我滚动的是子表的内容,主表是不会滚动的,主表滚动的时候子表是不会滚动的

转存失败,建议直接上传图片文件

20250923112352_rec_.gif技术特性

  • scrollEventAlwaysTrigger: 自动设置为true,确保边界滚动也能触发事件
  • 批量更新: 一次滚动事件批量更新所有子表位置

主从表checkbox联动功能

主从表checkbox联动实现了主表与子表之间选择状态的智能同步。当主表行被选中时,其对应的子表中所有行自动选中;当子表中部分行被选中/取消选中时,主表行的选择状态会相应更新状态。使用参数enableCheckboxCascade来决定是否开启,默认是true

主表checkbox点击 → 检测子表存在 → 遍历子表所有行 → 同步选择状态 → 触发联动回调
子表checkbox点击 → 统计子表选中数量 → 计算主表状态 → 更新主表checkbox → 触发联动回调

20250923112506_rec_.gif

技术实现

  • 事件监听: 监听主表和子表的checkbox变化事件
  • 状态同步: 通过内部状态管理器维护选择状态映射关系
  • 回调通知: 选择状态变化时触发相应回调函数,便于业务处理

这种联动机制大大提升了复杂数据结构的操作效率,用户可以通过简单的点击实现批量选择操作。

懒加载功能

当父行记录的 children 字段为 true 时,表示这是一个懒加载节点,需要通过监听 VTable TREE_HIERARCHY_STATE_CHANGE 事件来实现异步数据获取

当用户点击包含懒加载节点的展开图标时,会触发以下调用链:

用户点击展开图标
    ↓
table.toggleHierarchyState()
    ↓
触发 TREE_HIERARCHY_STATE_CHANGE 事件
    ↓
用户事件处理器接收事件参数
    ↓
tableInstance.setLoadingHierarchyState(col, row) 显示loading图标
    ↓
异步数据获取
    ↓
plugin.setRecordChildren(detailData, col, row) 设置数据并展开
    ↓
渲染子表并完成展开
方法 说明 参数
plugin.setLoadingHierarchyState(col, row) 显示loading图标 col: 列索引, row: 行索引
plugin.setRecordChildren(children, col, row) 设置子数据并展开 children: 子数据数组, col: 列索引, row: 行索引

20250923235728_rec_.gif

用户配置示例

const masterData = [
  { id: 1, name: '订单001', children: true },    // 懒加载标识
  { id: 2, name: '订单002', children: [...] }   // 静态数据
];

const plugin = new MasterDetailPlugin({
  detailTableOptions: {
    // 子表配置
  }
});

const tableInstance = new VTable.ListTable(options);

// 监听主从表层次状态变化事件
const { MASTER_DETAIL_HIERARCHY_STATE_CHANGE } = VTable.ListTable.EVENT_TYPE;
tableInstance.on(MASTER_DETAIL_HIERARCHY_STATE_CHANGE, async (args) => {
  if (args.hierarchyState === VTable.TYPES.HierarchyState.expand && 
      args.originData?.children === true) {
    
    // 显示loading状态
    plugin.setLoadingHierarchyState(args.col, args.row);
    
    try {
      // 异步数据获取
      const detailData = await fetchDataFromAPI(args.originData.id);
      
      // 设置子数据并自动展开
      plugin.setRecordChildren(detailData, args.col, args.row);
    } catch (error) {
      console.error('Failed to load detail data:', error);
    }
  }
});

智能缓存机制

  • 一次加载: 数据加载成功后,children: true 自动转换为实际数据数组
  • 永久缓存: 再次点击时识别为静态数据,直接展开无需重新加载

这种设计实现了透明的按需加载,用户只需配置 onLazyLoad 回调,其余状态管理完全由插件自动处理。

小结

VTable 主从表插件是一个正在成长的开源数据展示插件,我们致力于为Web应用提供优秀的层次化数据展示解决方案。

它将复杂的主从数据关系展示能力带到了Web端,同时充分发挥了现代Web技术的交互优势。无论您是要构建订单管理系统、项目管理平台、财务报表系统,还是任何需要主从表功能的Web应用,VTable主从表插件都能为你提供一个良好的选择

在线demo和教程

demo: visactor.com/vtable/demo… 教程: visactor.com/vtable/guid…

欢迎交流

最后,我们诚挚的欢迎所有对数据可视化感兴趣的朋友参与进来,参与 VisActor 的开源建设:

VTableVTable 官网VTable Github(欢迎 Star)

VisActor 官方网站:www.visactor.io/www.viactor.com

Discord:discord.gg/3wPyxVyH6m

飞书群(外网):打开链接扫码

转存失败,建议直接上传图片文件

微信公众号:打开链接扫码

转存失败,建议直接上传图片文件

github:github.com/VisActor

VChart 官网上线 智能助手与分享功能

作者 玄魂
2025年10月13日 20:27

1 🚀 VChart 官网全新分享功能上线,让你的图表“活”起来!

还在为如何分享和展示你的数据可视化作品而烦恼吗?现在,VChart 为您带来一系列强大的分享功能,让您的图表以前所未有的方式“活”起来,轻松嵌入任何应用场景!

该功能有助于您持久化图表案例,快速创建demo与他人进行分享讨论,也可以用来嵌入在其他web 应用中。


1.1 ✨ 分享功能入口

  1. 进入visactor.io/vchartvisactor.com/vchart)官网
  2. Playground页面任一图表Demo 页面
  3. 点击右上角的分享按钮

1.2 ✨ 核心功能说明

全新的分享功能全面支持 原生 JavaScript、 React 和 OpenInula 三大主流环境,确保您的图表Spec在任何环境都能完美呈现!

1.2.1 分享为 Playground:实时互动,即时调试

一键将您的图表配置分享为一个独立的 Playground 链接。您的同事或合作伙伴无需任何本地配置,即可在浏览器中直接查看、修改和调试图表,更可以用来和官方反馈问题,github 提issue时使用。

  • 跨环境支持:在原生、React 和 OpenInula 环境中无缝切换。
  • 配置继承:自动继承您当前使用的 VChart 版本和主题,保证环境一致性。
  • 效果演示:

2. 分享为 iframe:轻松嵌入,无缝集成

需要将图表嵌入到您的网站、博客或内部系统中?现在,只需复制一行 iframe 代码,即可将动态图表无缝集成到任何网页中。

  • 全环境覆盖:同样支持原生、React 和 OpenInula。
  • 版本与主题:自动同步 VChart 版本和主题,与您的应用风格保持一致。
  • 效果演示:
3. 分享为图片:一键截图,快速分享

需要将图表用于报告、演示文稿或社交媒体?全新的“分享为图片”功能,让您一键生成高清图表图片,随时随地分享您的数据洞察。

  • 简单快捷:在原生环境下,一键生成并下载图表图片。
  • 效果演示:

2 🚀 AI 智能助手,让图表编辑更“智能”

VChart 中的 AI 智能助手为图表编辑带来了更多便利与智能体验。一方面,其搜索框集成了 AI 助手,能帮助用户快速查找所需信息,大大提高信息检索效率,减少搜索时间成本 。另一方面,针对 AI 编辑功能,进行了 UI 优化,采用抽屉式交互,这种改进为用户营造了更流畅、更沉浸的编辑环境,减少外界干扰,让用户能够更专注于图表编辑。


2.1 ✨ 搜索框新增 AI 助手

VChart 的搜索框现已集成强大的 AI 助手,助您快速查找所需信息。

通过搜索框打开ai助手

输入问题获取答案:

2.2 ✨ AI 编辑功能 UI 优化

我们对 AI 编辑功能进行了 UI 优化,现已改为抽屉式交互,为您提供更流畅、更沉浸的编辑体验。

3 🚀 立即体验

访问 VChart 官网,立即体验吧!

这只是我们通过 AI 来提升用户体验的一小步,后面还有更多的大的动作,欢迎关注我们,进行交流和建议!

欢迎交流

最后,我们诚挚的欢迎所有对数据可视化感兴趣的朋友参与进来,参与 VisActor 的开源建设:

VChartVChart 官网VChart Github(欢迎 Star)

VTableVTable 官网VTable Github(欢迎 Star)

VMindVMind 官网VMind Github(欢迎 Star)

官方网站:www.visactor.io/www.viactor.com

Discord:discord.gg/3wPyxVyH6m

飞书群(外网):打开链接扫码

微信公众号:打开链接扫码

github:github.com/VisActor

❌
❌