## Daily ```dataviewjs // User-defined variables const currentPage = dv.current(); const numDaysBack = 30; const fields = ["Physical", "Mental"]; const calculationType = "default"; const today = new Date(); const dailyData = {}; // Enhanced debug function const debug = (message, data) => { console.log(`DEBUG: ${message}`, JSON.stringify(data, null, 2)); }; // Helper function to validate and parse values const parseValue = (value) => { if (value === undefined || value === null || value === '') return 0; if (typeof value === 'number') return value; if (typeof value === 'string') { const parsed = parseFloat(value.replace(/[^\d.-]/g, '')); return isNaN(parsed) ? 0 : parsed; } return 0; }; // Initialize data structure for (let i = 0; i < numDaysBack; i++) { const date = new Date(today); date.setDate(date.getDate() - i); const dateStr = date.toISOString().split('T')[0]; dailyData[dateStr] = {}; fields.forEach(field => { dailyData[dateStr][field] = 0; }); } // Get pages and validate data const pages = dv.pages("#reviews/daily") .sort(p => p.file.name, "desc") .where(p => { try { const pageDate = new Date(p.file.name); if (isNaN(pageDate.getTime())) { debug("Invalid date in filename", p.file.name); return false; } const daysAgo = Math.floor((today - pageDate) / (1000 * 60 * 60 * 24)); return daysAgo <= numDaysBack; } catch (e) { debug("Error processing page date", { filename: p.file.name, error: e.message }); return false; } }); debug("Total pages found", pages.length); // Process each page pages.forEach(page => { try { const pageDate = new Date(page.file.name); const dateStr = pageDate.toISOString().split('T')[0]; debug("Processing page", { date: dateStr, availableFields: Object.keys(page) }); fields.forEach(field => { try { const rawValue = page[field]; debug(`Raw ${field} value`, rawValue); const parsedValue = parseValue(rawValue); debug(`Parsed ${field} value`, parsedValue); dailyData[dateStr][field] = parsedValue; } catch (e) { debug(`Error processing field ${field}`, { error: e.message, page: page.file.name }); dailyData[dateStr][field] = 0; } }); } catch (e) { debug("Error processing page", { page: page.file.name, error: e.message }); } }); debug("Final daily data", dailyData); // Prepare chart data const dates = Object.keys(dailyData).sort(); const series = fields.map(field => { let runningSum = 0; const data = dates.map(date => { if (calculationType === "sum") { runningSum += dailyData[date][field]; return runningSum; } return dailyData[date][field]; }); return { title: field, data: data }; }); // Generate colors const colors = fields.map((_, index) => { const hue = (index * 360 / fields.length); return `hsl(${hue}, 70%, 50%)`; }); // Create chart const chartConfig = `\`\`\`chart type: bar labels: [${dates.map(d => `"${d}"`)}] series: [ ${series.map((s, i) => ` { title: "${s.title}", data: [${s.data}], backgroundColor: "${colors[i]}", borderColor: "${colors[i]}" }`).join(',\n')} ] width: 100% stacked: false fill: true beginAtZero: true legend: true legendPosition: top xAxisLabel: Date yAxisLabel: ${calculationType === "sum" ? "Cumulative Value" : "Daily Value"} \`\`\``; dv.paragraph(chartConfig); // Display statistics fields.forEach((field, index) => { const values = dates.map(date => dailyData[date][field]); const sum = values.reduce((a, b) => a + b, 0); const avg = (sum / values.length).toFixed(1); dv.paragraph(`<span style="color: ${colors[index]}">${field} - Total: ${sum.toFixed(1)} | Average: ${avg}</span>`); }); ``` ## Sum ```dataviewjs // User-defined variables const currentPage = dv.current(); const numDaysBack = 30; const fields = ["Physical", "Mental"]; const calculationType = "sum"; const today = new Date(); const dailyData = {}; // Enhanced debug function const debug = (message, data) => { console.log(`DEBUG: ${message}`, JSON.stringify(data, null, 2)); }; // Helper function to validate and parse values const parseValue = (value) => { if (value === undefined || value === null || value === '') return 0; if (typeof value === 'number') return value; if (typeof value === 'string') { const parsed = parseFloat(value.replace(/[^\d.-]/g, '')); return isNaN(parsed) ? 0 : parsed; } return 0; }; // Initialize data structure for (let i = 0; i < numDaysBack; i++) { const date = new Date(today); date.setDate(date.getDate() - i); const dateStr = date.toISOString().split('T')[0]; dailyData[dateStr] = {}; fields.forEach(field => { dailyData[dateStr][field] = 0; }); } // Get pages and validate data const pages = dv.pages("#reviews/daily") .sort(p => p.file.name, "desc") .where(p => { try { const pageDate = new Date(p.file.name); if (isNaN(pageDate.getTime())) { debug("Invalid date in filename", p.file.name); return false; } const daysAgo = Math.floor((today - pageDate) / (1000 * 60 * 60 * 24)); return daysAgo <= numDaysBack; } catch (e) { debug("Error processing page date", { filename: p.file.name, error: e.message }); return false; } }); debug("Total pages found", pages.length); // Process each page pages.forEach(page => { try { const pageDate = new Date(page.file.name); const dateStr = pageDate.toISOString().split('T')[0]; debug("Processing page", { date: dateStr, availableFields: Object.keys(page) }); fields.forEach(field => { try { const rawValue = page[field]; debug(`Raw ${field} value`, rawValue); const parsedValue = parseValue(rawValue); debug(`Parsed ${field} value`, parsedValue); dailyData[dateStr][field] = parsedValue; } catch (e) { debug(`Error processing field ${field}`, { error: e.message, page: page.file.name }); dailyData[dateStr][field] = 0; } }); } catch (e) { debug("Error processing page", { page: page.file.name, error: e.message }); } }); debug("Final daily data", dailyData); // Prepare chart data const dates = Object.keys(dailyData).sort(); const series = fields.map(field => { let runningSum = 0; const data = dates.map(date => { if (calculationType === "sum") { runningSum += dailyData[date][field]; return runningSum; } return dailyData[date][field]; }); return { title: field, data: data }; }); // Generate colors const colors = fields.map((_, index) => { const hue = (index * 360 / fields.length); return `hsl(${hue}, 70%, 50%)`; }); // Create chart const chartConfig = `\`\`\`chart type: bar labels: [${dates.map(d => `"${d}"`)}] series: [ ${series.map((s, i) => ` { title: "${s.title}", data: [${s.data}], backgroundColor: "${colors[i]}", borderColor: "${colors[i]}" }`).join(',\n')} ] width: 100% stacked: false fill: true beginAtZero: true legend: true legendPosition: top xAxisLabel: Date yAxisLabel: ${calculationType === "sum" ? "Cumulative Value" : "Daily Value"} \`\`\``; dv.paragraph(chartConfig); // Display statistics fields.forEach((field, index) => { const values = dates.map(date => dailyData[date][field]); const sum = values.reduce((a, b) => a + b, 0); const avg = (sum / values.length).toFixed(1); dv.paragraph(`<span style="color: ${colors[index]}">${field} - Total: ${sum.toFixed(1)} | Average: ${avg}</span>`); }); ```