Dataview: One row per day

Hey, i am currently getting started creating different dashboards with dataview.
One of my use-cases is tracking my gym training.

Usually in my daily notes i note down what kind of workout i did that day.
Like Training:: Push or Training:: Pull.
Now i would like to have an overview of when i have trained what body parts and also the days that i did not go to gym at all. My first query looked like this:

TABLE WITHOUT ID dateformat(file.day, "dd.MM.yyyy") as "Datum", Training
WHERE Training AND file.day >= (date(today) - dur(2 weeks))
SORT file.day DESC

Now this works alright, but it does not show me the days that i did not train. I might change the query to something like:

TABLE WITHOUT ID dateformat(file.day, "dd.MM.yyyy") as "Datum", Training
FROM #daily
WHERE file.day >= (date(today) - dur(2 weeks))
SORT file.day DESC

This is a bit better, but it only shows me the date if i created a daily note on that day.
There are days when i’m not at home and therefore neither go to gym nor make daily notes in general. I would still like those dates to show up in my dataview table.
Basically get one row for every day, regardless if the daily note for that day exists or not.
Is there any way to accomplish this?

Thanks!

If anyone else comes across this problem, i ended up solving it like this:

```dataviewjs
const dates = [...Array(14)]
    .map((_, i) => {
        const d = new Date();
        d.setDate(d.getDate() - i);
        return d;
    })
    .sort((a, b) => b - a)
    .map(d => d.toLocaleDateString('de-DE'));

let dateTrainingMap = dv.pages('#daily')
    .where(p => p.Training)
    .array()
    .reduce((map, page) => {
        map[page.file.day.toLocaleString('de-DE')] = page.Training;
        return map;
    }, {});

let result = dates.map(d => [d, dateTrainingMap[d]]);
dv.table(['Datum', 'Training'], result);
```đť…´

If you know a better way to accomplish this, please let me know :slight_smile:

1 Like

Since you asked for advice, here’s an alternate construction of the first block. It takes more advantage of what native JS offers and uses the luxon API (which dataview uses internally). It may be harder to understand if you’re not as comfortable in functional-style JS like this, but I hope it’s helpful!

  • dv.date("today") gives you a luxon DateTime
  • [...Array(14)].keys() gives you the array from 0 to 13, since arrays are like objects with integer keys
  • the .minus (and .plus) methods on a DateTime accept an object (see docs), so you can use the map arg directly as the number of days
  • an Array’s .reverse method is clearer than the sort
const today = dv.date("today");
const dates = (
  // 0, 1, ..., 13
  [...Array(14).keys()]
  // today, yesterday, ... 13 days ago
  .map(days => today.minus({ days }).toLocaleDateString('de-DE')
  // 13 days ago, 12 days ago, ... , today
  .reverse()
)
``
2 Likes

Thanks alot, i will adapt that!