当前位置: 首页 > news >正文

若依后台数据大屏实战:用ECharts嵌套饼图可视化你的SQL查询结果

若依后台数据大屏实战:用ECharts嵌套饼图可视化你的SQL查询结果

在数据驱动的时代,企业后台管理系统中的业务数据可视化已成为提升决策效率的关键。本文将带你从零开始,在若依分离版系统中实现一个完整的"计划与实际对比"数据大屏,重点讲解如何将数据库查询结果转化为直观的ECharts嵌套饼图。

1. 环境准备与数据查询

在开始可视化之前,我们需要确保开发环境配置正确。对于使用若依分离版的开发者,首先需要确认Vue和ECharts的版本兼容性:

# Vue 2项目推荐版本 npm install echarts@4.9.0 vue-echarts@5.0.0-beta.0 --force -save npm i -D @vue/composition-api # Vue 3项目推荐版本 npm install echarts@5.2.2 vue-echarts@6.0.0 --force -save

数据查询是可视化的第一步。假设我们需要从sm_shipment_daily表中获取2024年8月的发货数据:

SELECT DATE_FORMAT(shipment_date, '%Y-%m-%d') AS day, SUM(plan_quantity) AS daily_plan, SUM(actual_quantity) AS daily_actual, MONTH(shipment_date) AS month FROM sm_shipment_daily WHERE DATE_FORMAT(shipment_date,'%Y-%m')='2024-08' GROUP BY day

2. 数据格式转换与聚合

从数据库获取的原始数据通常需要经过处理才能适配ECharts的格式要求。我们需要将查询结果转换为嵌套饼图所需的结构:

// 假设后端API返回的数据结构 const rawData = [ { day: '2024-08-01', daily_plan: 1548, daily_actual: 775 }, { day: '2024-08-02', daily_plan: 1620, daily_actual: 810 }, // ...其他日期数据 ] // 转换为ECharts需要的格式 function transformData(rawData) { const monthlyPlan = rawData.reduce((sum, item) => sum + item.daily_plan, 0) const monthlyActual = rawData.reduce((sum, item) => sum + item.daily_actual, 0) return { daily: [ { value: rawData[0].daily_plan, name: '天计划' }, { value: rawData[0].daily_actual, name: '天实际' } ], monthly: [ { value: monthlyPlan, name: '月计划' }, { value: monthlyActual, name: '月实际' } ] } }

3. ECharts嵌套饼图深度配置

嵌套饼图(也称为环形图)通过多层饼图叠加实现,核心在于radius参数的配置:

const option = { tooltip: { trigger: 'item', formatter: params => { const { seriesName, name, value, percent } = params return `${seriesName}<br/>${name}: ${value} (${percent}%)` } }, series: [ { name: '当日数据', type: 'pie', radius: ['0%', '40%'], label: { position: 'inner', formatter: '{b}\n{c}', fontSize: 14 }, labelLine: { show: false }, data: transformedData.daily }, { name: '月度累计', type: 'pie', radius: ['55%', '70%'], label: { formatter: '{b}: {c}', borderWidth: 1, borderRadius: 4, textStyle: { color: '#ffffff', fontSize: '1.2em' } }, labelLine: { length: 30 }, data: transformedData.monthly } ] }

关键配置解析:

  • radius: 控制饼图半径范围,内环设置为['0%','40%'],外环设置为['55%','70%']
  • label.position: 内环标签设为'inner'显示在内部,外环默认显示在外部
  • formatter: 自定义标签内容,支持{b}(名称)、{c}(值)、{d}(百分比)等占位符

4. 若依前端组件封装与复用

为了在若依系统中实现图表的复用,我们可以封装一个通用的ECharts组件:

