Enhance Graph View with a Tree Layout

I don’t know if this complicates coding of this feature, but we can use fuzzy concept/logic to derive different connection manner. This way we don’t need to command everything nor leave Anytype to control everything, but this might be processing heavy.

If we are managing one specific relation, we can instruct Object A to be position somewhere to the left or negative axis location to Object B, then we have certain degree of control but allow Anytype to finalise the display-ability, so there will be less overlapping.
(P.S. Graph display still needs to be improved: clustering is still a big hindrance)

If we are managing relation in general, we can instruct hierarchy indicating relation to always put siblings on the left/right side, controlling hierarchy but then let another connection logic to determine the location of each branch.

  • For example, different work teams all work under the head of department, but teams are equally important to be layout side to side. In a more specific scenario, many teams are formed in different period of time. First formed team is supposed to be the oldest and be positioned on the left, followed by younger teams/siblings to the right. This can be determined by a number relation with a multi-dimension relation for sibling. This way unless (full) instruction is given, the layout is open and dynamic.
  • When dealing with larger amount of objects, changing the nature of relation helps batch edition for each connection between two objects.
    – And if we have too many siblings that overflow the screen width, then it is possible to display a 2nd or more layer(s) within the same area, and ask children objects to be located further down to lower area with longer connection line.

Then we still need to consider how to implement fuzzy logic with codeless design.. :sweat_smile::flexed_biceps:

This is not true TBH, imagine a bush where there are multiple root objects. I actually wanted to implement such logic for the list view of a widget to remove it completely but it’s a bit complicated in the current system. But it can work, there can be multiple root objects.

I dare to disagree.
Perplexity says this:
… … …
In a classic tree diagram (as used to represent random experiments or hierarchical structures), each element has exactly one parent element with the exception of the topmost element (the root). The tree diagram thus represents a strictly hierarchical structure in which branches only run from an initial node to several subordinate nodes, but never lead several superior nodes to a subordinate one.

If an element had more than one parent element, it would no longer be a tree, but a so-called directed acyclic diagram (DAG) or generally a graph, as trees by definition do not contain nodes with two parent nodes. In a tree diagram, it is therefore not possible for a node to have more than one direct connection “upwards”.

In short:
An element in a tree diagram cannot have more than one parent element - this is an essential feature of the classic tree structure concept.
… … …

According to this text, only the root dances out of the line, because it has no parent. Nothing else dances out of the line, each element has exactly one parent.

But do we really have a root?
In my own case, my old startpage (that once was the root of all) is meaningless.

If a Space has only four Objects and each of them links to each other - which one is supposed to the “the root”?
One could say, each of these four Objects is a root. But could a diagram of them be called a “tree”?

It’s not tree, it’s a DAG indeed. I mean that in the widget sense you can have a list of multiple roots and then toggle them each individually as a tree.

This may work in some cases, but I highly doubt that this would work in all cases. – I even believe in most of the real cases it wouldn’t.
Problematic are loops or rings (not sure about the correct terminology):
An element deep down in the “tree” could loop back to a higher position (and, at the same time, have other elements below itself).

A simple example:

  • “A” is root (although I doubt that we really have something like a root at all, btw.)
  • A has B and C below itself (B and C are parallel)
  • B and C have one shared child “D” (D has two parents).
  • D has a tree structure below itself, but D loops also back to A.

This was a very simple example, but absolutely realistic.
Although we have here a clear root (even only exact one root) we run here in a problem because of that loop in parallel to the tree structure below D.
If you speak about “in a widget sense”: how would you display such a structure in a widget?

An even much simpler example:
A Space has only three Objects:

  • A links to B
  • B links to C
  • C links to A

– In that example, there is no clear root, but we have a tiny loop. The structure looks like a triangle.
How would you deal with such a thing in a widget? There does the “tree” end?

In my understanding, our main problem is the term “tree”. We should get rid of that.
All of my given examples in this and my earlier posts have nothing to do with a “tree” structure.
In some cases it may be true that a restricted part of the structure can look like a tree structure. But the problem is, that it is only so if we blend out such problematic “details” like loops.
But this would be like closing the eyes to blend the reality out.
What’s the use of a widget that doesn’t show the real situation, but only a part of it?

What really shows the truth, is our Graph!
It shows the things like they really are: the linked Objects built an organic structure.
And an organic structure can in principle be much more complex then a tree structure ever could.

