一、特性
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
    }
  }
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