根据标签统计IT工单,任务列表

// 定义上半年的日期范围
const startDate = dv.date("2025-01-01");
const endDate = dv.date("2025-12-31");
 
// 获取所有符合日期范围的文件
const tasks = dv.pages('"年份归档-Archiving/2025/IT工单"')
    .filter(p => p.file.day >= startDate && p.file.day <= endDate);
 
// 定义要过滤的组织/模块标签 
const filterTag = "#主体";
 
// 创建一个对象来存储分类统计和文件链接
const categoryTasks = {};
 
// 遍历每个任务文件,统计标签并收集文件链接
tasks.forEach(task => {
    task.file.tags.forEach(tag => {
        // 检查是否为层级标签,并提取完整标签
        if (tag.includes("/")&&tag.includes(filterTag)) {
            if (!categoryTasks[tag]) {
                categoryTasks[tag] = { count: 0, files: [] };
            }
            categoryTasks[tag].count++;
        }
    });
});
 
// 转换统计结果为数组以便展示
const tableData = Object.entries(categoryTasks).map(([key, value]) => {
    return [key, value.count];
});
 
// 使用 DataviewJS 表格展示结果
dv.table(["组织/模块", "任务数量"], tableData);
 

根据元属性统计文件

筛选包含指定元属性的文件,将各文件元属性的值以折线图的形式展示

//声明需要记录的元数据名称  
let filedName = "红绿灯时长"  
// 获取当前 DataviewJS 容器  
let container = this.container;  
// 创建一个文本输入框  
let input = document.createElement('input');  
input.type = 'text';  
input.placeholder = '请输入元数据名称';  
// 设置样式以增加间距  
input.style.marginRight = '10px'; // 增加输入框和按钮之间的间距  
  
// 创建一个按钮  
let button = document.createElement('button');  
button.innerText = '确定';  
  
// 创建一个包裹输入框和按钮的 div
let wrapper = document.createElement('div');  
wrapper.style.display = 'flex';  
wrapper.style.justifyContent = 'center'; // 水平居中  
wrapper.style.alignItems = 'center'; // 垂直居中  
//wrapper.style.marginTop = '20px'; // 顶部间距  
  
// 将输入框和按钮添加到容器中  
wrapper.appendChild(input);  
wrapper.appendChild(button);  
  
// 将 wrapper 添加到容器中  
container.appendChild(wrapper);  
  
// 按钮点击事件  
button.addEventListener('click', () => {  
    // 这里可以处理输入的值,例如显示在控制台或其他操作  
    // console.log(`输入的值是: ${inputValue}`);  
    // alert(`输入的值是: ${inputValue}`);  
    filedName = input.value;  
    // 创建图表  
    createChart();  
});  
// 将创建图表代码封装为函数  
function createChart() {  
    // 清空容器内容  
    // container.innerHTML = '';  
    //清空图表部分内容,但保留输入框和按钮  
    while (container.children.length > 1) {  
        container.removeChild(container.lastChild);  
    }  
    //开辟新的一行创建容器  
//    container.appendChild(document.createElement('br'));  
    // 创建一个新的 div 作为容器  
    let newContainer = document.createElement('div');  
    // 设置容器的样式,例如大小和边框  
    newContainer.style.display = 'flex';  
    newContainer.style.justifyContent = 'center'; // 水平居中  
    newContainer.style.alignItems = 'center'; // 垂直居中
    // 选择要将容器添加到的父元素,例如 body 或其他现有元素  
    container.appendChild(newContainer);  
    // 在这里编写创建图表的代码  
    let pages = dv.pages().where(p => {  
        // 正则表达式匹配YYYY-MM-DD格式,并且确保存在“红绿灯时长”字段  
        //return /^\d{4}-\d{2}-\d{2}$/.test(p.file.name) && p[filedName]!=null ;  
        return p[filedName]!=null ;  
    });  
    let fileNames = []  
    let durations = []  
    pages.forEach(page => {  
        fileNames.push(page.file.name);  
        durations.push(page[filedName]);  
    });  
    let combinedArray = fileNames.map((name, index) => ({  
        name: name,  
        duration: durations[index]  
    }));  
    combinedArray.sort((a, b) => a.name.localeCompare(b.name));  
    fileNames = combinedArray.map(item => item.name);  
    durations = combinedArray.map(item => item.duration);  
    const option = {  
        xAxis: {  
            type: 'category',  
            data: fileNames  
        },  
        yAxis: {  
            type: 'value'  
        },  
        tooltip: {  
            trigger: 'axis'  
        },  
        series: [  
            {  
                data: durations,  
                type: 'line'  
            }  
        ]  
    };  
    app.plugins.plugins['obsidian-echarts'].render(option, newContainer)  
}

Journal日历面板

mode:month