Personal Assistant 支持 Vault 统计状态预览
之前通过 Better Word Count + Dataview + Chart
插件进行 Obsidian Vault 统计状态展示,使用这个方法的过程中会频繁碰到一些拖后腿的问题:
- 由于插件的统计数据是一个一行的 json 文件所以会导致多端数据同步的时候频繁的出现 git merge conflict 需要手动解决;
- vault 统计数据不准确问题,由于 better-word-count 插件实现的逻辑(触发数据记录时机是 tab view 的切换),这导致刚启动 obsidian app 的时候会出现统计数据短暂归零的情况,而且这本身不是该插件实现的 bug 所以无法提交 PR 进行修复;
- 缺乏定制性,数据渲染的可配置能力有限(易用性),数据定制性缺乏(例如展示周视图,年视图等);
效果展示
话不多说,先展示一下 Personal Assistant 插件查看我的个人 vault 统计状态的效果:
- 每天记录字数展示,顺便鞭策一下自己养成每天记录和思考的习惯;
- Vault 总文件数(markdown 文件);
- 按照300 words/page 统计总共的 page 数;
- ......
P.S. 我代码仓库中提供了 stat.json 文件用来测试效果,可以下载下来放到 Obsidian Vault 的配置目录中,注意文件名一定要是 stat.json
,例如.obsidian/stat.json
,搜索并执行命令Personal Assistant: Show statistics
然后就可以看到测试效果啦!
方案设计
利用 Personal Assistant 插件展示 Vault 统计数据的架构设计大致分为三大部分:
- 管理模块,负责相关事件、视图、Codemirror 等初始化、注册等管理;
- 数据模块,负责 Vault 统计数据搜集记录;
- UI 模块,负责利用 Svelte Component 渲染并展示 UI 界面;
方案模块的实现思路:
- 注册 Obsidian 记录统计的触发事件;
- 注册 Obsidian statistics item view;
- Obsidian Editor Extension 记录每日的记录数据;
- svelte chartjs 组件配置并生成 fragment 加入待更新队列;
- 根据记录数据将 svelte canvas 挂载到 Obsidian workspace 的 tab leaf 中绘制 UI;
匠心独运
功能方案的实现上没有太高的技术难度,不过我比较想聊聊开发实现过程中碰到的有意思的问题:
1. svelte chartjs
数据图形的渲染我选用了 chartjs,Personal Assistant 插件的选用了 Svelte 前端框架,所以要实现上面的方案需要支持 chartjs 的 Svelte 实现,根据 chartjs 的文档选择了 svelte-chartjs。技术选型的思路比较简单直接,用的是官方推荐。
在使用 svelte-chartjs 中碰到一个比较奇怪的问题,如下图所示的 Lint 报错:
报错的主要意思是 Line
component 只接受 number 或者 Point 类型的数据进行渲染,但是其实我的数据是 {string, number}
,Chartjs 原生是可以渲染该类型数据的。所以,应该是 svelte-chartjs 库实现的问题。
在解决这个 Lint Error 的时候耗费了非常多的时间,最终还是放弃了。或许后面会有更好的办法,欢迎熟悉了解的朋友指教。
2. 复用 better word count 模块
better word count 插件提供了非常好的 Vault 状态统计数据生成的实现,非常感谢 @lukeleppan ,站在巨人的肩膀上可以看得更高更远😜,所以我需要做的就是集成该插件的能力。具体可以查看 stat 模块。
当前的做法代码仅仅是简单的代码复用,后续可以根据性能和实际功能做优化甚至重构。但是当前的做法胜在可以快速实现需要的功能。
3. merge conflict 的缓解办法
better word count 插件为了节省资源在对 vault 统计数据落盘的时候仅仅做了 JSON 文件的序列化,这导致了 vault 数据是一个一行的字符串,在多个设备同步数据的时候几乎每次都需要处理统计数据文件的冲突问题,对此我对复用的代码进行如下的修改:
这样就可以保证数据是结构化的,在做 merge 的时候冲突尽可能减少,如果出现冲突解决起来也更加方便。
Public discussion