vxe-table 数据分组 + 单元格图表:柱状图与饼图渲染实战

在数据管理后台中,我们经常需要按维度分组展示数据,并在表格内直接呈现图表(如销售对比、完成率等),让用户一眼看懂趋势。 vxe-table 提供了强大的分组聚合(aggregateConfig)与单元格渲染(cellRender)能力,可以轻松实现"分组表格 + 柱状图/饼图"的混合展示。

该示例在分组表格中为每一行数据渲染柱状图(计划 vs 实际)和饼图(占比)。

html 复制代码
<template>
  <div>
    <vxe-grid ref="gridRef" v-bind="gridOptions"></vxe-grid>
  </div>
</template>

<script setup>
import { reactive } from 'vue'

const salesAmountsCellRender = reactive({
  name: 'bar',
  props: {
    bar: {
      max: 500 // 柱状图最大值(用于统一坐标尺度)
    },
    colors: ['#91C7AE', '#D48265'], // 系列颜色:[计划, 实际]
    labels: ['计划销售', '实际销售'],  // 图例标签
    tooltip: {
      formatter: '{label}:{value}元'
    },
    label: {
      formatter: '{value}元'
    }
  }
})

const salesCompletenessCellRender = reactive({
  name: 'pie',
  props: {
    colors: ['#91C7AE', '#D48265'],
    labels: ['计划销售', '实际销售'],
    tooltip: {
      formatter: '{label}:{value}元'
    }
  }
})

const gridOptions = reactive({
  height: 500,
  showOverflow: true,
  aggregateConfig: {
    groupFields: ['name']
  },
  columnConfig: {
    resizable: true
  },
  columns: [
    { type: 'seq', width: 70 },
    { field: 'group', title: 'Group', minWidth: 140, rowGroupNode: true },
    { field: 'date', title: '日期', width: 140 },
    { field: 'name', title: '产品名称' },
    { field: 'department', title: '部门' },
    { field: 'salesAmounts', title: '柱状图', minWidth: 160, cellRender: salesAmountsCellRender },
    { field: 'salesCompleteness', title: '饼图', width: 140, cellRender: salesCompletenessCellRender }
  ],
  data: [
    { id: 10001, name: '笔记本', department: '销售1部', actualAmount: 80, plannedAmount: 100, salesAmounts: [100, 80], salesCompleteness: [100, 80], date: '2025-02-01' },
    { id: 10002, name: '手机', department: '销售3部', actualAmount: 140, plannedAmount: 120, salesAmounts: [120, 140], salesCompleteness: [120, 140], date: '2025-01-01' },
    { id: 10003, name: '键盘', department: '销售2部', actualAmount: 220, plannedAmount: 200, salesAmounts: [200, 220], salesCompleteness: [200, 220], date: '2025-05-01' },
    { id: 10004, name: '鼠标', department: '销售1部', actualAmount: 110, plannedAmount: 140, salesAmounts: [140, 110], salesCompleteness: [140, 110], date: '2025-01-01' },
    { id: 10005, name: '笔记本', department: '销售2部', actualAmount: 40, plannedAmount: 90, salesAmounts: [90, 40], salesCompleteness: [90, 40], date: '2025-01-01' },
    { id: 10006, name: '鼠标', department: '销售4部', actualAmount: 40, plannedAmount: 120, salesAmounts: [120, 40], salesCompleteness: [120, 40], date: '2025-03-01' },
    { id: 10007, name: '键盘', department: '销售1部', actualAmount: 234, plannedAmount: 300, salesAmounts: [300, 234], salesCompleteness: [300, 234], date: '2025-05-01' },
    { id: 10008, name: '手机', department: '销售4部', actualAmount: 146, plannedAmount: 240, salesAmounts: [240, 146], salesCompleteness: [240, 146], date: '2025-11-01' },
    { id: 10009, name: '笔记本', department: '销售3部', actualAmount: 78, plannedAmount: 120, salesAmounts: [120, 78], salesCompleteness: [120, 78], date: '2025-05-01' },
    { id: 10010, name: '笔记本', department: '销售4部', actualAmount: 100, plannedAmount: 130, salesAmounts: [130, 100], salesCompleteness: [130, 100], date: '2025-03-01' },
    { id: 10011, name: '手机', department: '销售2部', actualAmount: 146, plannedAmount: 150, salesAmounts: [150, 146], salesCompleteness: [150, 146], date: '2025-03-01' },
    { id: 10012, name: '键盘', department: '销售4部', actualAmount: 130, plannedAmount: 130, salesAmounts: [130, 130], salesCompleteness: [130, 130], date: '2025-10-01' },
    { id: 10013, name: '手机', department: '销售2部', actualAmount: 140, plannedAmount: 80, salesAmounts: [80, 140], salesCompleteness: [80, 140], date: '2025-02-01' },
    { id: 10014, name: '笔记本', department: '销售1部', actualAmount: 200, plannedAmount: 100, salesAmounts: [100, 200], salesCompleteness: [100, 200], date: '2025-08-01' },
    { id: 10015, name: '键盘', department: '销售3部', actualAmount: 320, plannedAmount: 300, salesAmounts: [300, 320], salesCompleteness: [300, 320], date: '2025-05-01' },
    { id: 10016, name: '笔记本', department: '销售4部', actualAmount: 380, plannedAmount: 400, salesAmounts: [400, 380], salesCompleteness: [400, 380], date: '2025-10-01' },
    { id: 10017, name: '鼠标', department: '销售1部', actualAmount: 34, plannedAmount: 200, salesAmounts: [200, 34], salesCompleteness: [200, 34], date: '2025-12-01' },
    { id: 10018, name: '键盘', department: '销售4部', actualAmount: 100, plannedAmount: 150, salesAmounts: [150, 100], salesCompleteness: [150, 100], date: '2025-10-01' },
    { id: 10019, name: '鼠标', department: '销售3部', actualAmount: 90, plannedAmount: 120, salesAmounts: [120, 90], salesCompleteness: [120, 90], date: '2025-02-01' },
    { id: 10020, name: '手机', department: '销售2部', actualAmount: 40, plannedAmount: 50, salesAmounts: [50, 40], salesCompleteness: [50, 40], date: '2025-03-01' }
  ]
})
</script>

