QueryView 插件 真是一个功能强大的插件。
安装插件后,在 daily note/2024
文档内通过 /qv
空格 使用模板,点击 更新 sql 按钮,填入以下内容
热力图
所有 daily note 都在一个图
//!js
const query = async () => {
let dv = Query.DataView(protyle, item, top);
const blocks = await Query.dailynote(null, -1);
const yearSet = new Set();
const data = blocks.map(block => {
const m = block.ial.match(/dailynote-(\d{4})(\d{2})(\d{2})/);
const [_, year, month, day] = m;
yearSet.add(Number.parseInt(year, 10));
return {
id: block.id,
date: `${year}-${month}-${day}`,
year,
title: block.content,
}
})
const heatmapData = data.map((item, index) => {
return [item.date, Math.floor(Math.random() * 10000)];
});
const years = Array.from(yearSet).sort((a, b) => b - a);
const calendar = years.map((year, index) => {
return {
range: [`${year}-01-01`, `${year}-12-31`],
cellSize: ['auto', 13],
top: 50 + index * 150,
left: 30,
yearLabel: { show: true, position: 'top' },
}
});
const series = Array(calendar.length).fill(0).map((_, index) => {
return {
type: 'heatmap',
coordinateSystem: 'calendar',
calendarIndex: index,
data: heatmapData
}
});
const option = {
tooltip: {
formatter: (params) => {
const title = data[params.dataIndex].title;
return `${title}`;
}
},
visualMap: {
min: 0,
max: 10000,
show: false
},
calendar,
series,
};
dv.addecharts(option, {
height: `${calendar.length * 140 + 30}px`,
events: {
click: (params) => {
const item = data[params.dataIndex];
Query.Utils.openBlock(item.id);
}
}
});
dv.render();
}
return query();
热力图(一年分一半)
当前子文档的 daily note,一年分一半
//!js
const query = async () => {
let dv = Query.DataView(protyle, item, top);
const data = []
let thisYear;
let childs = await Query.childdoc(dv.root_id);
for (let child of childs) {
//获取子文档的子文档
const subchilds = await Query.childdoc(child.root_id);
for (let subchild of subchilds) {
const m = subchild.ial.match(/dailynote-(\d{4})(\d{2})(\d{2})/);
const [_, year, month, day] = m;
if (!thisYear) {
thisYear = year
}
data.push({
id: subchild.id,
date: `${year}-${month}-${day}`,
title: subchild.content,
url: `siyuan://blocks/${subchild.id}`
})
}
}
const heatmapData = data.map((item, index) => {
return [item.date, Math.floor(Math.random() * 10000)];
});
const option = {
tooltip: {
formatter: (params) => {
const title = data[params.dataIndex].title;
return `${title}`;
}
},
visualMap: {
min: 0,
max: 10000,
show: false
},
calendar: [
{
range: [`${thisYear}-01-01`, `${thisYear}-06-30`],
cellSize: [20, 20],
top: 50,
},
{
range: [`${thisYear}-07-01`, `${thisYear}-12-31`],
cellSize: [20, 20],
top: 250,
},
],
series: [
{
type: 'heatmap',
coordinateSystem: 'calendar',
data: heatmapData
},
{
type: 'heatmap',
coordinateSystem: 'calendar',
calendarIndex: 1,
data: heatmapData
},
]
};
dv.addecharts(option, {
height: '420px',
events: {
click: (params) => {
const item = data[params.dataIndex];
Query.Utils.openBlock(item.id);
}
}
});
dv.render();
}
return query();
索引
当前子文档的 daily note
//!js
function getWeekNumber(date) {
const startOfYear = new Date(date.getFullYear(), 0, 1);
const pastDaysOfYear = (date - startOfYear) / 86400000; // 计算从年初到当前日期的天数
return Math.ceil((pastDaysOfYear + startOfYear.getDay() + 1) / 7);
}
const query = async () => {
let dv = Query.DataView(protyle, item, top);
const blocks = []
let childs = await Query.childdoc(dv.root_id);
for (let child of childs) {
//获取子文档的子文档
const subchilds = await Query.childdoc(child.root_id);
blocks.push(...subchilds)
}
// 按月、周分组
const groupedByMonthAndWeek = blocks.reduce((acc, block) => {
// 将 created 字符串转换为日期对象
const m = block.ial.match(/dailynote-(\d{4})(\d{2})(\d{2})/);
const year = m[1];
const month = m[2];
const day = m[3];
const date = new Date(year, month - 1, day); // 月份从 0 开始
// 获取该日期所在的周数
const weekNumber = getWeekNumber(date);
// 按月分组的键
const monthKey = `${year}-${month.padStart(2, '0')}`;
// 按周分组的键
const weekKey = `W${weekNumber.toString().padStart(2, '0')}`;
// 如果该月份还没有在累加器中,创建一个空对象
if (!acc[monthKey]) {
acc[monthKey] = {};
}
// 如果该周还没有在月份分组中,创建一个空数组
if (!acc[monthKey][weekKey]) {
acc[monthKey][weekKey] = [];
}
const newBlock = {
id: block.id,
content: block.content,
date,
month,
day,
weekNumber: date.getDay(),
weekCN: ['日', '一', '二', '三', '四', '五', '六'][date.getDay()],
}
// 将当前 block 添加到对应的周数组中
acc[monthKey][weekKey].push(newBlock);
return acc;
}, {});
// 输出 Markdown
let md = '';
for (let month in groupedByMonthAndWeek) {
md += `## ${month}\n\n`;
for (let week in groupedByMonthAndWeek[month]) {
md += `- `;
const blocks = groupedByMonthAndWeek[month][week];
// 按日期排序
blocks.sort((a, b) => a.date - b.date);
for (let block of blocks) {
const title = `${block.month}-${block.day} (${block.weekCN})`
const url = `siyuan://blocks/${block.id}`
md += ` [${title}](${url})`;
}
md += '\n';
}
md += '\n';
}
dv.addmd(md);
dv.render();
}
return query();
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于