@AnyReport requested a tree structure, but this can never truly work.
In my understanding, what he really wishes, is to get a better overview over our real structure (no matter how the structure is named: “tree” or “organic” or anything else). He simply doesn’t like the dynamic and organic representation.
Later he asked for free positioning of ALL Objects, to make the structure look like he wants.
– I understand the wish, but for me it’s absolutely clear that he (nor anyone else) wouldn’t become happy with that. Free positioning makes simply too much work all the time if the Graph grows and morphs.

If we think only about the Graph and how to improve it, then I have a clear favorite:
Give the user the freedom to position & fix at least the Collections. (Or everything that has more then one outgoing link)
Everything that isn’t fixed manually floats & positions itself dynamically, like we all know it.
I would call such a half freedom and half automatic attempt a modern one.
It’s like an airplane with an auto-pilot. The pilot isn’t forced to sit on the steer all the time. But if he decides to use the steer, it has a higher priority then the automatism.

I agree, just gave an example on how it could work. Yes loops are the problem, in the widget I have a protection against recursive nesting.

I personally dont like it when objects are linked multiple times because it clutters the graph view. I always try to to keep a simple folder hierarchy to keep everything organized and good looking on the graph. I would love to have every object fixated more than anything else. Keep in mind I only have to do this once per object. So every time I open the graph view I know exactly where this object is. Exactly where I left it. I think many would love to have a consistent organized graph view like this. But yeah for the time being I just use Freeplane where I have my tree / org charts and just offline link my objects.

Nope, sorry, but you think wrong.
It’s 1000 times more likely, that you - like every other user - add some objects, delete some Objects, duplicate some Objects …
Same with Collections, you will add, delete, duplicate Collections.

The Graph is morphing, every day a bit, and sometimes even a lot.
Our dynamical Graph reflects that. It rearranges everything dynamically.
But I’m with you if you complain that our Graph does it much too frequently and much too radical!
It would be fine if it would store it’s rough shape.
Nailing the collections at fixed points would do that job within a few minutes.


But let me bring another example why I believe you wouldn’t be happy with “nailing” every single Object:
How do you comb your hair?

  1. Do you somehow handle each single hair, one by one?
  2. Or do you roughly style your haircut into the desired form, trusting that everyone recognizes you, although not every hair is exactly on the same spot as it was yesterday?

In addition to object filters, maybe we are also talking about filters by relation. This way we reduce the excessive edges which are irrelevant to context.

  • For example, when we are looking at research papers and concepts, we probably don’t need to see the relations (e.g. family members) created for their authors’ biography..

Maybe we are also talking two different layers of saving graph.

  1. Save by criteria which allows a re-calculation of graph if relations had been updated (more like @Code-Jack’s approach)
  2. Save as picture/final state which pulls information exactly when users last used it (more like @AnyReport’s approach)

Both methods served different purposes, for notes to catch up with life and changes vs. for notes to be published.

Filtering for Object Type can do this job.
In addition, a filter for Tags would (for me) do an excellent filtering job.
Related to your example: My family members already have the Tag “Familiy”, while research papers have a Tag like “research” (or similar).

But the kind of the filtering has nothing to do with the kind of the structure (tree vs. organic, etc.) about we speak in this thread.
It’s clear that the Graph still has a lot potential for diverse improvements.

Maybe I didn’t explain its relevancy enough. Let’s try again with a more detailed elaboration.

Let’s say I am doing an analysis on the development of psychoanalysis.

  • Sigmund Freud and Psychoanalysis are at the top of the tree
  • Followed by Anna Freud focusing on Child psychoanalysis.
  • Anna Freud is a child of Sigmund Freud, which in itself is a family tree; however, in terms of analysing the psychology field, this family linkage is less relevant; hence hiding this relationship would make most senes.
    –This type of bidirectional connections between two objects cannot be replaced by tags. And If we need tag filter, then we are doing filter for properties, which also includes relation.

The reason why tree seems to be impossible with thousands of objects is connections can expand until the end of the world and thus it is likely to have loops. However, we can limit the context to create a viable tree.

  • This means we are either only introducing relevant information/connection, or that we have to filter out irrelevant information.
  • E.g. An employees graph doesn’t need to include all their working projects, but maybe their most valuable project.
  • Just like local graph, we can have depths for tree layout. If we tell graph not to retrieve information beyond certain levels of depth, then we can reduce the likelihood of massive loops.

