Astro 博客标签系统与数据可视化记录
标签数据收集与统计
标签系统首先要做数据聚合。用 Astro Content Collections API 拿到所有已发布文章后,用 Map 结构统计每个标签的出现次数,再转成数组按文章数量降序排列。这个流程很直接,Map 的 O(1) 查找让统计过程几乎没有额外开销。
彩色卡片与交互设计
标签卡片按索引对 6 取模,循环分配电路板绿、电磁炮蓝、紫色、橙色、玫红、翠绿六种配色。悬停时有四个同步动画:卡片上移 4px、图标旋转 12° 并缩放 1.1 倍、箭头从左侧滑入、颜色渐变过渡,动画时长统一 300ms。移动距离控制在 12px 以内,避免 hover 时显得不稳定。
Chart.js 柱状图与主题响应
柱状图取前 10 个标签展示。主题切换的响应用 MutationObserver 监听 <html> 元素的 class 属性,检测到 .dark 类变化时自动更新配色。深色模式用半透明绿色(rgba(74, 222, 128, 0.1)),浅色模式换成更鲜艳的版本(rgba(74, 222, 128, 0.3))。这比轮询 localStorage 更可靠,也不需要额外的事件总线。
WordCloud2 词云
词云的数据处理分几步:先用正则清理 Markdown 语法(数学公式、代码块、链接、标题标记),再提取 2-4 字的中文词组和 2 个字母以上的英文单词,过滤 143 个常见停用词,最后按权重统计。权重分配是标签 ×3、正文和标题各 ×2、描述 ×1,这样标签词在词云里会更突出。
渲染前做了两层过滤:词频低于 3 次的直接丢弃,剩下的只取前 120 个。这两步分别减少了约 40% 和 60% 的渲染量,体感上词云出现的速度明显更快。高 DPI 屏幕用 devicePixelRatio 缩放 canvas,避免模糊。WordCloud2.js 本身用轮询延迟加载,等库就绪后再初始化,不阻塞页面其他内容。
智能目录组件
目录的展开逻辑基于窗口宽度:1400px 以上自动展开,以下自动收起。用户手动点击后,状态会保持到下次窗口宽度跨越阈值。滚动高亮用 requestAnimationFrame 节流,避免频繁 DOM 操作拖慢滚动性能。
Mermaid 全屏查看器
每个 Mermaid 图表左上角会注入一个放大按钮,默认透明,悬停时淡入。点击后打开全屏模态框,最大宽度 90vw,内容超出时可滚动。按 ESC 或点击遮罩关闭。对于流程图这类信息密度高的图表,全屏查看比在文章里硬塞一个小图要友好得多。
字体系统
全站字体栈按优先级依次是 Inter(Google Fonts)、-apple-system、PingFang SC、Microsoft YaHei,最后回退到 sans-serif。代码块单独用 JetBrains Mono。统一在全局样式里定义,避免各组件各自覆盖导致字体不一致。
几点收获
这次标签系统的开发让我对”克制”有了更具体的感受。动画幅度、词云词数、图表数据量,每一处都在做减法,最终呈现反而更干净。MutationObserver 处理主题切换更适合这里,因为它直接观察 DOM 状态而不依赖事件触发顺序。词云的权重分层(标签 > 正文 = 标题 > 描述)是个小细节,但它让词云更接近博客的内容重心,而不是把所有文字一视同仁地堆在一起。