DataviewJS Snippet Showcase

Hi. I just wanted to share a simple way I found to make dataviewjs render local images on both apps, desktop and mobile.

const filePath = (file) =>
    file.startsWith("http") ?
        file :
        app.vault.adapter.getResourcePath(file)

dv.table(["Name", "Thumbnail"], dv.pages("#Movie")
    .sort(item => item.file.name, 'asc')
    .map(item => [
        item.file.link,
        `![](${filePath(item.thumbnail)})`
    ])
)

The filePath() function just checks if the string starts with http, and converts it to an internal link otherwise, using the vault.getResourcePath function.

A minor inconvenience is that getResourcePath needs the full path to the images. So attachments/example.png works, but just example.png, ![](attachments/example.png) or ![[example.png]] doesn’t. But It can easily be upgraded with more checks to parse wiki links, markdown formatted links, etc.

3 Likes

Display notes with Trello links and click link to notes

Note links will be loaded on demand, thus keeping the table fairly lightweight.

You will, of course, need the Trello plugin installed.

const openButton = (boardandcard, note) => {
	const button = this.container.createEl('button', {"text": "𝌡"});
    button.addEventListener('click', async(e) => {
        e.preventDefault();
		[board, card] = boardandcard.split(";")
		app.plugins.plugins['obsidian-trello'].
			api.getCardFromBoard(board, card).
			forEach((info) => {
				window.location = info.url;
			})
    });
    return button;
}

console.log(dv.current());
dv.table(["Page", "Action"],
	dv.pages('').where(
		p => p.trello_plugin_note_id).sort(
		p => p.file.mtime, "desc").map(
		p => [
			p.file.link,
			openButton(
				p.trello_board_card_id,
				p.trello_plugin_note_id)])
)
1 Like

Hi, don’t know if this is the correct place to post, but i created a plugin that works on top of DataviewJS to display progress for whatever you want to track. Picture says it all i think:

11 Likes

Where can we get this plugin?

Its called “Heatmap Calendar”, search for it on the community plugin list in obsidian

1 Like

Show unresolved links

This snippet allows you to see all your dangling links.
You can configure how many connections each link has to have before it shows up.
You can also exclude existing and non-existing files from showing up.

//how many links a non existing file should have at minimum
const count = 2;

//specify the full path here.
const ignoredExisting = ["your/ignored/notes/here.md"];

//keep these in lower case.
const ignoredNonExisiting = ["your non exisiting notes", "here is note that does not exist"];

let d = {};
function process(k, v) {
  Object.keys(v).forEach(function (x) {
    if(!ignoredNonExisiting.includes(x.toLowerCase())) {
        x = dv.fileLink(x);
        if (d[x]==undefined) { d[x] = []; }
        if(!ignoredExisting.includes(k)) {
            d[x].push(dv.fileLink(k));
        }
    }
  });
}

Object.entries(dv.app.metadataCache.unresolvedLinks)
    .filter(([k,v]) => Object.keys(v).length)
    .forEach(([k,v]) => process(k, v));
    
dv.table(["Non existing notes", "Linked from"],
         Object.entries(d)
         .filter(([k, v]) => v.length >= count)
	     .sort((a, b) => b[1].length - a[1].length)
         .map(([k,v]) => [k, v.join(" • ")]));