柱状图/ 饼图渲染器参数

参数 说明
bar.max 柱状图的最大值刻度,用于统一多个单元格的视觉比例
colors 系列颜色数组,按数据顺序对应
labels 图例/提示框显示的文本
tooltip.formatter 鼠标悬浮时的提示内容,{label} 对应 labels 项,{value} 对应数据值
label.formatter 柱顶数值标签格式

vxeui.com

相关推荐
慧一居士3 小时前
Element Plus 按需引入的配置使用说明和完整示例
前端·vue.js
CoderWeen7 小时前
我写了个能一步步点着看的 Dijkstra 可视化项目(Vue3 + Leaflet + Generator)
前端·javascript·vue.js
无人生还7 小时前
第 1 篇:从 Vue3 到 React 的思维转变
前端·vue.js·react.js
就业发动机7 小时前
我用 Tauri 做了一个约 1.5 MB 的开源屏幕标注工具:MarkerOn
vue.js·rust
爱分享的程序猿-Clark8 小时前
【前端分享】vue开发项目,如何实现 从A页面跳转到B页面,并传值!
前端·javascript·vue.js
徐小夕8 小时前
花了3天,我写了一款开源AI公众号编辑器
前端·vue.js·github
come112349 小时前
Vue 2 与 Vue 3 语法区别及使用技巧
前端·javascript·vue.js
腻害兔9 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:ERP 企业资源模块,一个轻量级进销存的完整实现?
前端·javascript·vue.js·人工智能·前端框架·产品经理·ai编程
Simon_He10 小时前
AI 对话里的流式 Markdown 为什么难:从不完整 Token 到增量渲染
vue.js
达子66610 小时前
第4章_图解HarmonyOS 的结构
vue.js