
S2 引擎-大数据分析表格
antvS2
·
一、特性
1)开箱即用:提供不同场景下开箱即用的 React, Vue3 表组件及配套分析组件,只需要简单的配置即可轻松实现复杂场景。
2)多维交叉分析: 告别单一分析维度,全面拥抱任意维度的自由组合分析。
3)高性能:能支持全量百万数据下 < 4s 渲染,也能通过局部下钻来实现秒级渲染。
4)高扩展性:支持任意的自定义扩展(包括但不局限于布局,样式,交互,数据流等)。
5)交互友好:支持丰富的交互形式(单选、圈选、行选、列选、冻结行头、宽高拖拽,自定义交互等)
二、实现原理
G 是 Antv 系列的底层渲染引擎,为上层提供一致、高性能的 2D / 3D 图形渲染能力,适配 Web 端全部底层渲染 API (Canvas2D / SVG / WebGL / WebGPU / CanvasKit)。
s2 是基于 @antv/g 渲染的 canvas 表格,通过配置信息将原始数据处理,转换为以 行、列 纬度值为 path 的多维数组。在此之后,通过 hierarchy 来改变自动生成的层级结构。然后通过 layout 更改任意行、列、单元格的坐标信息。最后由 layoutResult 来确定行、列的笛卡尔交集的 dataCell 数据信息。
在性能的优化上做了,按需渲染和缓存设计:
按需渲染:只渲染可视区域内的单元格,滚动后通过 scrollX 和 scrollY,计算当前视窗中的单元格的节点索引,去动态并新增和删除单元格。
三、本地化
3.1 使用
// 生成 S2DataConfig: 数据配置,S2Options:参数配置,S2Theme:主题配置
const changeVariables = () => {
options.value = tableConfig.initOptions(columns.value, tableRef.value, props.options, headerCallBack, globalClickCallBack)
theme.value = tableConfig.initTheme(props.theme)
dataConfig.value = tableConfig.initDataConfig(columns.value, tableData.value, props.customTableSheetTotal, dataCellDbClickCallBack)
}
// s2 实例化
const initTable = () => {
// 实例类型:TableSheet 明细表,PivotSheet 交叉表
tableSheet.value = type.value === 'tableSheet' ? new TableSheet(tableRef.value, dataConfig.value, options.value) : new PivotSheet(tableRef.value, dataConfig.value, options.value)
// 设置主题
tableSheet?.value.setTheme(theme.value)
tableSheet?.value.render()
// 类属性赋值
tableConfig.tableSheet = tableSheet.value
tableConfig.tableRef = tableRef.value
// 注册单元格点击事件
tableConfig.dataCellClick()
}
// 画布尺寸监听,动态改变表格宽高
const addResizeEvent = () => {
const resizeObserver = window.ResizeObserver
const callback = (domList) => {
if (!domList[0]) return
let { width, height } = tableRef.value.getBoundingClientRect()
tableConfig.autoLayoutRender(width, height)
}
observer = new resizeObserver(callback)
observer.observe(tableRef.value)
}
3.2 自定义表头样式
// 自定义 customColCell 进行继承实现
export class customColCell extends ColCell {
initCell() {
super.initCell()
}
// 基于 s2 getBackgroundColor 自定义表头二级列背景色
getBackgroundColor() {
let backgroundStyle = super.getBackgroundColor()
...
backgroundStyle = { ... }
return backgroundStyle
}
// 基于 s2 addActionIcon 自定义表头 icon ,主要用于改变颜色
addActionIcon(options) {
...
var icon = new GuiIcon({ ... })
icon.set('visible', !defaultHide)
icon.on('mouseover', function (event) { ... })
icon.on('mouseleave', function (event) { ... })
icon.on('click', function (event) { ... })
this.actionIcons.push(icon)
this.add(icon)
}
}
3.3 自定义操作列
// 继承 s2 数据单元格,并追加自定义
export class customDataCell extends DataCell {
initCell() {
super.initCell()
// 在绘制完原本的单元格后, 再绘制定制化内容
this.renderCustomDataCell()
}
// 自定义单元格渲染
renderCustomDataCell() {
let textStyle = {
fill: '#8B60F0',
fontSize: 12,
lineHeight: 34,
textAlign: 'center',
cursor: 'pointer',
textBaseline: 'middle',
opacity: 1
}
...
actionList.map((item, index) => {
textStyle = {
...textStyle,
...item?.textStyle
}
...
switch (item.type) {
case 'default':
this.addShape('text', {
attrs: {
text: fieldValue,
...position.text,
...textStyle
}
})
break
case 'operate':
this.addShape('text', {
attrs: {
x: x,
y: position.text.y,
text: item.name,
...textStyle
}
})
break
}
})
}
}
3.4 自定义支持汇总
export class customDataCell extends DataCell {
drawTextShape() {
let { valueField, rowIndex } = this.meta
let { dataCfg } = this.spreadsheet
// 处理明细表汇总
if (dataCfg.customTableSheetTotal.enable && rowIndex === dataCfg.data.length - 1) {
this.meta.isTotals = true
if (valueField === '$$series_number$$') {
this.meta.fieldValue = dataCfg.customTableSheetTotal.label
}
}
super.drawTextShape()
}
// 汇总行填充色
drawBackgroundShape() {
super.drawBackgroundShape()
let { rowIndex } = this.meta
let { dataCfg } = this.spreadsheet
if (dataCfg.customTableSheetTotal.enable && rowIndex === dataCfg.data.length - 1)
this.backgroundShape.attr('fill', '#f5f7fa')
}
}
...
// 计算逻辑,另外
3.5 单元格数据格式化
// 封装的数据过滤方法
...
export const filterList = [
{
label: '数据转换',
options: [...]
},
{
label: '日期时间',
options: [...]
}
]
static initDataConfig(columns, data, customTableSheetTotal = { enable: false, label: '汇总' }, dataCellDbClickCallBack) {
...
columnsCustom.map(item => {
let { field, name, alias, formatter } = item
...
meta.push({
field,
name: alias || name,
item,
formatter,
dataCellDbClickCallBack
})
})
// 兼容二级表头
columnsCustom.map(item => {
...
})
// 汇总处理
data = this.handleTableSheetTotal(columns, data, customTableSheetTotal)
return {
...this.defaultDataConfig(),
fields,
meta,
data,
customTableSheetTotal
}
}
更多推荐
所有评论(0)