Fun fact: Weeping trees have branches that grow downward back to the ground. So technically speaking loops are fine, we can simply illustrate loops exist with a line. We can have branches that grown in different direction, as long as we identify the seed aka the main object and the direction of branches aka the following child objects.

  • Unlike widget, graph is not a linear representation, thus we won’t need to generate infinite information to represent the existence of a loop.

As for saving graph, the reason why it matters for tree layout is that we can be using the same structure for different graphs, if tree are calculated.

  • Graph of staff team A is probably very similar to team B.
  • As long as we identify the top team leader, we can identify the hierarchy by its relation and thus allocate team leaders on top of team members (from its bidirectional linkage), following by all sub-teams.
  • Even for manual allocation, we can duplicate the graph and use the formed tree as template to produce the same structure, reducing the efforts to create another tree.

I can’t see that anything you wrote changes anything about the fact that it is impossible to show the whole Graph as a tree.

In that moment when a loop occurs, it’s no longer a tree.

With some additional filters we would have more possibilities to display our data, yes. But then, the Graph does no longer show everything. It blends out some content.

If you blend out enough information that loops are avoided (although they are still there, they are simply not displayed), you may be able to show parts of the whole Graph as a tree, or as multiple trees. But that wouldn’t show the full truth.

And if you’re interested for a research only in psychoanalyses, a filter for that Tag would do the job (if the Graph would support filtering for Tags).
In the result, the Graph would show only Objects that have this Tag.
It would make sense, if there are connections that built a loop, that the Graph shows it (including loops). But if there are loops and/or multi-parent connections, then it would still be an organic structure, not a tree.

I share the wish for more filter options in the Graph.
And I share especially the wish for more then one-dimensional Tags!
In fact, I wish we could have “tree-Tags”!
Example:
The main Tag is “Plants”.
And “Plants” could have the child-Tags “herbs”, “flowers”, “bushes” …

This way, if we filter for the Tag “flowers”, we would see only the flowers.
But if we filter for the Tag “Plants”, we would see all the herbs, all the flowers, all the bushes, and so on.

The Tags should have the option for a tree-like structure. And the Graph should have corresponding filters.
But if Objects are connected in loops, or if they have multi-parents, it’s still an organic struture, not a tree.

We already have this feature. If I close the graph and reopen it at a later time after I added new stuff like new collections, duplicated, object etc all those objects can still keep their positions. The new stuff will be floating around somwhere on the graph and shows the connection. The graph is basically an unlimited canva. There is always enough room so your pinned object will remain at the position where you left them and put the new stuff somewhere else.

Its still possible. I already proved that by creating a tree layout in the actual graph view without deleting any objects. The loops are included and you can see the tree layout despite all the other connections that are not part of the tree layout. Just to make sure all loops, and connections are included.

You could then blend out all the connections to show only the true tree layout, and the loops and connections can be shown when hovering over an object for example.

The fact that the graph view doesnt save your changes doesnt make much sense to me. Are we really supposed to rearrange all objects every single time we open the graph view? Why? Its such a repetitive unthankful task if it doesnt save the changes.

No matter what the purpose is why we can rearrange the objects on the graph view and to give them a fixed position, it doesnt have much value when it gets resets every single time you close it.

Just save the changes please.

It’s not possible and you didn’t prove anything.
You’re somehow on the wrong ship. You call something a “tree” that definitely is NOT a tree in the sense of a network topology or the graph theory.
A TREE CAN NOT HAVE LOOPS!

If a topology contains loops, then it’s another topology then a tree.

In network topology are eight basic network topologies known for us humans on planet earth:

  1. point-to-point
  2. bus
  3. star
  4. ring or circular
  5. mesh
  6. tree
  7. hybrid
  8. daisy chain.

If you want to know what a tree is, vs. what NOT a tree is, look here:

In addition, you can also look for “graph theory” in the internet (the wiki article about that topic isn’t good, unfortunately).

Whatever you have “proved” by creating a structure in your graph, wasn’t a tree, because it contains loops.
Simply give the child another name. The name “tree” is already given to a certain structure - a structure without loops, where each child has only one parent. Only such a structure can be called a tree.

Let’s start with something simple.

Multiple parents should not be an issue in tree layout because in family tree, we already have 2 parents to a child object, and we can also have step-parents and adopted parents. As long as a line linking the between the parent and child object in vertical position, parent-child relationship can be illustrated.


