Graph Link Types

Summary

Graph Link Types is a plugin for Obsidian.md that enhances the graph-view by rendering link types dynamically. This plugin leverages the Dataview API and PIXI.js to create a more informative and interactive graph experience. By displaying the types of links between notes, it provides a clearer understanding of the relationships within your Obsidian vault.

If you enjoy using GraphLinkTypes and want to support its development, consider buying me a coffee! Your support helps in maintaining the project and exploring new ideas in community-driven coding.

drawing

Sample Vault Display

GraphLinkTypeDemo

Usage

To use the Graph Link Types plugin, ensure the Dataview plugin is installed in Obsidian. Then, simply 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.

In your note, add metadata like this:

---
related: [[Research Document]]
---

Or inline:

related:: [[Research Document]]

GraphLinkTypes will display “related” on the link in the graph view.

Features

  • Dynamically rendered link types in Obsidian’s graph view.
  • Custom text display for each link based on metadata.
  • Efficient updating and rendering using PIXI.js.

Development and Contributions

Interested in contributing to the development of GraphLinkTypes? Check out the Obsidian Sample Plugin for guidelines on how to develop a custom plugin for Obsidian.

Milestone Goals

Stay updated with progress and future plans by checking our Milestone Goals.

I hope this is useful for everyone - let me know if you have any suggestions, ideas, or demos!

12 Likes

Very interesting

1 Like

I forgot to add a link to the repo - for anyone interested
https://github.com/natefrisch01/Graph-Link-Types

1 Like

Fantastic idea! The reason that by directional links are king, is because they provide far more context than storing notes in the same folder or hitting notes with the same tags. Anything that allows us to access the context of links better is a major bonus. In my opinion.

2 Likes

This is really groundbreaking, I think. And it will fit into many people’s existing metadata / workflows easily, which is a big bonus.

2 Likes

I’ve really wanted something like this for a long time, thanks for making this!

1 Like

I really like the idea!

As some feedback I’d like to say that sometimes I want to use properties that shouldn’t show up as a graph link type text.

I have this suggestion to change the syntax a little:

---
property A: [[Research Document 1]]::related
property B: [[Research Document 2]]
---

In the same way, you could use this inline:

[[Research Document 1]]::related

Or, if you want to add blanks, you could write:

[[Felicitas]]::married to::

1 Like

If you want to add some stylization to the connections, this syntax could be handy:

[[Research Document]]::relate | thickness | color | attraction::

thickness is a value ranging from 1 to 100.
color is either a 6 digit hex number like FF5533 for a RGB color value, or a 8 digit hex number like 335522AB for a RGBA (Red, Green, Blue, Alpha/Transparency, ) color value. I omitted the usual #, since this would collide with the hashtag syntax.
attraction is a value ranging from -100 to 100. 0 means nothing changes with the distance of the connected nodes. 100 means maximum attraction between the nodes. -100 means maximum distance between the nodes.

thickness, color and attraction could be omitted from right to left.

Then you could insert the value of a property in the connection data, for example to affect the thickness of the line:

---
Oxytocin.increment: 15
---

Some text...

[[Serotonin]]::increases | 26::
[[Oxytocin]]::increases | {{Oxytocin.increment}}::

In a CSS file, you could specify how many pixels would correspond to a thickness value of 100.
And also how many pixels would ideally be the distance between nodes with an attraction value of -100 and 100, with no other forces applied.

Since I don’t have the time to contribute to GitHub, I just write my ideas here in the comments. :slight_smile:

1 Like

Wonderful thoughts. I’m just rewriting some of this so it’ll be clear to me if we implement this.

<MetadataTag>:: [[Research Document 1]]<GLT marker><DisplayName> | <Thickness> | <Color> | <Attraction>

I think we should use something besides :: for <GLT marker>, because in the inline notation I’m not sure what Dataview would do with it. could perhaps be |, ->, GLT, etc. or some combination of them. Also, by default I think it should still use <MetadataTag> as the display name, but make it an option in our list of tags to change it or make it nothing. Also, we should use identifiers so that you don’t have to include all the options if you don’t want to. I.e.
<DisplayName> could be DisplayName, "related" or DisplayName, ""

Some examples, assuming <GLT marker> is |:

property A:: [[Research Document 1]] | DisplayName, "related" | Thickness, 100 |
property B:: [[Research Document 2]] | DisplayName, "" | Color, FF5533 |
property C:: [[Research Document 2]] | Attraction, -93 |

