VisActor/VTable - 快速搭建表格
VTable源于VisActor体系,该体系是从字节跳动大量可视化场景沉淀而来,旨在提供面向叙事的智能可视化解决方案。VisActor包括渲染引擎、可视化语法、数据分析组件、图表组件、表格组件、GIS组件、图可视化组件、智能组件等多个模块,以及周边生态组成的可视化解决方案。VTable作为其中的表格组件库,基于可视化渲染引擎VRender进行封装,专为处理复杂的多维数据分析而设计。
一、应用场景与优势
VTable广泛应用于各种需要数据分析和展示的场景中,如企业报表、数据分析平台、商业智能(BI)工具等。通过VTable,用户可以轻松构建出复杂的多维表格,实现数据的快速分析和可视化展示。其优势在于高性能、多维分析能力以及灵活的配置与定制选项,这些特点使得VTable成为数据分析师和开发人员在进行复杂数据分析时的有力工具。
二、表格构成与配置
VTable的表格由五部分组成,分别是行表头、列表头、角表头、body数据单元格和框架。不同形态的表格在构成上可能有所差异,但基本结构相似。
- 行表头:显示在表格左侧,主要显示行维度信息的描述。
- 列表头:位于表格顶部,主要展示列维度信息的描述。
- 角表头:位于表格的左上角,用于显示行表头和列表头的交集信息。
- body数据单元格:表格最主要的显示数据的部分,展示了表格内的详细数据。
- 框架:表格的整体外边框,可以通过配置来改变其样式。
在使用VTable构建多维表格时,用户需要配置相应的参数。例如,通过“rows”定义行维度的字段,通过“columns”定义列维度的字段,通过“indicators”定义要展示的指标(如销售额、成本等),通过“dataConfig”配置数据处理的相关参数(如聚合规则、排序规则、过滤规则等),以及通过“theme”配置表格的整体样式(包括边框、颜色、字体等)。
三、快速上手
VTable 是一款简单易用、高性能、可视化类型丰富的前端可视化表格库。本章将介绍如何使用 VTable 绘制一个简单的基本表格。
3.1 获取VTable
1)使用NPM包
首先,需要在项目根目录下使用以下命令安装 VTable,代码如下:
# 使用 npm 安装
npm install @visactor/vtable
# 使用 yarn 安装
yarn add @visactor/vtable
2)使用CDN
可以通过 CDN 获取构建好的 VTable 文件。代码如下:
<script src="https://unpkg.com/@visactor/vtable/dist/vtable.min.js"></script>
<script>
const tableInstance = new VTable.ListTable(option);
</script>
3.2 引入VTable
1)通过 NPM 包引入
在 JavaScript 文件顶部使用 import 引入 VTable,代码如下:
import * as VTable from '@visactor/vtable';
or;
import { ListTable, PivotTable, TYPES, themes } from '@visactor/vtable';
2)使用 script 标签引入
直接在 HTML 文件中添加 <script> 标签,引入构建好的 vtable 文件,代码如下:
<script src="https://unpkg.com/@visactor/vtable/dist/vtable.min.js"></script>
<script>
const tableInstance = new VTable.ListTable(option);
</script>
四、绘制表格
在绘图前需要注意 VTable 的 DOM 容器,保证容器的宽高值为整数,VTable 内部逻辑中会用到容器的 offsetWidth、offsetHeight、clientWidth、clientHeight 属性,如果容器的 width 和 height 为小数会造成取值有误差,可能产生表格抖动问题。
4.1 绘制基本表格
这里使用的是Vue2的开发环境,要使用npm包安装和引入VTable,可以按照上述的NPM方式进行操作。
4.1.1 模拟数据
在Vue项目中创建data.json文件,用于存储表格的模拟数据。代码如下:
[
{
"id": 1,
"orderId": "CA-2018-156720",
"customer": "JM-15580",
"productName": "Bagged Rubber Bands"
},
{
"id": 2,
"orderId": "CA-2018-115427",
"customer": "EB-13975",
"productName": "GBC Binding covers"
},
{
"id": 3,
"orderId": "CA-2018-115427",
"customer": "EB-13975",
"productName": "Cardinal Slant-D Ring Binder, Heavy Gauge Vinyl"
},
{
"id": 4,
"orderId": "CA-2018-123259",
"customer": "PO-18865",
"productName": "Wilson Jones Legal Size Ring Binders"
},
{
"id": 5,
"orderId": "CA-2018-113259",
"customer": "PO-18865",
"productName": "Gear Head AU3700S Headset"
},
{
"id": 6,
"orderId": "CA-2018-103259",
"customer": "PO-18865",
"productName": "Bush Westfield Collection Bookcases, Fully Assembled"
},
{
"id": 7,
"orderId": "CA-2018-126221",
"customer": "CC-12430",
"productName": "Eureka The Boss Plus 12-Amp Hard Box Upright Vacuum, Red"
},
{
"id": 8,
"orderId": "CA-2018-158526",
"customer": "KH-16360",
"productName": "Harbour Creations Steel Folding Chair"
},
{
"id": 9,
"orderId": "CA-2018-148526",
"customer": "KH-16360",
"productName": "Global Leather and Oak Executive Chair, Black"
}
]
4.1.2 创建Vue模板
在HTML中,为VTable准备一个具备宽高的DOM容器。代码如下:
<template>
<div class="container" ref="vtable"></div>
</template>
<script>
export default {
data () {
return {
}
}
}
</script>
<style lang="less" scoped>
.container {
width: 800px;
height: 500px;
}
</style>
4.1.3 VTable实例
在Script中,引入VTable和data.json模拟数据,并在mounted周期函数中,创建VTable实例,并传入表格的配置项。代码如下:
<template>
<div class="container" ref="vtable"></div>
</template>
<script>
import * as VTable from '@visactor/vtable'
import TestData from './data/data.json'
export default {
data () {
return {
tableInstance: null,
options: {
records: TestData,
columns: [
{field: 'orderId', title: '订单ID', width: 'auto'},
{field: 'customer', title: '客户ID', width: 'auto'},
{field: 'productName', title: '产品名称', width: 'auto'}
],
widthMode: 'standard'
}
}
},
mounted () {
this.tableInstance = new VTable.ListTable(this.$refs['vtable'], this.options)
}
}
</script>
<style lang="less" scoped>
.container {
width: 800px;
height: 500px;
}
</style>
页面效果如下图:
4.2 widthMode
表格列宽度的计算模式,可以是 'standard'(标准模式)、'adaptive'(自适应容器宽度模式)或 'autoWidth'(自动宽度模式),默认为 'standard'。
- 'standard':使用 width 属性指定的宽度作为列宽度。
- 'adaptive':使用表格容器的宽度分配列宽度。
- 'autoWidth':根据列头和 body 单元格中内容的宽度自动计算列宽度,忽略 width 属性的设置。
4.2.1 autoWidth模式
开启自动列宽 widthMode:'autoWidth'或者 columns 中设置了 width:'auto',如刚“4.1.3 VTable实例”中配置项中通过columns设置width: 'auto',这里修改为widthMode: 'autoWidth',代码如下:
<template>
<div class="container" ref="vtable"></div>
</template>
<script>
import * as VTable from '@visactor/vtable'
import TestData from './data/data.json'
export default {
data () {
return {
tableInstance: null,
options: {
records: TestData,
columns: [
{field: 'orderId', title: '订单ID'},
{field: 'customer', title: '客户ID'},
{field: 'productName', title: '产品名称'}
],
widthMode: 'autoWidth'
}
}
},
mounted () {
this.tableInstance = new VTable.ListTable(this.$refs['vtable'], this.options)
}
}
</script>
<style lang="less" scoped>
.container {
width: 800px;
height: 500px;
}
</style>
效果如下图:
4.2.2 adaptive模式
如上图可见,虽然列的宽度开启了自适应,但是并未根据容器的宽度进行分配。所以,这里将widthMode设置为adaptive,代码如下:
<template>
<div class="container" ref="vtable"></div>
</template>
<script>
import * as VTable from '@visactor/vtable'
import TestData from './data/data.json'
export default {
data () {
return {
tableInstance: null,
options: {
records: TestData,
columns: [
{field: 'orderId', title: '订单ID'},
{field: 'customer', title: '客户ID'},
{field: 'productName', title: '产品名称'}
],
widthMode: 'adaptive'
}
}
},
mounted () {
this.tableInstance = new VTable.ListTable(this.$refs['vtable'], this.options)
}
}
</script>
<style lang="less" scoped>
.container {
width: 800px;
height: 500px;
}
</style>
效果如下图:
4.3 heightMode
表格行高的计算模式,可以是 'standard'(标准模式)、'adaptive'(自适应容器高度模式)或 'autoHeight'(自动行高模式),默认为 'standard'。
- 'standard':采用 defaultRowHeight 及 defaultHeaderRowHeight 作为行高。
- 'adaptive':使用容器的高度分配每行高度,基于每行内容计算后的高度比例来分配。
- 'autoHeight':根据内容自动计算行高,计算依据 fontSize 和 lineHeight(文字行高),以及 padding。相关搭配设置项autoWrapText自动换行,可以根据换行后的多行文本内容来计算行高。
4.3.1 adaptive模式
同样,将heightMode设置为adaptive,表格的行高也会根据容器的调度进行分配。代码如下:
<template>
<div class="container" ref="vtable"></div>
</template>
<script>
import * as VTable from '@visactor/vtable'
import TestData from './data/data.json'
export default {
data () {
return {
tableInstance: null,
options: {
records: TestData,
columns: [
{field: 'orderId', title: '订单ID'},
{field: 'customer', title: '客户ID'},
{field: 'productName', title: '产品名称'}
],
widthMode: 'adaptive',
heightMode: 'adaptive'
}
}
},
mounted () {
this.tableInstance = new VTable.ListTable(this.$refs['vtable'], this.options)
}
}
</script>
<style lang="less" scoped>
.container {
width: 800px;
height: 500px;
}
</style>
效果如下图:
五、theme主题
表格主题,其中内置主题名称有 DEFAULT, ARCO, BRIGHT, DARK, SIMPLIFY,具体配置方式可用内置类型或者直接使用字符串名称配置:
VTable.themes.DEFAULT
VTable.themes.ARCO;
VTable.themes.BRIGHT
VTable.themes.DARK
VTable.themes.SIMPLIFY
or
'default'
'arco'
'bright'
'dark'
'simplify'
5.1 修改主题
为适应数据大屏的暗黑模式,也可以满足用户在性能、可读性和定制化方面的需求。故可以使用VTable中内置主题,将表格修改为暗黑模式。代码如下:
<template>
<div class="container" ref="vtable"></div>
</template>
<script>
import * as VTable from '@visactor/vtable'
import TestData from './data/data.json'
export default {
data () {
return {
tableInstance: null,
options: {
records: TestData,
columns: [
{field: 'orderId', title: '订单ID'},
{field: 'customer', title: '客户ID'},
{field: 'productName', title: '产品名称'}
],
widthMode: 'adaptive',
heightMode: 'adaptive',
theme: VTable.themes.DARK
}
}
},
mounted () {
this.tableInstance = new VTable.ListTable(this.$refs['vtable'], this.options)
}
}
</script>
<style lang="less" scoped>
.container {
width: 800px;
height: 500px;
}
</style>
效果如下图:
5.2 主题的扩展
同时可以基于内置主题进行扩展,例如想基于 DARK 主题将表格圆角去除,以及外边框设置为虚线。
在 VTable 中,可以通过 borderLineDash 属性来设置表格线条为虚线。borderLineDash 是一个数组,用于定义虚线的样式,其中包含两个值:第一个值表示虚线的长度,第二个值表示虚线之间的间隔。代码如下:
<template>
<div class="container" ref="vtable"></div>
</template>
<script>
import * as VTable from '@visactor/vtable'
import TestData from './data/data.json'
export default {
data () {
return {
tableInstance: null,
options: {
records: TestData,
columns: [
{field: 'orderId', title: '订单ID'},
{field: 'customer', title: '客户ID'},
{field: 'productName', title: '产品名称'}
],
widthMode: 'adaptive',
heightMode: 'adaptive',
theme: VTable.themes.DARK.extends({
frameStyle: {
cornerRadius: 0,
borderLineDash: [5, 5] // 虚线样式,表示虚线长度为5,间隔为5
}
})
}
}
},
mounted () {
this.tableInstance = new VTable.ListTable(this.$refs['vtable'], this.options)
}
}
</script>
<style lang="less" scoped>
.container {
width: 800px;
height: 500px;
}
</style>
通过borderLineDash这种方式,可以轻松地将 VTable 的表格线条设置为虚线。如下图:
六、列的层级结构
在 VTable 中设置合并列头,可以通过定义列的层级结构来实现。具体方法是在columns列数据中增加 columns 子数组属性来定义子列,从而实现多级表头的合并效果。
6.1 更新数据
在模拟数据中添加用户名称,并且将姓名分为姓和名两部分。数据如下:
[
{
"id": 1,
"orderId": "CA-2018-156720",
"customer": "JM-15580",
"productName": "Bagged Rubber Bands",
"firstName": "王",
"lastName": "小明"
},
{
"id": 2,
"orderId": "CA-2018-115427",
"customer": "EB-13975",
"productName": "GBC Binding covers",
"firstName": "李",
"lastName": "红光"
},
{
"id": 3,
"orderId": "CA-2018-115427",
"customer": "EB-13975",
"productName": "Cardinal Slant-D Ring Binder, Heavy Gauge Vinyl",
"firstName": "孙",
"lastName": "旺"
},
{
"id": 4,
"orderId": "CA-2018-123259",
"customer": "PO-18865",
"productName": "Wilson Jones Legal Size Ring Binders",
"firstName": "童",
"lastName": "大牛"
},
{
"id": 5,
"orderId": "CA-2018-113259",
"customer": "PO-18865",
"productName": "Gear Head AU3700S Headset",
"firstName": "杨",
"lastName": "红"
},
{
"id": 6,
"orderId": "CA-2018-103259",
"customer": "PO-18865",
"productName": "Bush Westfield Collection Bookcases, Fully Assembled",
"firstName": "王",
"lastName": "順"
},
{
"id": 7,
"orderId": "CA-2018-126221",
"customer": "CC-12430",
"productName": "Eureka The Boss Plus 12-Amp Hard Box Upright Vacuum, Red",
"firstName": "刘",
"lastName": "大年"
},
{
"id": 8,
"orderId": "CA-2018-158526",
"customer": "KH-16360",
"productName": "Harbour Creations Steel Folding Chair",
"firstName": "朱",
"lastName": "棣"
},
{
"id": 9,
"orderId": "CA-2018-148526",
"customer": "KH-16360",
"productName": "Global Leather and Oak Executive Chair, Black",
"firstName": "章",
"lastName": "红光"
}
]
6.2 合并列头
以下示例代码,展示如何设置合并列头:
<template>
<div class="container" ref="vtable"></div>
</template>
<script>
import * as VTable from '@visactor/vtable'
import TestData from './data/data.json'
export default {
data () {
return {
tableInstance: null,
options: {
records: TestData,
columns: [
{field: 'orderId', title: '订单ID'},
{field: 'customer', title: '客户ID'},
{title: '姓名',
columns: [
{field: 'firstName', title: '姓', width: '50px'},
{field: 'lastName', title: '名'}
]
},
{field: 'productName', title: '产品名称', width: '200px'}
],
widthMode: 'adaptive',
heightMode: 'adaptive',
theme: VTable.themes.DARK.extends({
frameStyle: {
cornerRadius: 0,
borderLineDash: [5, 5]
}
})
}
}
},
mounted () {
this.tableInstance = new VTable.ListTable(this.$refs['vtable'], this.options)
}
}
</script>
<style lang="less" scoped>
.container {
width: 800px;
height: 500px;
}
</style>
效果如下图:
说明:
- 多级表头结构:通过在 columns 中定义 columns 属性,可以创建多级表头。
- 字段绑定:子列的 field 属性需要与数据源中的字段对应,以确保数据能够正确显示。
- 通过这种方式,可以灵活地实现表头的合并和分组效果。
注意:VTable的API和用法可能会随着版本的更新而发生变化,因此,建议查阅最新的VTable官方文档 ,地址:VTable —— 不只是高性能的多维数据分析表格,更是行列间创作的方格艺术家,以获取最准备的信息。