Generate explicit hierarchy out of properties

I’m not sure I fully grasp what is happening even with the example below.
Could you perhaps elaborate for my understanding?
It looks very cool though!

The system doesn’t know the meaning of each property, thus it needs some help in interpreting the desired direction of the tree. If using the inverse direction:

{{pagetree-from children}}
{{pagetree-to parent}}

the result looks kind of upside-down and not much of a tree:


Fortunately the issue is immediately visible and the remedy is simply swapping from / to.

1 Like

So it uses the values in the parent (or children) property to infer relations and put those in a tree?
Grandfather point to parent points to child for example?

By definition, a tree data-structure is one where all the nodes possess the same directional relationship to one or more other nodes, but with different value. So the algorithm for to simply follows the value of the specific property from one node to the other (grandparent -> parent -> child) and paints the path until its edges (which have no value), while the algorithm for from searches for inverse pointers (grandparent <- parent <- child). Therefore, in each case should pick the respective algorithm based on what type of pointers are available in the model.

2 Likes

Thanks! Now it makes sense :smiley:
I use pages which are tagged with either projects/areas/references/archive. All pages under those will then have for example project:: page linking to a page with tags:: projects.

So maybe by adding project:: projects I can use this for a project hierarchy overview.

  • Projects
    • project A
      • subpage of A
    • project B
      • subpage of B

And if I really want to change things up I could use a more general property to make a complete hierarchy overview.

  • Projects
    • project A
    • etc.
  • Areas
    • area B
    • etc.

This makes me excited :smiley: thank you!

This is interesting. Just as I was struggling to get a handle on Namespaces you presented this solution which makes Namespaces redundant. It comes at the right time as I have read most of a book that I have made notes on and that are subdivided into chapters.

I amended my config.edn and custom.css files, and created a custom.js file, then in a page pasted {{pagetree-to children}}, but no tree was rendered.

In the parent page I have this:

image

and the properties block of each child looks like this:

image

Could it be that the icon somehow causes a blockage, but I deleted it in 1 page thinking I would get a tree with the parent and 1 child, but nothing is rendered.

If the used property is parent::, then the macro should be {{pagetree-from parent}} (this is under deprecation, but it is valid at the time of this writing).

I clarified my text above slightly: the narrow screenshot with children is of the parent page — you probably realized that, but I just want to make sure.

I changed the macro to {{pagetree-from parent}} but I still don’t get anything.

This is what I have in the config.edn:

 ;; added by PB from https://discuss.logseq.com/t/generate-explicit-hierarchy-out-of-properties/20635
:macros {:pagetree-from "[:div {:class pagetree, :data-treedirection from, :data-treeprop $1}]"
:pagetree-to "[:div {:class pagetree, :data-treedirection to, :data-treeprop $1}]"
}
  • Each property is independent, and so are the respective trees.
    • As humans we understand some properties to be complimentary to each other, but the system doesn’t.
  • Your config.edn looks ok.
  • Your example works for me, so there has to be some difference.
    • If there is some text Tree...: but no tree below, the issue is probably with the position of the properties.
    • If there is no output at all, should Ctrl + Shift + i to check for any clues in the console.
  • Your other option is to create a new (empty) graph and start adding minimal info, checking the result of the macro as you go, until you find which change breaks it.
  • Also make sure that:
    • your app is up-to-date
    • you have restarted Logseq after adding custom.js
    • you have answered positively to the question about allowing custom.js to be executed

Success!! The problem was that I had copy/pasted only part of the custom.js. Copy/pasting the full code and restarting Logseq did the trick.
Note that it is actually {{pagetree-to children}} that works.

3 follow-up questions:

  • in the tree there is also my Templates page, which has nothing to do with the book I am reading, Yahweh to Zion.
    image

Looking at the templates page, there is this template:

image
Could be because of children:: that the Templates page is included in the book’s tree? If so, how could I avoid the Templates inclusion?

  • All children are sorted alphabetically, which is not the order of the book, even though on the parent page the children are shown in the order of the book. How can I get that sort order in the tree too?

  • Am I right when I say that for each book I read/project I am engaged in, I can put {{pagetree-to children}} on the parent page to get a tree for each book/project?

The current code is light and generic, so none of the features that you ask has a positive answer at this time. But thank you for your feedback, this is what I am looking for. I will have to go through each one of the features and consider supporting it.

OK, clear. What there is, is already interesting. I love the fact that I can stay away from Namespaces — perhaps that is being narrow-minded, whatever — because I feel that if they are not used properly, they will sooner or later cause hassles/problems.

I’ll await the next stage, patiently :grinning:

BTW, I don’t know if you saw, but I advertised your system here.

1 Like

Big update, check the changelog.

Is it possible to use more than one property i.e. once the first hierarchy is evaluated, add more children by looking at the next property?

The algorithm can support endless combinations, but its input is currently limited by the syntax of macros. I don’t want to support a few scenarios and leave others out. If you have any idea for a generic-enough syntax, please share it. Meanwhile, you can get some results by editing the queries directly.

2 Likes

@alex Actually, could you provide something more specific as an example? I have come with some design and would like to ensure that it covers your case before implementing it.

@mentaloid sure, check this mockup for the query builder:

So something like {{pagetree from, nationality, author}} to create that hierarchy.

In my opinion this should be a feature of queries but I was curious if it was possible here too.

1 Like

I wish somebody could make a video about how to utilize it for some complex hierarchy topics.

I looked at the mockup:

  • There you propose a single filter-sort-group query, which:
    • is a bottom-up approach (hierarchy-wise)
    • has no surprises (thus no discoveries either)
    • operates like this:
      • extracts some items (there books)
      • imposes some structure on them, which is:
        • regular
          • in position: properties have fixed layers
            • top nationality, bottom authorship, birthday on authors only
          • in participation: e.g. a nation without books doesn’t appear
        • limited
          • in size: the exact number of layers is predefined
          • in info: the reader should already know what each layer represents
  • This is not a genuine tree.
    • unless if we abstract nationality and authorship to e.g. origin
      • but then more results may appear and of less rigid structure
  • In contrast, a genuine tree:
    • is a top-down approach (hierarchy-wise)
    • operates like this:
      • begins from some root
      • spreads out in irregular forms

In my approach I implement a generalized graph traversal (like you said on this occasion), fed on every step by multiple predefined parameterized queries, operating on a level above them, to provide an unlimited partial structure of the graph itself, potentially discovering emerged relationships (e.g. “items authored after the birth of nationalities”, which may be books, but not strictly). Therefore, this is more than a tree, it is a cascade. It should still be possible to cover your scenario, but should:

  • define some queries that are more targeted, in order to avoid unwanted results
  • implement some syntax that needs parsing, e.g.:
    {{pagecascade top strict-from nationality ; flat strict-from nationality ; flat strict-from author }}

I’m looking into it.

2 Likes

If you share some complex hierarchy topic, I may prepare some guide.