Dataview 是 Ob 里很著名的一个插件,它提供了十分便利的数据查询功能
利用 Dataview 插件,可以且轻易地通过文件夹、标签等条件创建表格或是列表
但是相对于 Dataview 查询,Dataviewjs 更少人知道
Dataviewjs
Dataviewjs 是 Dataview 插件的高级功能,与 templater 一样,它也使用 javascript 语言
想要使用它也很简单,与 dataview 类似,只要在代码块前面加上 dataviewjs
```dataviewjs
js语句
```
下面介绍我发掘的一些用法
简单点的自定义查询样式
1
功能:显示文件、标签的数量
```dataviewjs
var i = [dv.pages().length,dv.pages(`"200-笔记"`).length,dv.pages(`"700-收集文章"`).length,
dv.pages().file.etags.distinct().length]
dv.paragraph(`总共有 **${i[0]}** 个文件`)
dv.paragraph(`其中==笔记== **${i[1]}** 篇,==收集文章== **${i[2]}** 篇`)
dv.paragraph(`==标签== **${i[3]}**个`)
```
2
功能:显示文件的时间
```dataviewjs
dv.list(
dv.pages(``)
.filter(p=>moment(Number(p.file.cday)).get("year")==2021)
.sort(p=>p.file.cday,'desc')
.map(p=>moment(Number(p.file.cday)).format('yyyy-MM-DD')+' >> '+p.file.link)
)
```
这个就比较中规中矩了,只不过是显示了文件的创建日期而已
你可能会觉得“这有什么用,我用dataview创建列表不一样能显示创建日期吗,你这个就是浪费时间”
确实如此,用 dataview 可以更简单地做到这件事,但是按照自己的意愿来显示的更好看诶,总有人会喜欢折腾的(比如我)
3
功能:这是用来管理的我的收集箱的代码
```dataviewjs
for(let i of dv.pagePaths(`"100-Index"`).groupBy(p=>p.split("/")[1])){
dv.paragraph(`### ${i.key}`);
let a = dv.pages(`"100-Index/${i.key}"`).length
dv.paragraph(`共有==${a}==篇`);
dv.list(
dv.pages(`"100-Index"`)
.filter(p=>p.file.folder.split("/")[1]==i.key)
.map(p=>p.file.link+' - '+moment(moment().diff(moment(Number(p.file.cday)),'days'))+'天' )
);
}
```
这段代码将不同文件夹的文件分别展示,并且显示了文件的数量及存在时间,提醒我尽快处理它们
与其他插件联合
这里举个例子,有个插件叫 Obsidian Charts,它可以生成可交互的图表,包括饼状图、折线图、条形图等等
```chart
type: line
labels: [Monday,Tuesday,Wednesday,Thursday,Friday]
series:
- title: Title 1
data: [1,2,3,4,5]
- title: Title 2
data: [5,4,3,2,1]
- title: Title 3
data: [8,2,5,-1,4]
```
```chart
type: pie
labels: [Monday,Tuesday,Wednesday,Thursday,Friday]
series:
- title: Title 1
data: [1,2,3,4,5]
- title: Title 2
data: [5,4,3,2,1]
width: 40%
labelColors: true
```
虽然这个插件有给 dataview 的api,但我着实没搞明白
不过这并不碍事,我自有一套骚操作
```dataviewjs
let la = Array()
let da = Array()
for(let i of dv.pages().groupBy(p=>p.file.folder.split("/")[0]))
{
la.push(i.key);
let n = dv.pages(`"${i.key}"`).length;
da.push(n);
}
dv.paragraph(`\`\`\`chart
type: pie
labels: [${la}]
series:
- title: none
data: [${da}]
width: 50%
legendPosition: left
labelColors: true
\`\`\``);
```
这是个展示各个文件夹里文件数量饼图的代码
原理也很简单,就是写了个模板然后往里套数据,像上面的例子中,实际渲染的文本是
```chart
type: pie
labels: [000-HomePage,010-Mine,100-Index,200-笔记,210-课程,400-汇总,500-附件,600-日常,700-收集文章]
series:
- title: none
data: [47,34,8,170,81,40,1,58,145]
width: 50%
legendPosition: left
labelColors: true
```
我觉得这是个很神奇的现象,dataviewjs 先渲染出上述文本,然后 obsidian-charts 再把这一段文本渲染成了饼图
依此原理,我们甚至能自动生成每月笔记数量的折线图
```dataviewjs
var y = "2022"
var m = Array(12).fill(0).map(function(v,i){return i});
var d = [31,29,31,30,31,30,31,31,30,31,30,31]
for(let i of m)
{
var n = Array(d[i]).fill(0).map(function(v,i){return i+1});
var data = Array(d[i]).fill(0);
for(let j of dv.pages(`"200-笔记"`).filter(p=>String(p.file.cday).split("-")[0]==y && String(p.file.cday).split("-")[1]==i+1).groupBy(p=>String(p.file.cday).split("-")[2].slice(0,2)))
data[j.key-1] = dv.pages(`"200-笔记"`).filter(p=>String(p.file.cday).split("-")[2].slice(0,2)==j.key).length;
if(data.every(p=>p==0))
continue
dv.header(4, i+1+"月");
dv.paragraph(`\`\`\`chart
type: line
labels: [${n}]
series:
- title: 200-笔记
data: [${data}]
labelColors: true
\`\`\``)
}
```
这总算是个非常实用的功能了
通过这种用法,也许能写出根据标题自动生成 mermaid 的代码
直接使用 Ob 的插件 API
这是偶然听群友提到的,经过探索后发现像dataview、templater、quickadd等可以用 js 的插件能够调用 Ob 给插件用的 API
简单来说就是,本来给插件用的函数,可以通过以上插件给我们调用
比如以下调用了可以读取文件内容的 app.vault.readRaw
函数
```dataviewjs
const term = "日常记录"
const files = dv.pages(`"600-日常"`).filter(p=>String(p.tags).includes("日记")).sort(p=>p.file.name)
const b = files.map(async function(p){
var x = await app.vault.readRaw(p.file.path);
x = x.split("\n### ").filter(p=>p.slice(0,term.length)==term)[0];
dv.paragraph("## "+p.file.name+"\n\`\`\`ad-note\ntitle: DailyNote\n"+x.slice(term.length)+"\n\`\`\`");
}
)
```
这样就集合了所有日记固定标题下的内容(顺便还展示了 Dataview 联合 Admonition 呢)
结束语
总之,dataviewjs 带来了更高级的数据分析或是自动渲染,这是个很有趣的功能
另外,这是我写过的第一篇文章,本人的 javascript 也是边用边学的,文章的语言或是一些代码可能写得很烂,也许折腾的成分大于实用性,因此希望能够以这篇拙劣的文章来抛砖引玉,吸引一些大佬分享自己的用法