我的博客(kqwq.com)跑了几年,累计 1000+ 篇文章、1500+ 条评论。一直想有个「数据大屏」把这些信息可视化出来——看看自己这些年都写了啥、读者从哪来、啥时候最勤快。折腾了一周,总算做出了一个单文件的 dashboard.php。这篇文章记录从 0 到 1 的过程,以及几个让我抓狂的坑。

一、为什么不直接用插件?
市面上有 WP Statistics、MonsterInsights 之类的统计插件,但它们要么要埋第三方脚本、要么功能模板化、要么数据不归自己。我更想要一个完全自己掌控、能展示我真正关心的维度(比如按省份、按高频词、按发文时段)的页面。
于是决定:自己写。
二、技术方案:单文件 PHP + ECharts
整个大屏就是一个 dashboard.php,核心思路:
- 直连数据库:自动读取 WordPress 根目录的
wp-config.php拿到 DB 账号,不依赖任何 WP 插件或 REST API。
- 可视化:用 ECharts 5.5.0 画图,评论 / 标签词云用 echarts-wordcloud。
- 双层缓存:服务器开了 Memcached,再套一层文件缓存兜底,数据半个月刷新一次(避免每次访问都跑几十个 SQL)。想强制刷新就访问
?refresh=1。
- 访客省份:用主题 xiaochen 自带的纯真 IP 库(
ip2c.php+25qqwry.dat)解析评论 IP,不依赖插件。
- 中国地图:下载本地
china-geo.json随文件一起部署,避免运行时再请求外部接口。
三、大屏里都有啥
- 📊 数据概览卡片(文章数、评论数、标签数……)
- 📈 每月发文趋势(从 2021 年 4 月起,更早月份数据异常、不具参考性)
- 📂 分类文章分布、🏷️ 热门标签 Top 10
- 💬 评论高频词 TOP 15(「不错」「非常好」这类出现最多的词)
- 🗺️ 访客省份分布(中国地图 + 进度条)
- 📅 每周发文分布、⏰ 发文时段热力图(热力图 / 按星期 / 按小时 三视图切换)
- 📆 年度数据对比、🖼️ 媒体类型分布
- 🔥 热评文章 Top 10、🕐 最新文章
- ☁️ 评论 / 标签漂浮词云
顶部还有吸顶导航,品牌名居中,带一个「内容导航」下拉,一键跳到任意板块。
四、开发中的几次迭代
这部分最有意思,因为几乎每个功能都改了好几版。
1. 「评论话术」其实是高频词 一开始想做「评论话术前十」,后来发现更准确的说法是评论内容高频词——比如有 10 个人评论「不错」、8 个人评论「非常好」。于是改成分词统计 TOP 15。
2. 词云:从静态到「真漂浮」 最早用 echarts-wordcloud,但它只有进场动画,不会一直动。加定时器重排也只是抖动。最后干脆用纯 HTML/CSS 重写:每个词是绝对定位的 span,用 @keyframes 做 ±40px 的循环漂移 + 整体 55 秒呼吸式微旋转。效果终于「活」了。
3. 热力图:从乱到精致 初版热力图时间轴太密、色阶打架,看着很乱。重做后:x 轴每 3 小时标一次、色阶移到右侧竖向、单元格加描边。又加了「热力图 / 按星期 / 按小时」三视图切换。
4. 顶部导航 从最初一个简单的「返回博客首页」按钮,扩展成带「内容导航」下拉菜单(16 个板块锚点跳转),品牌名做到居中显示。
五、三个让我抓狂的坑
坑 1:浏览器缓存,改了等于没改 我改完前端逻辑,刷新页面却「没生效」。折腾半天才发现:服务端缓存(Memcached)只缓存数据数组,不缓存 HTML/JS;而浏览器会把整个页面(含内联 JS)缓存住。我加的 ?refresh=1 只清了服务端数据缓存,对浏览器缓存的旧 JS 完全无效。
解决办法:在 PHP 顶部加 no-store 系列响应头,强制浏览器每次重新拉页面:
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Pragma: no-cache');
header('Expires: 0');
坑 2:ECharts tooltip 的隐藏 bug,让切换「失灵」 热力图加完三视图切换,点按钮「没反应」。控制台报 Cannot read properties of undefined (reading '1')。
根因:热力图的 tooltip 用了 ...chartTheme.tooltip 展开,结果把默认 trigger:'axis' 继承了下来(heatmap 本该用 'item')。axis 触发时悬停传入的参数没有 .value,formatter 一读取就崩,还把 ECharts 实例状态搞坏,表现就是切换按钮失灵。
修法:热力图显式设 trigger:'item'、给 formatter 加空值保护、切换时用 notMerge:true 彻底清配置、渲染包 try/catch。
坑 3:海外 CDN 太慢,首屏空白 11 秒 最初 echarts 走 cdn.jsdelivr.net,国内加载 11 秒,打开页面长时间白屏。
修法:把 echarts.min.js 和 echarts-wordcloud.min.js 下载到本地、和 PHP 放一起,走自己的服务器(国内秒开),并保留 CDN 兜底;同时把库从 <head> 挪到图表脚本之前,避免阻塞首屏。
六、部署与安全
- 上传时把
dashboard.php、china-geo.json、echarts.min.js、echarts-wordcloud.min.js放同一目录。
- 大屏直接放根目录会任何人可访问。我用了宝塔的防盗链(防 JS 被盗用)+ 流量限制(防被刷)+ IP 白名单(只有自己能开)来加固。
- 服务器建议开启
.js的 gzip,1MB 的 echarts 能压到 ~300KB,加载更快。
七、小结
从一个「想看看自己博客数据」的小念头,到做出一个能漂词云、能切视图、能看地图的单文件大屏,中间踩的坑比写的代码还多。但正是这些坑,让这个页面真正「可用」。
如果你也想给自己的 WordPress 做类似大屏,核心就三句话:直连数据库取数、ECharts 负责好看、缓存和防缓存(浏览器)决定体验。
八、大屏文件
感兴趣的可以找我下载直接使用~