<template> <div class="chart-container"> <v-chart :options="chartOption" :autoresize="true" style="height: 100%; width: 100%" /> </div> </template> <script> import ECharts from 'vue-echarts' import 'echarts/lib/chart/pie' import 'echarts/lib/component/tooltip' import 'echarts/lib/component/legend' export default { components: { 'v-chart': ECharts }, props: { apiUrl: String, chartTitle: String }, data() { return { chartOption: { title: { text: this.chartTitle, left: 'center' }, tooltip: { trigger: 'item' }, legend: { bottom: 10, left: 'center' }, series: [] } } }, async mounted() { const response = await this.$http.get(this.apiUrl) this.updateChart(response.data) }, methods: { updateChart(rawData) { const transformedData = this.transformData(rawData) this.chartOption.series = [ { name: '当日数据', type: 'pie', radius: ['0%', '40%'], label: { position: 'inner', formatter: '{b}\n{c}' }, labelLine: { show: false }, data: transformedData.daily }, { name: '月度累计', type: 'pie', radius: ['55%', '70%'], label: { formatter: '{b}: {c}' }, data: transformedData.monthly } ] }, transformData(rawData) { // 转换逻辑同上 } } } </script> <style scoped> .chart-container { height: 400px; width: 100%; } </style>

使用封装好的组件:

<template> <div> <pie-chart api-url="/api/shipment-data" chart-title="发货计划与实际对比" /> </div> </template> <script> import PieChart from '@/components/PieChart' export default { components: { PieChart } } </script>

5. 性能优化与交互增强

在实际项目中,我们还需要考虑以下优化点:

数据缓存策略

  • 使用localStorage缓存API响应
  • 实现数据过期机制(如1小时自动刷新)
async fetchData() { const cacheKey = `chart-data-${this.apiUrl}` const cachedData = localStorage.getItem(cacheKey) if (cachedData) { const { data, timestamp } = JSON.parse(cachedData) if (Date.now() - timestamp < 3600000) { // 1小时缓存 return this.updateChart(data) } } const response = await this.$http.get(this.apiUrl) localStorage.setItem(cacheKey, JSON.stringify({ data: response.data, timestamp: Date.now() })) this.updateChart(response.data) }

交互增强功能

  • 添加数据刷新按钮
  • 实现图表下载为图片
  • 响应式调整图表大小
methods: { refreshChart() { localStorage.removeItem(`chart-data-${this.apiUrl}`) this.fetchData() }, downloadChart() { const chartInstance = this.$refs.chart.getEchartsInstance() const imgUrl = chartInstance.getDataURL({ type: 'png' }) const link = document.createElement('a') link.href = imgUrl link.download = 'chart.png' link.click() }, handleResize() { this.$refs.chart.resize() } }, mounted() { window.addEventListener('resize', this.handleResize) }, beforeDestroy() { window.removeEventListener('resize', this.handleResize) }

6. 实际项目中的经验分享

在多个若依项目实践中,我发现以下几点特别值得注意:

  1. 版本兼容性问题:不同版本的ECharts对配置项的支持有差异,特别是从4.x升级到5.x时,部分API发生了变化。建议团队统一ECharts版本。

  2. 大数据量优化:当数据点超过1000时,需要考虑以下优化手段:

    • 使用large属性开启大数据模式
    • 设置largeThreshold参数
    • 考虑数据采样或聚合
series: [{ type: 'pie', large: true, largeThreshold: 1000, // ...其他配置 }]
  1. 主题定制:若依系统通常有自己的UI风格,可以通过ECharts主题系统保持一致性:
// 注册主题 import theme from './echarts-theme.json' ECharts.registerTheme('ruoyi', theme) // 使用主题 <v-chart theme="ruoyi" :options="chartOption" />
  1. 移动端适配:针对移动设备需要调整标签大小和交互方式:
// 根据屏幕宽度动态调整 const isMobile = window.innerWidth < 768 this.chartOption.series.forEach(series => { series.label.fontSize = isMobile ? 10 : 14 })
http://www.zskr.cn/news/1409723.html

相关文章:

  • 思科Fat AP组网踩坑记:从‘能通’到‘好用’,我总结的3个关键配置细节与1个常见误区
  • OpenWRT旁路由模式部署Zerotier全攻略:不干扰主网络,实现安全内网穿透
  • 解锁隐藏潜能:NVIDIA Profile Inspector完整调校指南,让游戏性能飙升50%
  • Unity新手避坑指南:Camera组件这10个参数没搞懂,游戏画面就毁了
  • 告别工控机?用ESP32/ESP8266无线读取西门子PLC数据的低成本方案(S7协议实战)
  • 保姆级教程:手把手教你用Sysmac Studio配置得克威尔EX-1100 EtherCAT从站(附XML文件下载)
  • 行业深度盘点:浙江十家优质 GEO 优化公司实力评级与口碑参考 - 玖叁鹿
  • 别再死记公式了!用‘电脑价格猜猜看’和‘出门带伞’两件小事,5分钟掌握贝叶斯更新核心思想
  • 从单片机裸奔到跑系统:ARM Cortex-M3的特权/用户模式与双堆栈如何守护你的FreeRTOS
  • 告别脚本和触发器:用DBSync这款绿色小工具,5分钟搞定MySQL到SQL Server的实时同步
  • 电磁夹爪选购思路解析:精选2026年电磁夹爪品牌 - 品牌2025
  • 避开这些坑!用FDTD Solutions 8.0做微纳光学仿真时,网格设置与边界条件的实战经验
  • 别再死磕ImageNet预训练了!聊聊工业异常检测里那些‘水土不服’的模型与实战调优思路
  • STM32F405+EC600N-CN OTA升级实战:手把手教你解决4G模块存储不够和固件地址错位两大坑
  • 大家都在电脑上安装了openclaw了吗?
  • 高匿代理如何隐藏真实 IP:TCP/IP 协议与 HTTP 头深度解析
  • 智能电表背后的AI:深度学习如何从一条总功率曲线里‘认出’你家的空调和冰箱?
  • 2026年 宝钢冷轧HC420/780DP双相钢厂家/品牌推荐榜单:高强轻量化与卓越成形性能的行业优选 - 品牌企业推荐师(官方)
  • 2026宁波最权威GEO优化公司TOP10深度攻略:万字全景解析 + 口碑服务商完整解读 - 玖叁鹿
  • 别再追模型了,OPC真正该追的是工作流和交付链路
  • 2026年怎么免费降低论文AI率?10款最新降AI工具实测及手改技巧指南 - 降AI实验室
  • 2026年AI Agent爆发元年:12大框架横评与选型决策全解析,助你抢占智能办公先机!
  • 解决高温难题:Inconel718耐磨耐腐蚀合金专业厂商精选 - 品牌2025
  • 2026年4月艺术职高推荐推荐,艺术职高需要多少分,艺术职高,艺术环境优雅宜人 - 品牌推荐师
  • 别再乱卸载补丁了!Win10/11共享打印机报错0x00000709、0x0000011b的终极修复指南
  • 10 CLAUDE.md 进阶
  • 2026 杭州 GEO 优化 TOP10:权威排名 + 万字实操攻略 + 服务商全解析 - 玖叁鹿
  • 急需交货期?盘点几家响应迅速、现货充足的Nitronic60不锈钢优质厂商 - 品牌2025
  • 列表页别逐条查:我在 Rust CRM 里用 is_in + HashMap 干掉 N+1
  • LLM推理优化:MLA与MoE架构突破内存与计算瓶颈