(code based on: Is there a way to see backlinks without creating a markdown document? - #3 by JLDiaz)

9 Likes

Could you share an example of the code you used to create this please?

2 Likes

I’m using a Mac, and Dataview is converting “Command” to “Control,” so when I have a hotkey at uses Ctrl-Cmd, it is listed and Ctrl-Ctrl. And more importantly, if it’s Cmd-O, it’s listed as Ctrl-O.

Is there something I could change to have the queries account for the Mac’s command key?

Thanks,
Russell

Hi everybody !

Would you know a method to use emojis as keys inside a dataviewjs query ?
I could write some successful queries using DQL but not with dataviewjs

Somehwere in my vault :

- [ ] [🗝:: value] Text

What I try to do :

let tasks = dv.array(dv.pages().file.tasks)
dv.header(6,tasks[0].🗝)

This doesn’t work and throws an error :

Evaluation Error: SyntaxError: Invalid or unexpected token
[...]

It would be even better if I could have a Yaml setting, such as :

---
filter : 🗝
---

Used in my dataviewjs query :

var filter = dv.current().filter;
let tasks = dv.array(dv.pages().file.tasks)
dv.header(6,tasks[0].filter)

Many thanks in advance for your kind help

Solved by @TfTHacker himself, thank you so much !
For those who would be interested, the solutions are :

let tasks = dv.array(dv.pages().file.tasks)
dv.header(6,tasks[0].["🗝"])

and even the yaml filter thing works,

---
filter : 🗝
---
var filter = dv.current().filter;
let tasks = dv.array(dv.pages().file.tasks)
dv.header(6,tasks[0].[filter])
4 Likes

Generally this works great but for some reason, when I make a new note today I get this error (but it does not happen in the notes I created for all days earlier in this week …):

Evaluation Error: TypeError: Cannot read properties of undefined (reading 'file')
    at eval (eval at <anonymous> (eval at <anonymous> (app://obsidian.md/app.js:1:1444405)), <anonymous>:7:36)
    at DataviewInlineApi.eval (eval at <anonymous> (app://obsidian.md/app.js:1:1444405), <anonymous>:15671:16)
    at evalInContext (eval at <anonymous> (app://obsidian.md/app.js:1:1444405), <anonymous>:15672:7)
    at asyncEvalInContext (eval at <anonymous> (app://obsidian.md/app.js:1:1444405), <anonymous>:15682:32)
    at DataviewJSRenderer.render (eval at <anonymous> (app://obsidian.md/app.js:1:1444405), <anonymous>:16267:19)
    at DataviewRefreshableRenderer.maybeRefresh (eval at <anonymous> (app://obsidian.md/app.js:1:1444405), <anonymous>:15995:26)
    at HTMLDivElement.i (app://obsidian.md/app.js:1:138855)

Oh, but of course a shutdown/re-open of Obsidian fixes this.

:thinking:

Just ignore the above error posting then …

Would love to have this snippet!

1 Like

I have not been able to get inline image to work with Blue Topaz theme. Do we have to specify anything to render images inline?

Hello everyone!

I created a dictionary that pulls all “terms” and “definitions” from my vault, but when there are more than one term and definition, they are all placed in the same table cell.

Here is my code

const pages = dv.pages().where(b => b.term)
dv.table(['Term','definition'],pages
		 .sort(a => a.term,'asc')
		 .map(a => [a.term,a.definition]))

and here is the output:

How can I break up that first row into individual rows?

7 Likes

I have this same question - it’s essentially like “flatten” in regular dataview, but I can’t for the life of me figure out how to do it into dataviewjs.

1 Like

Could you provide a small data example? I’m rather new to dataview (and Obsidian) and unaware how you could get a ‘term’ property on your pages and how the resulting data structure look like :x

General speaking, dv.pages() return a data array that again has a function flatMap. Maybe you get the wanted result when you use flatMap instead of map?

Also, for debugging purposes, it can be helpful if you assign pages.sort(a => a.term,'asc').map(a => [a.term,a.definition]) to a variable and then add a console.log(variableName) to your query. Hitting shift ctrl I in Obsidian opens the developer console whereas you’ll see your console.log call.
This way you can investigate how your resulting table data looks like and how the data differs when you get a single row per term/definion or one row with multiple term/definitions.

It could look like this then:

const pages = dv.pages().where(b => b.term)
const tableData = pages
		 .sort(a => a.term,'asc')
		 .map(a => [a.term,a.definition]);
console.log('tableData ->', tableData)
dv.table(['Term','definition'], tableData)

Hope that helps! :slight_smile:

1 Like

Hi! I made a DataviewJS snippet that automatically adds people’s birthdays in your daily notes upon creation, if it exists, like so:

It uses the file’s alias, but I added an option in the code to use the file name instead.

Credit goes to @Moonbase59’s code here, I only added small modifications, hope that’s okay!

Here’s the gist with setup and instructions:

6 Likes

This is very useful – thank you for sharing it. I already have a People folder, and in it the individuals have birthDate: in the yaml. Which bits of your template should I change to accommodate this?

Please tell me how can I learn about the obsidian dataviewjs plugin from the beginning. I am from a non-coding background and don’t know javascript. But I am interested in learning this plugin.