I use a fairly complex DataviewJS script. I fine tuned it to my situation, but I suspect it could work for others with a few tweaks.
My vault has a lot of content that I don’t consider zettels, so my script specifically looks for notes with a “date” field, that’s how I distinguish between my zettels and other content. I use this string in my zettel template to create the correct date format:
---
date: {{date:YYYYMMDD}}{{time:HHmm}}
---
This is the date I query off of, because I’ve found Dataview’s “cdate” field to be unreliable. It works better to include the string in each note. I also check certain configurable folders for efficiency (for me, my “Umami” and “Fleeting” folders).
And here is my script for creating the table and graphs (you’ll need both the Dataview and Obsidian Charts plugins installed and active). “daysback” controls the date range for the table, and “chartlength” controls the date range for both charts.
daysback:: 3
chartlength:: 100
location:: "Umami" OR "Fleeting"
```dataviewjs
var start = moment().startOf('day');
var dateformat = "YYYYMMDDhhmm";
var daysback = (dv.current().daysback) || 2;
var location = dv.current().location || '';
var chartlength = dv.current().chartlength || 50;
var docs = dv.pages(location);
function getRecentDocs(numDays) {
// this function finds recently created docs
// it uses a where function to return a collection
// based on days in the past
return docs
.where(f => {
if (!f.date) return false;
var pastDate = moment(start).subtract(numDays, 'days');
var docDate = moment(f.date, dateformat);
return docDate.isAfter(pastDate);
});
}
// creating the table
var ztDocs = getRecentDocs(daysback);
dv.table(['link', 'date'], ztDocs
.sort(f => -f.date)
.map(b => [b.file.link, moment(b.date, dateformat).format('YYYY-MM-DD hh:mm')]));
// creating the charts
var ztLastWeek = getRecentDocs(chartlength).sort(f => f.date);
var daysData = [];
var totalcount = 0;
// formatting the data
for (var i=0; i<=ztLastWeek.length; i++) {
var f = ztLastWeek[i];
if (f && f.date) {
var itemDate = moment(f.date, dateformat);
var newDate = itemDate.format('MM-DD');
var index = daysData.findIndex(d => d.label === newDate);
if (index !== -1) {
daysData[index].num += 1;
} else {
daysData.push({label: newDate, num: 1});
}
totalcount += 1;
}
};
var labels = [],
data = [],
aggData = [];
daysData.map(el => {
labels.push(el.label);
data.push(el.num);
if (aggData.length) {
var lastNum = aggData[aggData.length - 1];
aggData.push(el.num + lastNum);
} else {
aggData.push(el.num);
}
});
const lineChart = {
type: 'line',
data: {
labels: labels,
datasets: [{
label: 'Docs created',
data: data,
backgroundColor: [
'#4e9a06'
],
borderColor: [
'#4e9a06'
],
borderWidth: 1
}]
}
}
const aggregateChart = {
type: 'line',
data: {
labels: labels,
datasets: [{
label: 'Aggregate Docs Created',
data: aggData,
backgroundColor: [
'#4e9a06'
],
borderColor: [
'#4e9a06'
],
borderWidth: 1
}]
}
}
// render both charts and a total
window.renderChart(lineChart, this.container);
window.renderChart(aggregateChart, this.container);
dv.paragraph('Total: ' + totalcount);
\```
Not the cleanest code, but it works for me. Let me know if you try it, I’d be interested to see if it works for anyone else!