As for tree layout

Why should we fixate on the term “tree” with its scope being computing language and its shape?

  • A tree is not defined by its branches, but its seed, trunk and its growing direction. If a tree only grows one branch from its one trunk, it is still a tree; if a tree has many branches, then it is also a tree. If a tree’s branch grows back into the origin, like weeping tree, then it is also a tree.
  • The main characteristic of tree layout is its vertical arrangement. Parent object locates on top and child object locates in a lower position. (Or horizontal arrangements, if we are referring to horizontal tree like Gantt chart)
    – This vertical arrangement occurs from an assigned definition of Y-axis. Family tree respects a generation line; a company map is defined by staff’s position and power. (and Gantt chart respects time.) This definition of Y-axis instructs why any object should and should not take the top position of the tree.
    – In graph, we can create define nodes’ position on Y-axis through any properties involving numbers/time/sequences, and/or inferred hierarchy through relations (Obsidian plugin - Excalibrain’s approach - which I sincerely suggest trying out). In Anytype, we can assign definition on graph, or wherever FR Creation of Relations from scratch is going to take place.
  • Once we set a priority for different governing force of the graph (vertical position as first priority in tree layout), other rules have to set aside for the prior rule. This way loops and their nodes are forced to take a “non-organic” position.
    – For example, if a primary teacher has lots of student, then one of the student is very intelligent and well-educated and become a professor, and later one day the primary teacher took the professor’s course - taking the role of a student to the professor, now we have a “loop”. (Strictly speaking, this is not a loop, instead this is two roles of the same person locating in two different trees).
    – Yet this loop is not definitively relevant. For the primary school tree, only the teacher-student relationship is relevant; for the university tree, only the professor-student relationship is relevant. For a person’s growth, we can assign the individual on top.
    – That’s why graph filter matters. We have to eliminate nodes which are not relevant to the context / Y-axis. Or else we have lot of noises in the graph, making a graph meaningless, hence the nodes cannot take shape and thus there seems to be no tree.
  • Just to clarify, graph is not a widget. Loops, Möbius strips and even wormholes are mathematically and graphically possible to be represented. Since we are not on the loop or strip itself (linear representation), we are forming a 2D or more representation for the loop and we are demonstrating the shape of the loop, recursive nesting / infinitive rendering won’t be happening.

The ultimate goal of feature request is to empower users with non-centre spreading arrangements of nodes. No matter how much we agree or disagree on the definition of tree, this needs still exist because we live in a world with certain degree of order, not just chaos/organic.
– These days organic food also needs to comply to rules and regulations.. even if regulations can be excessively meaningless.


Onto the most furious side of this discussion: whole graph as tree

In nature, we have not just apple tree or weeping tree.. We also have mangrove tree/forest. Mangrove tree’s seedings germinate with its connection to its parent tree. The seed move from a position from above the ground, then into the ground, and then upward into a tree. As mangrove reproduces, a tree becomes a forest.

  • Each mangrove tree lives under its own circumstances.

In graph, as long as we can define what it means by one group of objects, we can establish a “tree” with however shape it organically takes.

  • Collection would indeed be a good definition of a single tree.

If we need to demonstrate multiple positions, we can use other shapes of lines in addition to straight lines. We can use angled line (e.g. the shape of ᴎ), or curvature to represent its change of hierarchy and even shows 2+ copies of the same node (e.g. fully coloured nodes and partially coloured nodes) to demonstrate its child and its parent positions in the 2+ respective trees.


Additional information to above posts

Hiding a line/edge is different to hiding an object. With typical plants, we can pick up the seed from Plant A and walk across the whole world and pick a random spot to plant a new Plant B.

  • Plant A is the parent of Plant B
  • However, many times we don’t know need to know this relationship. We only see them as individual Plant, yet the seed and its parent plant is biological and genetically linked.

We cannot use tag filter on object to hide the connection line, because we still need to show both Plant A and Plant B. Unless we are going to give add tag system onto the relation system as well, or we are going to have relation as object, where users can write/edit the properties of relation.

I’m tired of this discussion.

Only that:
A family tree is not a “tree” in the sense of network topology – no matter if the sentence has the word “tree” in it.
A structure where a child has more then one parent (like in a family tree) is not a tree in the sense of a tree diagram in the context of a network topology.

