Tracking Elul In Obsidian

This Elul I’m going with a “one thing” approach: one practice, one log, and a couple of charts that keep me honest. The goal is zero ceremony—hit a QuickAdd button, jot a line, and let Obsidian do the rest. Here’s the setup.


Template for each day:

---
date: 2025-08-24
gratitudeMeditation: false
gratefulFor:
  - life
lieCounter: 0
type: Elul Log
---

Started meditation around [timeStarted:: null]. gratitudeMeditation → did I actually do it?

  • gratefulFor → concrete things I named.
  • lieCounter → reinforcement for my “truthfulness” resolution.
  • timeStarted → inline timestamp for consistency.

QuickAdd makes this painless: one hotkey = new log. Another marks the meditation done and stamps the time, another increments the lie counter.

All the pieces roll up into a single Resolution note with the Elul window in the front-matter:

---
type: Resolution
resolution: Every day, preferably in the morning, meditate on Hashem’s kindness and the many gifts He has given me in His infinite love.
year: 5785
elulStart: 2025-08-24
elulEnd: 2025-10-03
---

The rest of the page is just DataviewJS + ChartsView.

Pie chart showing how many days I’ve completed vs missed:

type: Pie
data: |
  dataviewjs:
  const { elulStart, elulEnd } = dv.current().file.frontmatter;
  const start = dv.date(elulStart);
  const end   = dv.date(elulEnd).endOf('day');

  const logs = dv.pages("Elul Logs")
    .where(p => p.type === "Elul Log" && p.date &&
                dv.date(p.date) >= start && dv.date(p.date) <= end)
    .array();

  const completed = logs.filter(p => p.gratitudeMeditation).length;
  const missed = logs.length - completed;

  return (logs.length
    ? [{ status: "Completed", count: completed },
       { status: "Missed", count: missed }]
    : [{ status: "No data yet", count: 1 }]);

options:
  angleField: "count"
  colorField: "status"
  label:
    type: "inner"
    offset: "-30%"
    content: "{percentage}"

Basically a streak visualizer: did I actually show up?

Truthfulness – Daily Counts Column chart of lie counts per day:

type: Column
data: |
  dataviewjs:
  const { elulStart, elulEnd } = dv.current().file.frontmatter;
  const start = dv.date(elulStart);
  const end   = dv.date(elulEnd).endOf('day');

  const logs = dv.pages()
    .where(p => p.type === "Elul Log" && p.date &&
                dv.date(p.date) >= start && dv.date(p.date) <= end)
    .sort(p => p.date, 'asc')
    .array();

  return logs.map(p => ({
    date: dv.date(p.date).toISODate(),
    lies: p.lieCounter ?? 0
  }));

options:
  xField: "date"
  yField: "lies"
  xAxis:
    type: time
    mask: "YYYY-MM-DD"
    title: { text: "Date" }
  yAxis:
    title: { text: "Lie Count" }
    min: 0

Lets me see if the counter stays flat at zero or spikes.

The pie chart only counts logged days. If I want accuracy against the entire Elul window (including blanks), I use this DataviewJS snippet:

const { elulStart, elulEnd } = dv.current().file.frontmatter;
const start = dv.date(elulStart).startOf('day');
const end   = dv.date(elulEnd).endOf('day');

// restrict to "Elul Logs" folder; exclude template files
const logs = dv.pages('"Elul Logs"')
  .where(p => p.type === "Elul Log" && p.date && dv.date(p.date) >= start && dv.date(p.date) <= end)
  .where(p => !p.file.name.toLowerCase().includes("template"))
  .array();

const doneDays = new Set(logs.filter(p => p.gratitudeMeditation).map(p => dv.date(p.date).toISODate()));

let totalDays = 0, completed = 0;
for (let d = start; d <= end; d = d.plus({ days: 1 })) {
  totalDays++;
  if (doneDays.has(d.toISODate())) completed++;
}

const pct = totalDays ? Math.round((completed / totalDays) * 100) : 0;
dv.paragraph(`Completed: ${completed} / ${totalDays} (${pct}%)`);

That one doesn’t care if I logged—if I didn’t show up, it still counts as a miss.

At the bottom of the page I keep the script I actually use, so the dashboard isn’t just analytics—it reminds me what I’m supposed to be doing:

The point isn’t the charts. It’s that with automation in place, I don’t burn willpower on logistics. QuickAdd spawns the logs, Dataview aggregates them, ChartsView makes the streak obvious. My only job is to actually do the practice.

And yes—it’s also just fun to nerd out.