--- cssclasses: - wide-dashboard - no-properties - note-bg-blur - styled-checkbox - styled-hr - small-text ---
--- # Dailys ## Week ```dataviewjs // Force English locale for weekdays moment.locale("en"); const today = moment(); // === CONFIGURE WEEK RANGE HERE === // For current week: const weekStart = today.clone().startOf("isoWeek"); const weekEnd = today.clone().endOf("isoWeek"); // For next week, uncomment these: // const weekStart = today.clone().add(1, "week").startOf("isoWeek"); // const weekEnd = today.clone().add(1, "week").endOf("isoWeek"); // For weekend only (Sat & Sun): // const weekStart = today.clone().startOf("isoWeek").add(5, "days"); // Saturday // const weekEnd = today.clone().startOf("isoWeek").add(6, "days"); // Sunday // All notes tagged #Calendar within the week const pages = dv.pages("#Calendar") .where(p => { const d = moment(p.file.name, "DD.MM.YYYY", true); return d.isValid() && d.isBetween(weekStart, weekEnd, "day", "[]"); }); // Generate days array (Mon–Sun or custom) const totalDays = weekEnd.diff(weekStart, "days") + 1; const weekDays = Array.from({ length: totalDays }, (_, i) => weekStart.clone().add(i, "days")); // Separate days with and without notes const daysWithNotes = []; const daysWithoutNotes = []; for (const day of weekDays) { const page = pages.find(p => p.file.name === day.format("DD.MM.YYYY")); if (page) { daysWithNotes.push({ date: day, page }); } else { daysWithoutNotes.push(day); } } // Build Columns plugin Markdown let md = "````col\nheight=shortest\ntextAlign=start\n===\n"; // Columns for days with notes for (const { date, page } of daysWithNotes) { const isToday = date.isSame(today, "day"); const label = `${isToday ? "📌 " : ""}${date.format("ddd")}
${date.format("DD.MM.YYYY")}`; md += "```col-md\n"; md += `### ${label}\n`; // Show reason from frontmatter under the title if (page.reason) { md += `**Reason:** ${page.reason}\n\n`; } // Get tasks from the note const tasks = page.file.tasks; // Filter tasks under # Tasks heading if possible const tasksInSection = tasks.filter(t => { if (t.heading) return t.heading.toLowerCase().includes("tasks"); return true; // fallback: include all tasks if heading not available }); if (tasksInSection.length > 0) { for (const t of tasksInSection) { md += `- [${t.completed ? "x" : " "}] ${t.text}\n`; } } else { md += "_No tasks found_\n"; } md += "```\n\n"; } // Single column for days without notes if (daysWithoutNotes.length > 0) { md += "```col-md\n"; md += "### Days without notes\n"; for (const day of daysWithoutNotes) { md += `- ${day.format("ddd")} — ${day.format("DD.MM.YYYY")}\n`; } md += "```\n\n"; } md += "````\n"; // Render the dashboard dv.paragraph(md); ``` ## Weekend ```dataviewjs // Force English locale for weekdays moment.locale("en"); const today = moment(); // === CONFIGURE WEEK RANGE HERE === // For current week: //const weekStart = today.clone().startOf("isoWeek"); //const weekEnd = today.clone().endOf("isoWeek"); // For next week, uncomment these: // const weekStart = today.clone().add(1, "week").startOf("isoWeek"); // const weekEnd = today.clone().add(1, "week").endOf("isoWeek"); // For weekend only (Sat & Sun): const weekStart = today.clone().startOf("isoWeek").add(5, "days"); // Saturday const weekEnd = today.clone().startOf("isoWeek").add(6, "days"); // Sunday // All notes tagged #Calendar within the week const pages = dv.pages("#Calendar") .where(p => { const d = moment(p.file.name, "DD.MM.YYYY", true); return d.isValid() && d.isBetween(weekStart, weekEnd, "day", "[]"); }); // Generate days array (Mon–Sun or custom) const totalDays = weekEnd.diff(weekStart, "days") + 1; const weekDays = Array.from({ length: totalDays }, (_, i) => weekStart.clone().add(i, "days")); // Separate days with and without notes const daysWithNotes = []; const daysWithoutNotes = []; for (const day of weekDays) { const page = pages.find(p => p.file.name === day.format("DD.MM.YYYY")); if (page) { daysWithNotes.push({ date: day, page }); } else { daysWithoutNotes.push(day); } } // Build Columns plugin Markdown let md = "````col\nheight=shortest\ntextAlign=start\n===\n"; // Columns for days with notes for (const { date, page } of daysWithNotes) { const isToday = date.isSame(today, "day"); const label = `${isToday ? "📌 " : ""}${date.format("ddd")}
${date.format("DD.MM.YYYY")}`; md += "```col-md\n"; md += `### ${label}\n`; // Show reason from frontmatter under the title if (page.reason) { md += `**Reason:** ${page.reason}\n\n`; } // Get tasks from the note const tasks = page.file.tasks; // Filter tasks under # Tasks heading if possible const tasksInSection = tasks.filter(t => { if (t.heading) return t.heading.toLowerCase().includes("tasks"); return true; // fallback: include all tasks if heading not available }); if (tasksInSection.length > 0) { for (const t of tasksInSection) { md += `- [${t.completed ? "x" : " "}] ${t.text}\n`; } } else { md += "_No tasks found_\n"; } md += "```\n\n"; } // Single column for days without notes if (daysWithoutNotes.length > 0) { md += "```col-md\n"; md += "### Days without notes\n"; for (const day of daysWithoutNotes) { md += `- ${day.format("ddd")} — ${day.format("DD.MM.YYYY")}\n`; } md += "```\n\n"; } md += "````\n"; // Render the dashboard dv.paragraph(md); ``` --- # Next Week ```dataviewjs // Force English locale for weekdays moment.locale("en"); const today = moment(); // === CONFIGURE WEEK RANGE HERE === // For current week: //const weekStart = today.clone().startOf("isoWeek"); //const weekEnd = today.clone().endOf("isoWeek"); // For next week, uncomment these: const weekStart = today.clone().add(1, "week").startOf("isoWeek"); const weekEnd = today.clone().add(1, "week").endOf("isoWeek"); // For weekend only (Sat & Sun): // const weekStart = today.clone().startOf("isoWeek").add(5, "days"); // Saturday // const weekEnd = today.clone().startOf("isoWeek").add(6, "days"); // Sunday // All notes tagged #Calendar within the week const pages = dv.pages("#Calendar") .where(p => { const d = moment(p.file.name, "DD.MM.YYYY", true); return d.isValid() && d.isBetween(weekStart, weekEnd, "day", "[]"); }); // Generate days array (Mon–Sun or custom) const totalDays = weekEnd.diff(weekStart, "days") + 1; const weekDays = Array.from({ length: totalDays }, (_, i) => weekStart.clone().add(i, "days")); // Separate days with and without notes const daysWithNotes = []; const daysWithoutNotes = []; for (const day of weekDays) { const page = pages.find(p => p.file.name === day.format("DD.MM.YYYY")); if (page) { daysWithNotes.push({ date: day, page }); } else { daysWithoutNotes.push(day); } } // Build Columns plugin Markdown let md = "````col\nheight=shortest\ntextAlign=start\n===\n"; // Columns for days with notes for (const { date, page } of daysWithNotes) { const isToday = date.isSame(today, "day"); const label = `${isToday ? "📌 " : ""}${date.format("ddd")}
${date.format("DD.MM.YYYY")}`; md += "```col-md\n"; md += `### ${label}\n`; // Show reason from frontmatter under the title if (page.reason) { md += `**Reason:** ${page.reason}\n\n`; } // Get tasks from the note const tasks = page.file.tasks; // Filter tasks under # Tasks heading if possible const tasksInSection = tasks.filter(t => { if (t.heading) return t.heading.toLowerCase().includes("tasks"); return true; // fallback: include all tasks if heading not available }); if (tasksInSection.length > 0) { for (const t of tasksInSection) { md += `- [${t.completed ? "x" : " "}] ${t.text}\n`; } } else { md += "_No tasks found_\n"; } md += "```\n\n"; } // Single column for days without notes if (daysWithoutNotes.length > 0) { md += "```col-md\n"; md += "### Days without notes\n"; for (const day of daysWithoutNotes) { md += `- ${day.format("ddd")} — ${day.format("DD.MM.YYYY")}\n`; } md += "```\n\n"; } md += "````\n"; // Render the dashboard dv.paragraph(md); ``` --- ![[Veranstaltungen - 2025]] --- ![[Wohnorte]] --- # Stats ```dataviewjs // === Config === const splitOnSlash = false; // true -> merge hierarchical tags (#project/obsidian -> project) const topN = 50; // show top N tags (null for all) // === Catppuccin Mocha Palette === const catppuccin = { rosewater: '#f5e0dc', flamingo: '#f2cdcd', pink: '#f5c2e7', mauve: '#cba6f7', red: '#f38ba8', maroon: '#eba0ac', peach: '#fab387', yellow: '#f9e2af', green: '#a6e3a1', teal: '#94e2d5', sky: '#89dceb', sapphire: '#74c7ec', blue: '#89b4fa', lavender: '#b4befe', text: '#cdd6f4', subtext1: '#bac2de', base: '#1e1e2e' }; const catppuccinColors = [ catppuccin.rosewater, catppuccin.flamingo, catppuccin.pink, catppuccin.mauve, catppuccin.red, catppuccin.maroon, catppuccin.peach, catppuccin.yellow, catppuccin.green, catppuccin.teal, catppuccin.sky, catppuccin.sapphire, catppuccin.blue, catppuccin.lavender ]; // === Helpers === function flattenTags(input, out = []) { if (!input) return out; if (Array.isArray(input)) { for (const v of input) flattenTags(v, out); } else if (typeof input === 'string') { out.push(input); } else if (typeof input === 'object') { if (typeof input.tag === 'string') out.push(input.tag); else if (typeof input.path === 'string') out.push(input.path); else { const s = String(input); if (s && s !== '[object Object]') out.push(s); } } else { out.push(String(input)); } return out; } // Convert a string to Title Case (preserving slashes/hyphens) function toTitleCase(str) { return str.replace(/[\w]+/g, w => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase() ); } // === Collect tags from all pages === const pages = dv.pages(); let allTags = []; for (const p of pages) { if (p.file?.tags) flattenTags(p.file.tags, allTags); if (p.tags) flattenTags(p.tags, allTags); if (p.tags_list) flattenTags(p.tags_list, allTags); } // === Normalize and count === const counts = {}; for (let tag of allTags) { if (!tag) continue; tag = String(tag).replace(/^#/, '').trim().toLowerCase(); if (!tag) continue; if (splitOnSlash && tag.includes('/')) tag = tag.split('/')[0]; counts[tag] = (counts[tag] || 0) + 1; } // === Handle no tags === const tagEntries = Object.entries(counts); if (tagEntries.length === 0) { dv.el("p", "⚠️ No tags found in your vault."); } else { // === Sort + limit === tagEntries.sort((a, b) => b[1] - a[1]); const limited = (topN && tagEntries.length > topN) ? tagEntries.slice(0, topN) : tagEntries; // Convert to title case for display const labels = limited.map(e => toTitleCase(e[0].replace(/[-_]/g, ' '))); const dataValues = limited.map(e => e[1]); // === Color setup === const bgColors = []; const borderColors = []; for (let i = 0; i < labels.length; i++) { const color = catppuccinColors[i % catppuccinColors.length]; bgColors.push(color + "55"); borderColors.push(color); } // === Chart.js config === const chartData = { type: 'bar', data: { labels: labels, datasets: [{ label: 'Tag Usage', data: dataValues, backgroundColor: bgColors, borderColor: borderColors, borderWidth: 1 }] }, options: { plugins: { legend: { display: false }, title: { display: true, text: `Tag Usage (Top ${labels.length})`, color: catppuccin.text, font: { size: 16 } } }, scales: { x: { ticks: { color: catppuccin.subtext1, autoSkip: false, maxRotation: 60, minRotation: 30 }, title: { display: true, text: 'Tags', color: catppuccin.text }, grid: { color: catppuccin.base } }, y: { ticks: { color: catppuccin.subtext1 }, title: { display: true, text: 'Count', color: catppuccin.text }, beginAtZero: true, grid: { color: catppuccin.base } } }, maintainAspectRatio: false } }; // === Render === const wrapper = this.container.createEl('div'); wrapper.style.minHeight = '320px'; wrapper.style.maxHeight = '60vh'; wrapper.style.overflow = 'auto'; wrapper.style.borderRadius = '8px'; wrapper.style.padding = '8px'; window.renderChart(chartData, wrapper); } ``` ```dataviewjs // === Config === const splitOnSlash = false; // true -> merge hierarchical tags (#project/obsidian -> project) const topN = 20; // show top N tags (null for all) // === Catppuccin Mocha Palette === const catppuccin = { rosewater: '#f5e0dc', flamingo: '#f2cdcd', pink: '#f5c2e7', mauve: '#cba6f7', red: '#f38ba8', maroon: '#eba0ac', peach: '#fab387', yellow: '#f9e2af', green: '#a6e3a1', teal: '#94e2d5', sky: '#89dceb', sapphire: '#74c7ec', blue: '#89b4fa', lavender: '#b4befe', text: '#cdd6f4', subtext1: '#bac2de', base: '#1e1e2e' }; const catppuccinColors = [ catppuccin.rosewater, catppuccin.flamingo, catppuccin.pink, catppuccin.mauve, catppuccin.red, catppuccin.maroon, catppuccin.peach, catppuccin.yellow, catppuccin.green, catppuccin.teal, catppuccin.sky, catppuccin.sapphire, catppuccin.blue, catppuccin.lavender ]; // === Helpers === function flattenTags(input, out = []) { if (!input) return out; if (Array.isArray(input)) { for (const v of input) flattenTags(v, out); } else if (typeof input === 'string') { out.push(input); } else if (typeof input === 'object') { if (typeof input.tag === 'string') out.push(input.tag); else if (typeof input.path === 'string') out.push(input.path); else { const s = String(input); if (s && s !== '[object Object]') out.push(s); } } else { out.push(String(input)); } return out; } function toTitleCase(str) { return str.replace(/[\w]+/g, w => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase() ); } // === Collect tags === const pages = dv.pages(); let allTags = []; for (const p of pages) { if (p.file?.tags) flattenTags(p.file.tags, allTags); if (p.tags) flattenTags(p.tags, allTags); if (p.tags_list) flattenTags(p.tags_list, allTags); } // === Normalize + count === const counts = {}; for (let tag of allTags) { if (!tag) continue; tag = String(tag).replace(/^#/, '').trim().toLowerCase(); if (!tag) continue; if (splitOnSlash && tag.includes('/')) tag = tag.split('/')[0]; counts[tag] = (counts[tag] || 0) + 1; } const tagEntries = Object.entries(counts); if (tagEntries.length === 0) { dv.el("p", "⚠️ No tags found in your vault."); } else { // === Sort + limit === tagEntries.sort((a, b) => b[1] - a[1]); const limited = (topN && tagEntries.length > topN) ? tagEntries.slice(0, topN) : tagEntries; const labels = limited.map(e => toTitleCase(e[0].replace(/[-_]/g, ' '))); const dataValues = limited.map(e => e[1]); const total = dataValues.reduce((a, b) => a + b, 0); // === Colors === const bgColors = [], borderColors = []; for (let i = 0; i < labels.length; i++) { const color = catppuccinColors[i % catppuccinColors.length]; bgColors.push(color + "aa"); borderColors.push(color); } // === Create container === const wrapper = this.container.createEl('div'); wrapper.style.minHeight = '400px'; wrapper.style.maxHeight = '70vh'; wrapper.style.position = 'relative'; wrapper.style.borderRadius = '8px'; wrapper.style.padding = '8px'; wrapper.style.overflow = 'auto'; // === Center label === const centerLabel = document.createElement('div'); centerLabel.style.position = 'absolute'; centerLabel.style.top = '50%'; centerLabel.style.left = '44%'; centerLabel.style.transform = 'translate(-50%, -50%)'; centerLabel.style.color = catppuccin.text; centerLabel.style.fontSize = '14px'; centerLabel.style.fontWeight = '600'; centerLabel.style.textAlign = 'center'; centerLabel.innerText = 'Tag Usage'; wrapper.appendChild(centerLabel); // === Chart.js config === const chartData = { type: 'doughnut', data: { labels: labels, datasets: [{ data: dataValues, backgroundColor: bgColors, borderColor: borderColors, borderWidth: 1 }] }, options: { cutout: '60%', plugins: { legend: { display: true, position: 'right', labels: { color: catppuccin.subtext1, font: { size: 12 } } }, title: { display: true, text: `Tag Distribution (Top ${labels.length})`, color: catppuccin.text, font: { size: 16 } }, tooltip: { callbacks: { label: ctx => { const val = ctx.raw; const pct = ((val / total) * 100).toFixed(1); return `${ctx.label}: ${val} (${pct}%)`; } } } }, onHover: (evt, elements) => { if (elements.length > 0) { const el = elements[0]; const label = labels[el.index]; const value = dataValues[el.index]; const pct = ((value / total) * 100).toFixed(1); centerLabel.innerText = `${label}\n${pct}%`; } else { centerLabel.innerText = 'Tag Usage'; } }, maintainAspectRatio: false } }; window.renderChart(chartData, wrapper); } ``` ---