Modification we’d have to make:
extractPathFromMarkdownLink() and extractPathFromWikiLink() should return, in addition to paths, all the arguments as a dict or something. Then those would argments would be returned from getMetadataKeyForLink() and used in createTextForLink() to implement the optional arguments.

These are some great ideas, thanks for taking the time to work out potential syntax for these features!

1 Like

Thanks, cool. :slight_smile:

Yes, I agree with your points.

I think -> would make the most sense aesthetically and intuitively for the inline notation.

[[Research Document]]->relate|70|

To make DisplayName nothing inline you could write:

[[Research Document]]->|70|

Sometimes I make a graph visualization where I need to have more than one connection between two nodes. Transparency could show this, but the connection labels should not overlap… Perhaps the DisplayNames could be separated with a / in the graph view?

If two notes have more than one connection, I think the applied attraction in the Graph View should be the average of the attraction values of both notes.


When I have some time, I’d like to try to implement my idea to display folders in the graph view:

Is there a way to access the graph view from a plugin? I didn’t find it in the documentation…

1 Like

A compressed notation might look like this:

[[Research Document]]->|||90|
  • DisplayName is set to nothing
  • Thickness gets its default value
  • Color gets its default value
  • Attraction is set to 90

You could define default values for the parameters of a DisplayName in the CSS file. If you omit a parameter in the graph link type parameter list, it would be set to its default value.

[[Research Document]]->supports|20||30|
  • DisplayName is set to “supports”
  • Thickness is set to 20
  • Color is set to the default color for the “supports” DisplayName from the CSS file
  • Attraction is set to 30

I think it is a bit difficult to see the affiliation of a DisplayName to a link in the graph view when a lot is displayed, since every text has the same appearance.

Therefore I suggest to write the DisplayNames of the graph type links in italics to make them more distinguishable from the node labels.

1 Like

Another great idea for showing multiple link types in one file that point to the same file. I made a feature request that I think captures what you’d want.

1 Like

Thanks! :pray: For the properties block, I’d suggest this approach if you want to have relate as the shown DisplayName:

---
relate: [[Research Document]]|Thickness|Color|Attraction|
---

If you want to set DisplayName to nothing, it could be:

---
relate: [[Research Document]]->|Thickness|Color|Attraction|
---

Then this would look the same way as in the inline notation for no displayed name.

1 Like

Displaying folders as a shaded area in the graph view would be awesome! “Is there a way to access the graph view from a plugin? I didn’t find it in the documentation…” Well, there is not much support by obsidian for accessing the graph view in plugins, and from what I gather, it is low on their priority list to make an API to access it. I think this is because it’s internally complicated. That being said, with enough patience, I was able to put together a manageable solution:

  1. Access the Pixi.js renderer for the graph view. findRenderer()
  2. Add children (extra things you want to draw, in my case text, in yours the shaded area) to the renderer. In createTextForLink() see renderer.px.stage.addChild(text).
  3. Transform the position of the object you created to match the coordinate system that obsidian uses. updateTextPosition()

What this means is, I think adding area shading for folders would be doable! The more difficult part, in my opinion, is figuring out how to group the nodes and writing their position, but again, I think this is doable. To do this, you need to edit the position of nodes that already exist, which to my knowledge, is pretty much the only thing we DO have access to thanks to (persistent-graph)[https://github.com/Sanqui/obsidian-persistent-graph/blob/master/main.ts]. See their restoreGraphData() function for how to do this. If anyone does know how to edit other existing objects, that would be incredibly helpful in adding new features to Graph Link Types as well, since we wouldn’t have to be drawing new objects over exisiting ones.

1 Like

If the internals of the graph view are that convoluted, maybe they could provide something like a wrapper with simple methods? Then they wouldn’t have to reorganize the code until they decide to do so…

1 Like

I suggested this as a feature request:

3 Likes

Hello there! This seems lovely and I want to use it but I can’t find you in the community plugins. How can I install this? I also tried searching your name but that didn’t work either :confused:

1 Like

Oh wow, I was just thinking last night that I could really use something like this in Obsidian and it was one of the capabilities I missed since switching from thebrain.

1 Like

Yeah, me too

& @NarraAtor Use the BRAT plugin to install it, since this is still a beta plugin.

2 Likes