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:

  1. Books with reading progress

  2. Projects with a counter of completed and not completed tasks

  3. Progress of the year, month, day and whole life

  4. Films in the form of cards I will disassemble each case under the cut.

Installing Data View

  1. 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)

  2. To get started, go to Menu => Third Party Plugins => Enable Community Plugins

  3. Then “Browse”

  4. 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)

  5. Click “Install”, wait a couple of seconds until the plugin is downloaded and installed

  6. Then click “Enable”

    How it all works in a nutshell

    1. dataview works on built-in query language

    2. 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

  1. This case is designed to compile your own database of books and track reading progress

  2. The request code looks like this:

```dataview
TABLE WITHOUT ID 
	file.link AS "Книга",
	Прогресс_Бар AS "Прогресс",
	Автор,
	URL
FROM "Книги"
```
  1. Let’s break down the code line by line:

    1. TABLE WITHOUT ID – we indicated that we need a table

    2. 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)

    3. 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.

    4. Then Author

    5. Then URL

    6. 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.

  2. 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>
  1. Let’s break it down line by line:

    1. Note title – It will be displayed first in the table

    2. URL is a link to the book

    3. Author – This is the author of the book in quotation marks. there is a gap

    4. 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%)

  2. The end result is a table like this:

Projects with a counter of completed and not completed tasks

  1. This case is designed to track progress on projects

  2. 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 #проекты
```
  1. Let’s break down the code line by line:

    1. TABLE WITHOUT ID – we indicated that we need a table

    2. 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)

    3. Status is the status of our projects (In Progress, Done, Not started)

    4. 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

    5. By this line, we consider the number of all tasks, i.e. take the size of the file.tasks.text array

    6. With this line we count the number of completed tasks

    7. 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

    8. 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.

  2. The notes themselves should contain the following set of parameters:

#проекты
Статус:: "Готово"

---
# ToDo:
- [x] Снять размеры с вытяжки
- [x] Нагуглить вытяжки
- [x] Купить вытяжку
- [x] Съездить за вытяжкой в магазин
- [x] Установить вытяжку
  1. Let’s break it down line by line:

    1. Tag #projects – for the query to select the notes we need

    2. 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

    3. Then a delimiter (—) – for convenience

    4. And then the list of tasks – which will be processed by our table

  2. We end up with a table like this:

Progress of the year, month, day and whole life

  1. This case is designed for visual visualization of the past year/month/day/life. This block is needed sad about lost time

  2. The 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")}
`)
```
  1. Let’s break down the code line by line:

    1. In the first block, we set the constants for the current day and the end of the year

    2. In the second block, we set the predicted life expectancy (80 years) and the date of birth

    3. Next, we describe the function for calculating progress

    4. And at the end we present all this in the form of an arbitrary markdown table

  2. We end up with a table like this:

Movies in the form of cards

  1. 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:

    1. First, set the Minimal theme, for this we go to settings => Appearance => Customize

    2. There we select the theme Minimal

    3. Then we go to third-party plugins and install and enable the Minimal Theme Settings plugin

    4. And then install the Sortable plugin as well

  2. 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 "Фильмы"
```
  1. Let’s break it down line by line:

    1. 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

    2. Then in the dataview block we again set that this will be a table ( TABLE WITHOUT ID )

    3. Then this line ((“![](” + Poster + “)”) as Poster) we tell the handler that we want to display the poster itself as a picture in the table

    4. Then again the title of the note

    5. Then a year of movies

    6. Then movie search rating

    7. Then we display a link to the movie search

    8. We collect all this from the “Movies” folder (FROM “Movies”)

  2. 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"
  1. 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.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *