Open EhuddR opened 3 years ago
I have a potential hack for this, though doing it is somewhat annoying in general (I don't think I can add links directly to the Obsidian indices easily). Will investigate for next major release.
Thank you! It will be amazing if you can add that feature
Duplicate of #224
While I realize this doesn't fit every use case, it fits nearly all of mine, so it might help some people.
Until this exciting feature is added, I've got a work around using the Templater plugin to auto-generate my links. I've tested it on Windows 10, Linux, and mobile, and it only works on the first two. Since it works on Linux, I would guess it works on MacOS too, though I can't say for sure.
https://gist.github.com/ngraham20/bb1528357bb692baacffc5fb3943c0a0
Essentially it just scrapes the file's current folder and generates links to all files in said folder. Hope it helps!
This will be a excelent adiction
Is there an ETA for this?
Just showing my support for this issue. Thanks for your hard work. This tool is incredibly useful.
To give some context on why this has not been implemented: it's difficult. I need two things for this to work:
The first one is a little scary performance wise, though it is probably doable; the second one I have no route forward on. The only remediation I can offer is work I am doing on "materializing" views, where it converts a query into plain markdown results, which WILL show up in the graph (since Obsidian will parse it). This should work as a stopgap for MOCs / other tables in the short term.
Re: materialising views, something akin to freezing MIDI tracks in Ableton Live might be worthwhile, e.g. bouncing the results in place and freezing the initial query/settings. This way, users could run a "refreeze" command that executes the query once more while updating the frozen results. This may prevent extensive recalculation, and would suit my use case where I would only need to update the graph once in a while (and might actually be preferable, as this also paves the way for modular writing approaches where frozen query results can be reviewed and edited in place as pure markdown, while the initial query still exists somewhere in a frozen codeblock, YAML field or elsewhere).
If graph rendering is to be have by default, I would like an approach that offers the non-indexation and vice versa. I suggest something in the lines of the existing WITHOUT ID. I.E: "WITHOUT INDEX".
Graph rendering would be default-off and opt-in on queries (since it would be super noisy otherwise); it would likely be WITH INDEX
or INDEXED
or be a different query type all-together.
@blacksmithgu
- I have to pre-compute every query in the vault for links that it produces, and cache these somewhere.
One of my needs of this feature is somewhat static, so what I'm currently doing is the following:
Maybe there is no need for external caching, this process could be done programmatically, the end user don't even have to notice that when he finishes editing the query, that the rendered result is the just computed or just a copy of the computed. So the extension would run the query and copy it results to its place.
By having the computed result with the links right in the .md file, there is no need for adaptations to work with the graph view.
There could be a routine that goes though every single file and updates the query, this could be called manually, periodically, each time the vault is opened... in the future there could even be some clever watchers and triggers to not check all the files or something like it.
I don't know if I made myself clear, I'll gladly converse about it if needed.
Edit. reading the comments it seems that this is in line with what @dleeftink had in mind as well.
@rzfzr - this is the same option I would consider myself as well; the only annoying part is where to put the generated links and output in the general case if the plugin automatically does the generation. Do I just append them in a "## Generated Links" section at the bottom of the page?
That would work for me, but it could be inline as well. Either way I'm sure that this would have to be a togglable feature, as many people must have tons of queries that would make the graph view un-renderable... But instead of being global in the settings it could be an opt-in inside the code block, for instance, default as is now: Lets say we add another triple-` descriptor like livelinks, that would inject the result of the query right below it while making its own block code not rendered, or rendered in one line just indicating that is a dataview: I believe it would be an elegant solution as in the reader's view there wouldn't be any difference to notice.
The only possible problem I see when re-rendering the query as the user will be able to edit the 'live' results... So even with complex caching, it would be hard to know what was generated, in order to know what must be replaced.
There could be a second closing block/inline code to limit the generated space: Let's say the user deletes the second block, we could warn him, not re-rendering until the block is placed, and once it's placed every line between these two is far game for replacing.
I haven't messed with plugin development but I'm willing to get started, let's discuss some more though, there must be a better solution, the second block is not that elegant, what do you think?
@blacksmithgu or anybody else has any suggestions on the topic so that I could start implementing it?
Keeping an eye on this as interested in any solution.
Very interested in this, has there been any progress on this so far, beyond discussion?
Very interested in this, has there been any progress on this so far, beyond discussion?
See #42; the backup mechanism (which converts dataview queries into plain markdown isnide the page) will also provide graph discoverability.
I am just here to show support for this feature! That would be great to have!
Adding my support as well.
One way of doing this would be to have query files that you can schedule that generates the result outside of the codeblock.
Example: queryexample.md
---
type: dataviewquery
---
TABLE WITHOUT ID
file.link AS Note,
filter(file.etags, (x) => !contains(x, "#idea")) AS "Tags"
FROM #idea
SORT file.mtime DESC
MyIdeas.md
---
type: MOC
---
´´´dataviewschedule
USE queryexample EVERY hour %% Executes every hour, on the hour %%
´´´
Variant:
´´´dataviewschedule
USE queryexample EVERY (day + (hour * 2)) %% Executes 2 AM every day %%
´´´
´´´dataviewschedule
USE queryexample EVERY day * 2 %% Executes every other day from STARTING or from start of year %%
STARTING 2022-10-13
´´´
Result would be in the form of: %% scheduled-dataview-start: queryexample %% Generated code %% scheduled-dataview-end: queryexample %%
That way you can find the generated part and remove or update it.
USE queryexample AS "Example Query"
Would generate: %% scheduled-dataview-start: Example Query %%
Advantages of doing it this way would be: You can do any query you normally do without changing them. You can reuse the query as templates. You don't have to save any duplicate query. You can expand how you schedule without having to change the query. Would not produce noise.
Finally I want to say thanks for a wonderful and impressive plugin that has changed how we use Obsidian profoundly. <3
If anyone has seen the discussion on 42, this is halfway there since there are new markdown rendering methods. You could write your own plugin/templater script to already achieve this.
I've ended up in the same rabbit hole as everyone else it seems, trying to get the dataview results into the graph.
Here's a crude Templater javascript that I use to solve this for any dataview block. (Inspired from the stuff in 42)
Materialize Dataview.md
<% tp.user.materializeDataview(tp) %>
materializeDataview.js
/**
* Take selected dataview and insert a comment with materialized data
* @param tp
*/
async function materializeDataview(tp) {
const editor = app.workspace.activeLeaf.view.editor;
var delim = "%%\n";
// Get current selection. Either entire dataview block, or just the dataview query (TABLE FROM ...)
const selection = editor.getSelection();
var query = selection;
if (selection.startsWith('```dataview')) {
query = selection.replace('```dataview', '').replace('```', '');
} else {
delim = '';
}
const dv = app.plugins.plugins["dataview"].api;
const data = await dv.tryQueryMarkdown(query);
// Replace selection with: selection + materialized data comment
return selection + "\n" + delim + "materialized-dataview\n" + data + delim;
}
module.exports = materializeDataview;
Basically, just select an entire dataview block or just a dataview query and insert the template. The original selection will be left intact, but after it a comment block will be inserted containing the current markdown result. Feel free to use it if it helps. 😃
Was originally planning on making it easily refreshable using a button or something, but this is the point where my patience ran out. If you want to refresh the data, just manually delete the comment block and run it again.
Perhaps add an INDEX
or MOC
query type that actually generates links?
For instance, most physical folders in my vault have a MoC in them (with the same name as the folder they're in) and I usually have some dataview query in them for Easy Navigation™ but that means that the links don't show up in the Graph. I'm pretty glad to see that it's not just my use case that makes this a Good Thing™.
My contribution is that the INDEX
query functions much like a LIST
, but the linked notes are actually shown as links in the Graph View. Furthermore, notes with the metadata field index: true
(or moc: true
) are treated specially. Namely, each file should have a parent
field (needn't contain only one parent); if a file's single parent
is pointed at a file with index: true
, that (child) file will be displayed under (as a child of) the index
. Multiple parent
s and and non-index
parent
s are ignored. The most important thing is that either parent
age acts as a link to the index
in the Graph view or INDEX
queries produce actual links that show up in the graph view. Either one works, but I would imagine that the first is easier to implement.
Hi, this would still be an extremely useful feature to have in Dataview, but since development for Datacore is already underway, is this something that could be implemented in Datacore from the get go? @blacksmithgu
Thanks for all your work in this amazing plugin
Re: materialising views, something akin to freezing MIDI tracks in Ableton Live might be worthwhile, e.g. bouncing the results in place and freezing the initial query/settings. This way, users could run a "refreeze" command that executes the query once more while updating the frozen results. This may prevent extensive recalculation, and would suit my use case where I would only need to update the graph once in a while (and might actually be preferable, as this also paves the way for modular writing approaches where frozen query results can be reviewed and edited in place as pure markdown, while the initial query still exists somewhere in a frozen codeblock, YAML field or elsewhere).
Perhaps some syntax like:
%% \```dataview
LIST WITHOUT ID "[[" + file.name + "|" + name + "]]"
FROM "philo" OR #philo
WHERE name != [[]].name
\``` BEGIN DATAVIEW RESULTS %%
- [[philo-edu|Philosophy of Education]]
- [[epistem|Epistemology]]
- [[Utilitarianism|Utilitarianism]]
%% END DATAVIEW RESULTS %%
Those are some actual results from my vault btw
Anything between the BEGIN and END would updated each time the vault's queries are re-ran. The most obvious issue is visually delineating the dataview results from the rest of the contents.
Any thoughts?
I didn't notice this FR till now. Perhaps this plugin will help some people: https://github.com/natefrisch01/Graph-Link-Types.
"Add metadata with internal links to your notes using Dataview's syntax. Graph Link Types will render these links as text in the graph view."
Let me know what you think!
I've created a plugin to serialize Dataview queries: https://github.com/dsebastien/obsidian-dataview-serializer
Here's an example from one of my Maps of Content:
<!-- QueryToSerialize: LIST FROM #luck WHERE public_note = true SORT file.name ASC -->
<!-- SerializedQuery: LIST FROM #luck WHERE public_note = true SORT file.name ASC -->
- [[30 Areas/32 Literature notes/32.04 Expressions/Audaces fortuna juvat.md|Audaces fortuna juvat]]
- [[30 Areas/32 Literature notes/32.05 Quotes/Choice, not chance, determines your destiny.md|Choice, not chance, determines your destiny]]
- [[30 Areas/33 Permanent notes/33.02 Content/Engineer serendipity.md|Engineer serendipity]]
- [[30 Areas/32 Literature notes/32.05 Quotes/Give yourself a lot of shots to get lucky.md|Give yourself a lot of shots to get lucky]]
- [[30 Areas/32 Literature notes/32.02 Content/Glücksshuld.md|Glücksshuld]]
- [[30 Areas/33 Permanent notes/33.02 Content/Invest in your relationship capital.md|Invest in your relationship capital]]
- [[30 Areas/32 Literature notes/32.05 Quotes/It’s a lot easier to say all successful people got lucky than it is to admit you have no ability to delay gratification, handle rejection, or think for yourself.md|It’s a lot easier to say all successful people got lucky than it is to admit you have no ability to delay gratification, handle rejection, or think for yourself]]
- [[30 Areas/32 Literature notes/32.05 Quotes/La fortune sourit aux audacieux.md|La fortune sourit aux audacieux]]
- [[30 Areas/32 Literature notes/32.05 Quotes/Life, I've found, works the following way. Daily, you're presented with many small and surprising opportunities. Sometimes you seize one that takes you to the top. Most, though, if valuable at all, take you only a little way.md|Life, I've found, works the following way. Daily, you're presented with many small and surprising opportunities. Sometimes you seize one that takes you to the top. Most, though, if valuable at all, take you only a little way]]
- [[30 Areas/32 Literature notes/32.05 Quotes/Luck is what happens when preparation meets opportunity.md|Luck is what happens when preparation meets opportunity]]
- [[30 Areas/32 Literature notes/32.05 Quotes/Luck isn’t an independent variable but increases super-linearly with more surface area—you meet more people, make more connections between new ideas, learn patterns, etc.md|Luck isn’t an independent variable but increases super-linearly with more surface area—you meet more people, make more connections between new ideas, learn patterns, etc]]
- [[30 Areas/33 Permanent notes/33.02 Content/Luck surface area.md|Luck surface area]]
- [[30 Areas/32 Literature notes/32.05 Quotes/Persistence beats timing. Execution beats luck. Not immediately, but eventually.md|Persistence beats timing. Execution beats luck. Not immediately, but eventually]]
<!-- SerializedQuery END -->
As you can see, the query in comment gets executed and the output is added to the note as Markdown.
Result online: https://notes.dsebastien.net/30+Areas/34+MOCs/Luck+(MoC)
The documentation is here: https://developassion.gitbook.io/obsidian-dataview-serializer
Note that you must be careful with Dataview queries that output tags, since those will be actual tags in the notes where the queries are located, which could lead to unexpected results.
Hi!
It is possible to make the list of elements displayed by the plugin to be recognized by Obsidian as output links? In other words, that they can be understood as links that are displayed in the note in which the query is executed [[Note A]] --> [[Element 1]]; [[Note A]] --> [[Element 2]].
I don't know, if it makes sense.
What I am looking for is that in the Graph View you can notice the links that the plugin organizes and generates.
Thanks in advance.