WeBlog 数据可视化实战:ECharts 文章发布热图与 PV 走势图实现原理
WeBlog 数据可视化实战:ECharts 文章发布热图与 PV 走势图实现原理
想要让个人博客的后台更有"科技感",数据可视化是绕不开的一环。WeBlog 作为一款基于 Spring Boot + Vue 3.2 + Vite 4.3 的前后端分离个人博客系统,在后台仪表盘中内置了 ECharts 图表:一张展示每日文章发布情况的文章发布热图(日历热力图),一张追踪近 7 天访问量的 PV 走势图(折线图)。本文从零拆解这两张图表的完整实现原理,带你搞懂"前端图表组件 + 后端统计接口 + 数据库聚合查询"的整套数据可视化链路,无论你是想做毕业设计,还是想给自己的博客加个统计面板,都能直接借鉴这套思路。
数据可视化整体架构:一张图看清数据从哪来、画到哪去
在动手写代码之前,先建立全局视角。WeBlog 后台仪表盘的数据可视化分为三层:
- 展示层(Vue 3 前端):负责用 ECharts 渲染图表,核心是
weblog-vue3/src/components/目录下的ArticlePublishChart.vue(文章发布热图)与PVChart.vue(PV 走势图),它们被后台首页weblog-vue3/src/pages/admin/index.vue引入。 - 接口层(Spring Boot 后端):
AdminDashboardController暴露三个统计接口,统一走POST请求,其中/admin/dashboard/publishArticle/statistics服务热图、/admin/dashboard/pv/statistics服务走势图。 - 数据层(MySQL):文章发布数据直接聚合自
t_article表;PV 数据则来自独立的t_statistics_article_pv统计表。
前端通过 weblog-vue3/src/api/admin/dashboard.js 中的 axios 请求封装调用后端接口,拿到 JSON 数据后交给 ECharts 的 setOption() 完成渲染,链路非常清晰。
文章发布热图实现原理:ECharts 日历热力图是怎么画出来的
文章发布热图的视觉形态类似 GitHub 的提交贡献图:以"日"为格子、以"颜色深浅"代表当天发布文章的数量。这套效果在 ECharts 中被称为日历热力图(Calendar Heatmap),核心思路是把 calendar(日历坐标系)和 heatmap(热力图系列)组合使用。
前端图表配置:calendar + heatmap 双剑合璧
在 ArticlePublishChart.vue 中,页面加载后会先请求后端统计接口,拿到一个"日期 → 发文数"的 Map 数据,再逐条转换成 ECharts 需要的 [日期, 数值] 二维数组:
visualMap定义颜色映射区间(如min: 0, max: 10),决定数值对应哪种颜色;calendar组件设置range,即热力图覆盖的日期范围;series的type设为heatmap、coordinateSystem指向calendar,把数据"贴"到日历上;- 通过
gradientColor定义从浅到深的渐变梯度(#fff→#40c463→#30a14e→#216e39),发文越多颜色越深,一眼就能看出高产日。
一个容易被忽视的细节是日期范围的取舍:如果展示整年 12 个月的热图,屏幕宽度往往放不下后面的月份。因此 WeBlog 采用了"当前日期为基准,往前 4 个月、往后 2 个月"共 6 个月的窗口方案,既能看到历史节奏,又能预览未来,视觉上更从容。
后端统计接口:一条 SQL 按天分组出文章数
热图的数据来自 AdminDashboardServiceImpl 的 queryDashboardPublishArticleStatisticsInfo() 方法。它的实现非常经典,分三步:
- 计算"年初第一天"到"今天"的日期区间;
- 调用
ArticleMapper.selectArticleCount()执行聚合 SQL,按DATE(create_time)对t_article表分组统计每天的发布数量; - 用
LinkedHashMap补齐日期:从年初遍历到今天,把没有发布文章的日期补成 0,确保前端拿到的是一份"完整无空洞"的日期序列。
这种"数据库聚合 + 服务端补零"的模式,是日历热力图数据准备的通用解法,值得记进小本本。
PV 走势图实现原理:近 7 天访问量的折线图如何生成
如果说热图回答的是"我哪天爱写文章",那 PV 走势图回答的就是"我的博客哪天最受欢迎"。它用折线图展示最近 7 天的页面访问量变化,实现上同样分为前端渲染与后端统计两条线。
前端图表配置:一个简洁的 line 折线图
PVChart.vue 的实现比热图更简单:接口返回 pvDates(近 7 天的 MM-dd 日期数组)和 pvCounts(对应的 PV 数值数组),前端分别塞给 xAxis 与 series,type 设为 line 即可得到一条平滑的趋势折线。后端在 queryDashboardPVStatisticsInfo() 中会自动生成最近 7 天的日期序列,并保证与查询结果一一对齐,缺失的日期补 0,这样折线就不会出现断点。
PV 数据从哪来:一张统计表 + 一次异步自增
PV 数据的源头很讲究。WeBlog 单独建了一张 t_statistics_article_pv 统计表(见 sql/schema.sql),字段只有 pv_date(被统计日期)和 pv_count(当日浏览量),并给 pv_date 建了唯一索引,保证"一天只有一条记录"。
每次用户访问文章时,后端并不会同步去更新数据库,而是交给 PVIncreaseAsyncTask 这个异步任务(方法上标注了 @Async):先给文章阅读数 +1,再调用 pvIncrease() 处理当日 PV——如果当天记录已存在就执行 pv_count = pv_count + 1 的 SQL 自增,不存在则插入一条 pv_count = 1 的新记录。
用异步任务统计 PV 的好处很明显:把高并发的写操作从请求主链路中剥离,不拖慢文章阅读接口的响应速度,这也是大型系统做埋点统计的常见套路。对应的 DAO 实现位于 AdminStatisticsArticlePVDaoImpl,查询最近 7 天记录则通过按 pv_date 倒序取 limit 7 完成。
三步看懂完整数据链路:从访问到图表
把前后端串起来,一次"PV 走势图刷新"背后其实是这样的流程:
- 埋点:访客打开文章 → 后端触发
PVIncreaseAsyncTask异步任务 →t_statistics_article_pv表中当日 PV +1; - 查询:后台首页加载 →
dashboard.js发起POST /admin/dashboard/pv/statistics→ 服务端聚合最近 7 天数据并补零,返回日期与数值两个数组; - 渲染:
PVChart.vue拿到数组 →echarts.init()初始化图表 →setOption()画出折线。
文章发布热图完全复用这套流程,只是数据源换成 t_article 表的按天分组统计。整套代码在 weblog-springboot/weblog-module-admin 与 weblog-vue3/src 中均有完整实现,按上面提到的文件路径即可逐行对照阅读。
写在最后:这套实现能给你什么启发
WeBlog 的数据可视化实现虽然没有炫技,却处处是"教科书级"的工程取舍:日历热力图用 6 个月窗口解决屏幕适配、后端用补零保证图表数据连续、PV 用异步 + 唯一索引保证统计准确且不阻塞主流程。对于想用 ECharts 做数据可视化的新手来说,这套"前端图表组件 + 后端聚合接口 + 分组统计 SQL"的组合拳,完全可以照搬到自己的博客、管理系统乃至毕业设计中。如果你也想给自己的项目加上一张漂亮的统计图表,不妨从复刻这张文章发布热图和 PV 走势图开始。
更多推荐

所有评论(0)