Also the examples from biology, where branches can grow together under certain circumstances, have nothing to do with the definition of a tree diagram.
– Not everything that has the word “tree” in it, has something to do with a tree diagram.
We speak here about topology, not about biology.

And it’s clear, that the more you filter the Graph to eliminate things like loops, the more can the remaining Graph look like a tree diagram.
But this works only because you have applied filters that eliminate the loops and the multi-parents.
But it’s not possible to show the whole unfiltered Graph as a single tree!

Even a forest is another topology then a tree – it’s multiple trees. But these trees are still only then true trees if they don’t have loops and no object has more then exactly one parent.

For me it’s absolutely OK if all of you would call the thing that you really mean a “tree-like structure”.
– Such a structure has similarities with a tree diagram, but it isn’t truly one.
But if you call it a “tree”, then you use the wrong term because the structures in Anytype are more complex – too complex for a classic tree diagram.

But we are arguing about the emperor’s beard here. I’m tired of that.
I understand what the thread starter really wishes: he wishes an alternative way to display the Graph in a more “tree-like structure”.
This could be possible I believe. Even with multi-parents and loops.
But such a structure would be only “tree-like”; it can’t be called a “tree” in the sense of a tree diagram.

I doubt that I will further participate in this discussion.

Reviving this topic because I brought it up in the town hall (thanks again, team, for hosting those! Amazing!), and @anton said I should elaborate on my use case.

I’m using AT for task lists, charting dependencies via a hierarchy of links/backlinks. As it stands, the only way to see such a chain is via the sidebar, where a pinned object is displayed with an expandable link-tree underneath it. This serves the purpose in a very basic way but could be better as a visualization tool. The Graph view has the potential to provide what I’m looking for because it’s more thorough and graphical. But it currently is often unreadable due to overlapping objects, labels, and lines; and it’s difficult to keep track of or manage due to constant auto-rearrangement.

In the posts above, there have been suggestions ranging from a fully rectilinear tree view (the OP) to tweaks like being able to anchor specific objects and let only the others auto-rearrange. I want the former, but anything along the lines of the latter would also be an improvement.

@Code-Jack seemed to be saying that the OP’s request is basically impossible because loops exist and there’s no inherent root object. This mystifies me, because the concept is currently implemented in the sidebar under every pinned object that has links. I just want that in graph form. Loops are represented by duplicating single objects, and infinite series are obscured via collapsed branches that can be revealed only manually, one object at a time. (Alternately, I like the family-tree idea that @C.c suggested here if it can be pulled off, but I could imagine that just re-creating something like the current situation.)

I’ve previously written a more detailed breakdown of my use-case, pros and cons, etc. I could copy-paste some of that material here if it’s desired.

Thank you!

[EDIT:] If I’m understanding correctly, one of @Code-Jack’s other objections was that a tree wouldn’t necessarily be able to show all objects. I don’t see why all objects need to be shown. As in the sidebar, the act of designating any object the root of a tree would inherently exclude any objects not downstream of it. It’s basically a kind of filter, “children of object X”. Given that the Graph view already has filters, I don’t see the problem in adding another. (The conceptual problem, anyway. Obviously technical problems are another matter entirely, and I’m not a programmer so I have no idea what I’m really asking for in that regard.)

I have been thinking about this for many many many times. I played with the pinned widget in the sidebar. When there was a loop, the tree just expanded infinitely after each click. I think this is a good approach which can also be brought to collections.

@lester1027, what do you mean about bringing the approach to collections? If you mean in the sidebar, i.e., a pinned collection would have a link-tree underneath it that includes children of the collected objects, there’s a trick I use to achieve this: Give the collection a backlink to a non-collection object, then pin that object instead of the collection.

On the other hand, if you mean you’d like to be able to see the expandable tree when you open the collection, i.e., in the Grid/Gallter/List/etc. view, then I agree that that would be a great addition!

In fact, that could actually be where the “tree layout” idea is implemented: When you use graph view inside a collection, the collection would be the natural root of the tree, and all of its children and sub-children could be displayed in a sensible tree like the OP’s mockup. I just tried this with a query that filtered for a set of objects that were in a heirarchical link-chain, and I manually arranged them into something like the OP without much effort. But when I exited the query and then reopened it, the graph had rearranged itself to its original chaotic layout. So close!

This feature request has been added to our tracker and received by our product team.