Obsidian + Dataview: Tables

This comment inspired me to write this article.
Dataview is a powerful plug-in for Obsidian that allows you to select data (tags, dates, numbers and any other custom parameters) of markdown notes, and then filter and select them as you wish.
This is a kind of analogue of Notion-tables, where you can create a table with infinite nesting (a table, inside one cell, and inside another table and more and more).
KDPV just collected different cases of implementing the functionality of the Dataview plugin:
Books with reading progress
Projects with a counter of completed and not completed tasks
Progress of the year, month, day and whole life
Films in the form of cards I will disassemble each case under the cut.
Installing Data View
This manual is written for program version 1.1.9. (Before all the actions described below, it would be nice to update: Menu => About the program => Check for updates)
To get started, go to Menu => Third Party Plugins => Enable Community Plugins
Then “Browse”
Then we find Dataview in the list (You can write in the search, or you can not write, this plugin is second in the list)
Click “Install”, wait a couple of seconds until the plugin is downloaded and installed
Then click “Enable”
How it all works in a nutshell
dataview works on built-in query language
All requests should be written inside a block of code like this:
```dataview TABLE|LIST|TASK <Поле1> [AS "Название столбца"], <Поле2>, ..., <Поле3> FROM <Источник> WHERE <Выражение> SORT <Выражение> [ASC/DESC] ... другие команды ```
Books with reading progress
This case is designed to compile your own database of books and track reading progress
The request code looks like this:
```dataview
TABLE WITHOUT ID
file.link AS "Книга",
Прогресс_Бар AS "Прогресс",
Автор,
URL
FROM "Книги"
```
Let’s break down the code line by line:
TABLE WITHOUT ID – we indicated that we need a table
Next, we list the columns that we need, the first column will be a link to the note itself (file.link), and this column will be called “Book” (AS Book)
Then we need a progress bar (Progress_Bar), and this column will be called “Progress” (AS “Progress”) – AS … – we write only when we want the column to be called something different from the parameter that follows it hiding. For a change, you can use emoji, they are supported.
Then Author
Then URL
Then we specify where the notes from the “Books” folder (FROM “Books”) will be collected and processed. This method of selecting notes is suitable for those who want to select notes from a specific folder => notes in your repository should be sorted into folders. In the future, when adding a new note to the specified folder, it will also be displayed in the resulting table.
The notes themselves should be in the “Books” folder and contain the following set of parameters:
URL:: [LitRes](https://www.litres.ru/stiven-kovi/7-navykov-vysokoeffektivnyh-ludey-moschnye-instrumenty-razviti/)
Автор:: "Кови Стивен"
Прогресс_Бар:: <p> <progress max=100 value=90> </progress> 90% </p>
Let’s break it down line by line:
Note title – It will be displayed first in the table
URL is a link to the book
Author – This is the author of the book in quotation marks. there is a gap
Progress_Bar – Here we set the bar progress parameters, the maximum value (progress max=100), the current value (value=90) and the text explanation (90%)
The end result is a table like this:
Projects with a counter of completed and not completed tasks
This case is designed to track progress on projects
The request code looks like this:
```dataview
TABLE WITHOUT ID
file.link AS Проект,
Статус,
(length(filter(file.tasks.completed,
(length(file.tasks.text)) AS Всего,
(length(filter(file.tasks.completed,
(length(file.tasks.text)) - (length(filter(file.tasks.completed,
FROM #проекты
```
Let’s break down the code line by line:
TABLE WITHOUT ID – we indicated that we need a table
Next, we list the columns that we need, the first column will be a link to the note itself (file.link), and this column will be called “Project” (AS Project)
Status is the status of our projects (In Progress, Done, Not started)
In the next line, we calculate the number of completed tasks in the project and the number of unfinished tasks, divide them by each other and get the percentage of project completion
By this line, we consider the number of all tasks, i.e. take the size of the file.tasks.text array
With this line we count the number of completed tasks
And with this line we subtract the number of completed tasks from the total number of tasks and thus get the number of incomplete tasks
Then we specify where the notes will be collected and processed from. In this case, all notes with the tag #projects (FROM #projects) will be selected. This method of selecting notes is suitable for those who want to select notes with a specific tag => notes in your repository must be assigned the appropriate tags. In the future, when a new note with the specified tag is added to the repository, it will also be displayed in the resulting table.
The notes themselves should contain the following set of parameters:
#проекты
Статус:: "Готово"
---
# ToDo:
- [x] Снять размеры с вытяжки
- [x] Нагуглить вытяжки
- [x] Купить вытяжку
- [x] Съездить за вытяжкой в магазин
- [x] Установить вытяжку
Let’s break it down line by line:
Tag #projects – for the query to select the notes we need
Status – so that it is displayed in the table. In the future, this status can be changed in the note and it will change in the table
Then a delimiter (—) – for convenience
And then the list of tasks – which will be processed by our table
We end up with a table like this:
Progress of the year, month, day and whole life
This case is designed for visual visualization of the past year/month/day/life. This block is needed
sad about lost timeThe request code looks bigger, like this (this code already uses JavaScript). It differs in the first line dataview => dataviewjs
```dataviewjs
const today = DateTime.now()
const endOfYear = {
year: today.year,
month: 12,
day: 31
}
const lifespan = { year: 80 }
const birthday = DateTime.fromObject({
year: 1990,
month: 3,
day: 11
});
const deathday = birthday.plus(lifespan)
function progress(type) {
let value;
switch(type) {
case "lifespan":
value = (today.year - birthday.year) / lifespan.year * 100;
break;
case "year":
value = today.month / 12 * 100
break;
case "month":
value = today.day / today.daysInMonth * 100
break;
case "day":
value = today.hour / 24 * 100
break;
}
return `<progress value="${parseInt(value)}" max="100"></progress> | ${parseInt(value)} %`
}
dv.span(`
| | Прогресс | Процент |
| --- | --- |:---:|
| **Год** | ${progress("year")}
| **Месяц**| ${progress("month")}
| **День**| ${progress("day")}
| **Жизнь** | ${progress("lifespan")}
`)
```
Let’s break down the code line by line:
In the first block, we set the constants for the current day and the end of the year
In the second block, we set the predicted life expectancy (80 years) and the date of birth
Next, we describe the function for calculating progress
And at the end we present all this in the form of an arbitrary markdown table
We end up with a table like this:
Movies in the form of cards
This case is designed to compile your own library of watched or vice versa unwatched films. To implement this case, you need to do a couple more preparatory steps:
First, set the Minimal theme, for this we go to settings => Appearance => Customize
There we select the theme Minimal
Then we go to third-party plugins and install and enable the Minimal Theme Settings plugin
And then install the Sortable plugin as well
The request code looks like this:
---
cssClasses: cards, cards-cover, cards-1-1, table-max, cards-cols-4
---
```dataview
TABLE WITHOUT ID
("") as Постер,
file.link AS Название,
Год,
РейтингКП,
URL
FROM "Фильмы"
```
Let’s break it down line by line:
First, we assign a custom css class to the note, for this we beat it off from above and below with separators (—), and in between them we write cards, cards-cover, cards-1-1, table-max, cards-cols-4, this means that we will have a table in the form of cards, the cards will be 1×1 in size, the table will be stretched to the entire width of the note and we fix the number of columns = 4
Then in the dataview block we again set that this will be a table ( TABLE WITHOUT ID )
Then this line ((“”) as Poster) we tell the handler that we want to display the poster itself as a picture in the table
Then again the title of the note
Then a year of movies
Then movie search rating
Then we display a link to the movie search
We collect all this from the “Movies” folder (FROM “Movies”)
The notes themselves should contain the following set of parameters:
Год:: 2003
РейтингКП:: 8.7
URL:: "[Кинопоиск](https://www.kinopoisk.ru/film/3498/)"
Постер:: "https://kinopoisk-ru.clstorage.net/N30iW1384/e515deON/2zI0YN6s508t2KHYsS6u_7YQb9WcfzvbzhmPOPlra6c20ffu3qRaZAQJo-WDAweGjJX5SdfmSPBis5fUXmnHbD_2FBHL6RZb6C10PEDu_jqzJI4VGWvvD0t9zunMvt5VxdN0zEmGOZaGC2Xxt0d2U1kADUiCU8zA4yem43291-vIU5VSn680az8ach9wPy7fZlK7xZ2-Lnivelnaa0qJ5yVh9D6bVHvkpSk0EiVWs5LrI69psdIegdcGtOBfS4VYifM08o7fBpqtOFJNMx2czWVQ-gQPLI5bTeoa6RpoiiVEcYa9yffYJCRZJ8Pnl3KCu6BsmxIzPMFmhOYQfDuH6kkB9lDufrQq7UigbmAeXU2WgRol7twNG-6467j669s1J4MEjBhnutWEaJVQBnVDsctDfQsBAs3AN4b0or9qp9gZ43bQ3M71GV6bYd5ArgwMxoG6lj69fVlvahtJenkoFHchBm3p98pVRml0IaZWIYLLEiwYEwIu0tTGRcGdSoY5yFE2ke7u52uNaoNPAKwNb0cha-YObg147FvZyDlo6vT08xT_OtaJJkfbFSHndNCR-xOfq-Hz3ZCm5abxLcq1ixqD9sLdj9f43iuCTED8jU-XM6v3nw18eax6CLtbSboll7BErsk0OjU2aLYxp1Ugg0rDThngYMzS10RGMJz5FTiJgjcynN6nCf34Uv8xrk8NBFLpJ9x83YotStvJW1lL9zQzlhyYZCqXFFtHkeR2EuCokG1asnH_kfeHxYAvaPb5qcN0oV3v9hnuK4BNcx6NbWTDynYsPi45PvnquMipSvUFYMRt-ffaZ7U7trA2tBMyifOvyIITLMHUVDSyfWmWWogBJrH_3ZTI_8vBjyOcbV_FQytnDo3dW-_LarppaStFNDNFThvmq9SG29RBhQZQINrCjfvR4D0T14WHIC9a9NgbQvXgj76GGv06IkzSnb9f1RF7dE2PDjjtK6s4aKq4NBdC5Y0LZqkmVUpVgNc0cRGJA6_r8rGP0AeGVoHfCWf6SgEH4o5tNlv-iNLcEe5tLpdzaWX9HP1JLWqb2evo-bRUwzZvyGS7F0bpxdBXNXBQe2Fv-oGx70FFVxagLxj1yBmiZGD9jqVJHWpCDNL_3byEEot1rz1eat0KuojJOhpGhuJGTUlUahcUCVax9heCcdlhf4ricg7C1YSmI91K5UnJA4Qh7a7l6S_6MB1g_q4vNnLZlvz-P5r8qCj5Gpm5FMcCRq8YhdqWpjj3k1REEiJ7YG0K4aPu0tf3J_KuypQaidBWgKxshwl_G9Od0R4PLUaS-pcuPf05P9oKSqk5SUcUUDaem_a4xsdqxWAndLIzmbCPC6ITDMBEx7bTH9mXy6sBdtEd7edabXhAbIMvHoy0M3g2Pg7ce30IGQsY2ugXVEJF7qjk-ndlGrUztCcx0vuyr4iB8s6CFGSV8-5bhStqsiYT_o1GyQ26Y56Djv7-dQJLBZ8938ie28vbe8rbhNWyBv97N8qVVrj1IcW2wjGKMB_pUrAfkPTllxJMy2Taq_J0ApzNFyj_udIM876c75fTy9VNLe1Z3GhZCHtbmcSkg4QNeQR6F3To56IWtyCR2DINmQMATnH3dAdRD3qEKZgQReK9nbbpfgpCz2GPHRxmcEinP13uCD6o2mnrucjXlQPkrNtUaacGy6Uj9CbR0xkzvOrh0Y2RJff18P741OhrMDTR_qzG-x1oAhyg_x5u52C4Vn0_34lcyvtJeNnL95dDB9zo5BnkZ_jWcrZG4IK60U9rYCJeUQbVhVGNS7XZGzP10g8_Zjm9KhD8MTxsLbahKlZvjr3L3PmIyKto2lWmQBT-KieploQZVfJUpzDA6DAcy8Mw_aJndGaC3opGG-nA19DPPkVpDUtz7KL-7nzn01g0Tv4euIxqS9jquvlm52PWf_t16zSna1cClydiwvnDraviknzDZTak8l5bdYprA-UBHP1X676LQj6gzYzdpMKpVYyOnKlemkn4OOjLRBRwJ33LJGjlF_kX0PZWMIPY4a8aEyPtMPU2lXMsW2fZenNHUe6uhgqvK5PNUIxOzWfjORbub35IvWmaajnLKYUVcaeuSwQLlZYIx6KGJBHxC7BfyiHQXTAVteVCTNpG6WozpuCuH2UZX2pQ3zLNHu1XEwmVrQyMGd44C4g5iUl05sMlfOpni7aFGSUB93cA0rliTZuT4c8gtZZ2o-5aliirYSaD3g5E6d8aMH7yHO8f5iBLxR5v3etPemvai5n615eiZcx6NguGtxkUIDVVUuPYAE-rsCJuYjbX5PBea6VZiAAUEQ7dVgqOanF-wo3O_7aBmncMr98ZXChImtq5O_bE88WtGgf49Aa61_O1JQPDiUK_moCz3KH3VAYQX9sFaHsDdKCvjYYYvfiR_mId_MylMntmP0yNSW7paMq5KXpmttPXfTomKTSWmceT9tUC89kAHXuxw33C1IQ3cv0K9ipKMCYzHy0War9KkPwyDgxNZXGIR-6cL4mOudvYaxgp9tWzJ9355KpmZlr0MHc3E-FZ4qzYEcPPMJb3J8JNeLbqS_OWoc8vNMvviCFNQ8wevbcBG-b-TD9Z3utLiWhbG-U04aQ-eFb7FSUJNIHGVaPTGdBcOOOyfcN0RlXibRuGKqtD5_KOf9drHRjyLgGt3gzH44l0fh5uWLx5y4kbafp3dINWrxvWCbR0aWVgNXeCIsnA3LuisS5S52Y3gcxZtUmpQAXhb-9WKJ6oAK5jnn-cpJN6p_0-3-veK2nLe1iIdBYCVp_6teqElVtFMhe3MlG7Us8KguINsweG9WMOa-RZe-E0YL-91JscGJF8Yn2uXuRxOUZePs5ZLtiJaOlJ6AUXUya_yfRKBlYq12HkxIHRCQCt-bAwTxFG9rbh_GiGC5tjZdF8PUcqr7phTvI8_z_kgzmULB9tOWyoiZoZycpHd1AGfvlk2mW3SKVgJIYTkNvCLOjTgT1ipvRX0"
In the end, we get such a table that can be sorted on the fly by any of the fields (thanks to the Sortable plugin):
Conclusion
I hope I was able to reveal a small part of the functionality of the Dataview plugin.
Perhaps the case studies will inspire someone.
Not having time to publish this article, I already started drafting an article about tasks in the same Dataview plugin, which I have been using actively for more than a year and by now I have already created more than 6 thousand tasks for myself.
And we will disassemble each case under the cut.