视频演示:https://www.bilibili.com/video/BV1oq4y157qs?p=18
感谢@邦邦
/**
* @title heatmap
* @author 邦邦
* @note 可以直观呈现每日创建bullet数,点击对应方块可以查看当天创建的所有bullet
*/
pluginManager.register("heatmap", {
heatmapData: {},
chartData: [],
async init() {
const l = await plugin.db.node.toArray();
const excepts = [NNodeView.mkid('untitled'),NNodeView.mkid('stars'),NNodeView.mkid("listall")];
this.heatmapData = {};
for (let i = 0; i < l.length; i++) {
if(l[i].status==-1||l[i].status==-2||l[i].status==99||isEmpty(l[i].ori)||!isKy(l[i].ky)||excepts.includes(l[i].ky))continue;
const tt = timekit.format("yyyy-MM-dd", l[i].created);
if (this.heatmapData[tt]) {
this.heatmapData[tt].push(l[i]);
} else {
this.heatmapData[tt] = [l[i]];
}
}
this.chartData = [];
for (const item in this.heatmapData) {
this.chartData.push({
date: new Date(item),
count: this.heatmapData[item].length
})
}
},
async showHeatMap() {
if (plugin.heatmap.dialog && plugin.heatmap.dialog.$view != null) return;
jSmallMsg("正在加载数据", 1e3);
await this.init();
this.dialog = JDialog.create({
title: "热力图",
content: `<div id="chart1"></div>`,
width: "800px",
minimize: true,
buttons: {
"关闭": () => {
return true;
}
}
})
var chart1 = calendarHeatmap()
.data(this.chartData)
.selector('#chart1')
.colorRange(['#ebedf0', '#216e39'])
.tooltipEnabled(true)
.onClick(function (data) {
if (data.count == 0) {
jSmallMsg("没有找到当天数据", 1e3);
return;
} else {
plugin.heatmap.showDay(data.date.format("yyyy-MM-dd"));
}
});
chart1();
},
showDay(day) {
var template = `<div id="day${day}" class="plugin-heatmap-preview">`;
const data = this.heatmapData[day];
if (!data) {
jSmallMsg("没有找到当天数据", 1e3);
return;
}
const tmpnode = NNodeView.temp();
for (let i = 0; i < data.length; i++) {
template += `<section nel="dom" class="nmarkdown mynode p" layout="default" mdblock="p">
<div class="icon-circle mynode-btn" onclick="plugin.router.to('${data[i].ky}')" nel="btn"></div>
<div nel="head" class="mynode-head">
<div nel="text" class="mynode-text">${data[i].codeBlockText?"【代码块,请单击左侧圆点查看】":(data[i].text||tmpnode.parseOriText(data[i].ori))}</div>
</section>`;
}
template += `</div>`;
const dialog = JDialog.create({
title: `${day}创建的节点(${data.length})`,
content: template,
minHeight: 200,
minimize: true,
maxHeight: $(window).height() - 100,
height: $(window).height() * 0.618,
width: 500,
buttons: {
"关闭": () => {
return true;
}
}
});
dialog.$view.resizable();
},
after_systabs_run() {
plugin.systabs.add('heatmap', `<i title="打开热力图" class="icon-fire"></i> `,
function () {
plugin.heatmap.showHeatMap();
});
},
run() {
loadScript("https://cdn.bootcdn.net/ajax/libs/d3/3.5.9/d3.min.js");
loadScript("https://cdn.bootcdn.net/ajax/libs/moment.js/2.29.1/moment.min.js");
loadScript("https://cdn.jsdelivr.net/gh/sheenblue/calendar-heatmap/src/calendar-heatmap.js");
loadCss("https://cdn.jsdelivr.net/gh/sheenblue/calendar-heatmap@0.4.5/src/calendar-heatmap.css");
$(`<style>.plugin-heatmap-preview{font-weight:300;position:relative;width:100%;height:100%}.plugin-heatmap-preview .mynode{position:relative;padding-top:2px;padding-bottom:2px}.plugin-heatmap-preview .mynode>.mynode-btn{width:24px;height:24px}.plugin-heatmap-preview .mynode-btn{z-index:3;height:24px;line-height:24px;font-size:9px;width:24px;text-align:center;cursor:pointer;position:absolute;margin-top:1px;display:flex;justify-content:center;align-items:center;left:2px;border-radius:100px}.plugin-heatmap-preview .mynode-head{position:relative;display:flex;justify-content:space-between;align-items:baseline}.plugin-heatmap-preview .mynode .mynode-text{padding-left:31px;margin-left:0}.plugin-heatmap-preview .mynode .mynode-text{padding-left:31px;padding-right:60px;min-height:24px;font-weight:normal;border-bottom:1px solid transparent;margin-right:5px;cursor:default;font-size:15px;line-height:180%;word-break:break-all}.plugin-heatmap-preview .mynode-head .mynode-text{flex-grow:1;flex-shrink:1}.plugin-heatmap-preview .mynode>.mynode-btn:hover::before{box-shadow:0 0 0 5px rgb(3 169 244 / 20%);background-color:var(--node-btn-hover);transform:scale(1.5);transition:all .1s}.plugin-heatmap-preview .mynode>.mynode-btn::before{content:'';background-color:var(--node-btn-default);width:6px;height:6px;border-radius:10px}</style>`).appendTo(document.body)
}
})