Generate explicit hierarchy out of properties

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.

I don’t have particular topic in mind but I struggle to create some hierarchy of information, todos, ideas. Todo’s are connected to many ideas, ideas are connected to many todo’s.
For me complex hierarchy issue is when I try to manage my todo’s. I have different areas of interest like cooking, home, work, productivity, learning English, reading books, etc. I noticed that traditional tree of documents is not enough to create hierarchy, but tags are also not enough. I created #todo and as a subpage #todo/now #todo/next. But I also want to have #work/todo #productivity/todo pages. So, #todo/next page and #work/todo are different and separate pages. And another layer of information is differentiation between ideas and physical things. Increasing productivity is an idea, connected to self-improvement. Should I have another page: self-improvement? While learn how to use Logseq is connected to idea: productivity, and todo. It is and activity.

Good solution for me would be to have ability to see different trees based on properties, so that the same page could have different places in different trees: ideas tree, activities tree, physical objects tree (book about productivity is a physical object to buy), etc. the same page: “now” could appear as todo/now and productivity/now depending on what tree I display. And productivity page could be at different levels of hierarchy depending on tree displayed:
/ideas/self-improvement/productivity/software/logseq
todo/now/productivity
productivity/now
physical_objects/books/room2/cupboard3/productivity/author/title
physical_objects/room2/books/cupboard3/productivity/author/title

This way naming pages like this: productivity/now would be not necessary because properties would manage hierarchy.

I’d like to be able to switch easily between different tree views to have easy access to them, for example from panel icon.

It would be like virtual trees not physical pages trees.

I visualize my information rather like multidimensional connections not like a tree but this would be to difficult to achieve as a way of navigation in a program.
https://images.wallpapersden.com/image/download/molecules-atoms-chemistry_aGhmapSZmpqtpaSklGhtaWWtZ2ZrZQ.jpg

The best solution would be to be able to create hierarchies dynamically by drag and drop to some virtual hierarchy space.

Actually we should stop call it hierarchy (unless someone wants to treat it like that) and call it “connections views”.

Without a particular example, it is difficult to give particular advice.

This is an issue beyond this thread. Consider opening a separate one.

It would really help to put some order in the terminology itself:

  • TODOs and ideas are information themselves.
  • TODOs may have sub-TODOs, but that’s all about their hierarchy (see lower).
  • There are two types of ideas:
    • Specific ideas that you come with: These are like TODOs.
    • Abstract ideas that pre-exist: These are the best material for multiple hierarchies.

Unless you mean the same connection inverted, only one direction should be valid.

Libraries (e.g. of books) know that very well. Fixed hierarchies remain useful, but they are very limited. The solution is graphs.

This won’t work well, because now and next change dynamically.

These should not be pages, but queries that filter your TODOs.

Now you are on topic, as far as this thread is concerned.

I get “Access denied” when trying to open that link.

This is again beyond this thread.

Overall, consider this approach:

  • Think about the possible virtual trees that you would like to generate.
  • For each one of them, find a property that describes the relationship among its nodes (e.g. type, category, container, subtopics, sections, etc.)
    • TODOs are not nodes, but leaves. A TODO:
      • may appear almost anywhere in your pages
      • doesn’t have pages as children
  • Use those properties consistently while creating your pages.
  • Use one macro for each tree, built around its defining property.

If you decide to try that approach, we may use it as a point of reference.

No. Queries results can’t be sorted manually. I want to have todo pages because I don’t use to do option. I know that something is todo when I have it on todo page and I use references from text to todo page. When there is a reference on todo page it means I must do something about it.

I added direct link to jpg.

Use one macro for each tree, built around its defining property.

I am new to Logseq and I wish there was a video about it, about creating macros. I will customize it.
If possible, please use your own properties and show how to write and run macros to display trees. And how to create an easy access to them. I don’t have so many data in Logseq yet. It will be easier for me to use properties in a meaningful way if I know what can be utilized for.

I found only one video about properties
How to use properties and templates in Logseq by OneStutteringMind, but it doesn’t cover the topic in depth.

Currently, I can only clear up how to use the single macro for this thread:

  • A macro is defined only once, by providing its name and output. For the trees, you only need to copy the following line and paste it inside the configuration file config.edn (found in the first page of Logseq’s Settings), inside section macros{}.
:pagetree "<div class='kit pagetree' data-kit='pagetree' data-node-prep='$1' data-node-prop='$2' data-leaf-prep='$3' data-leaf-prop='$4'>pagetree</div>"
  • A defined macro is called as many times as you need, by opening double curly braces in a note, and writing inside the name of the macro (here pagetree) followed by the desired parameters (called arguments), like this:
{{pagetree arg1, arg2, ... }}

Make sure each time to replace the part arg1, arg2, ... with a comma-separated series of the actual arguments (i.e. the desired tree’s characteristic property, preceded by its type), like in the examples provided in the OP:

{{pagetree to, children}}
{{pagetree from, broader, is, refs}}
2 Likes

Wow, thank you for your valuable work. I have to try this out!

Hi, thank you for sharing this neat trick.

From the example below (taken from one of the examples), I would sometimes only want to show the pagetree where parent:: [[man1]], so that the tree would look like the following:

boy1
girl2

Would this be doable with the current code?

boy1.md
  parent:: [[man1]]
boy2.md
  parent:: [[man2]]
girl1.md
  parent:: [[man2]]
girl2.md
  parent:: [[man1]]
grandmother1.md
  children:: [[man1]], [[woman1]]
grandmother2.md
  children:: [[man2]], [[woman2]]
man1.md
  parent:: [[grandfather1]]
man2.md
  parent:: [[grandfather2]]
woman1.md
  parent:: [[grandfather1]]
  children:: [[boy2]], [[girl1]]
woman2.md
  parent:: [[grandfather2]]
  children:: [[boy1]], [[girl2]]

EDIT: The motivation for this question is I would like to keep the parent and child property all throughout my graph for linking pages.

Welcome. Currently the code is limited by the syntax of macros, so there is no placeholder for defining a page as the single root. But if you can write some code, you can define in PageTree.roots.queries a query that returns a specific page as a starting point (in your example man1). Using this query, the tree would look like the following:

  • man1
    • boy1
    • girl2

Sadly, I do not know enough javascript and datalog to get this working quick. I might have to go look into this again over the weekend. Thank you.

Here is a quick workaround:

  • Find this line in the code:
        const roots = pgRoots.get(nodeconfig);
    
  • Replace it with these lines:
        const curpage = (div.dataset.page === "current") && logseq.api.get_current_page();
        if (curpage) curpage["original-name"] = curpage.originalName;
        const roots = (curpage) ? [curpage] : pgRoots.get(nodeconfig);
    
  • Add this macro inside file config.edn, inside macros{}:
    :curpagetree "<div class='kit pagetree' data-kit='pagetree' data-node-prep='$1' data-node-prop='$2' data-leaf-prep='$3' data-leaf-prop='$4' data-page='current'>pagetree</div>"
    
  • Visit the desired page
    • e.g. man1
  • Use the macro, either in the page or on the right sidebar
    • e.g. {{curpagetree from, parent}}
      • the result of the example:
        image
1 Like

bro do you know any tutorial for this? looks like is what i was seeking in a note app, but im not tech savy
Is there a page/github that we can track that code ?

  • Everything is available in the first post and the links there:
    • examples
    • code
      • The whole code is public within posts in this forum.
        • It has not changed for many months now.
        • Nobody has reported any problem so far.
    • instructions
      • Read the posts
      • Follow the steps
        • If you get stuck at any step, let me know.

bro im testing here and looks very promissing, may i ask you some questions that i have ?
so just a example i have a note called “Despesa Publica”
Despesa Publica.md
broader:: [[finPublica]]
Divida Publica.md
broader:: [[Despesa Publica]]
narrower:: [[Divida Flutuante]], [[Divida Fundada]]
Divida Flutuante.md
broader:: [[Despesa Publica]]
Divida Fundada.md
broader:: [[Divida Publica]]

Output on Despesa Publica.md

  • {{pagetree(from,broader)}}
    image

Divida Flutuante.md stays sibling of Divida Publica.md, altough should be child
Is there a way to make narrower and broader work together ?
I saw that the code works as expected just looking to “broader” attribute, but if it could take in consideration the “narrower” this code would be the god of hierarchies PKMs.

another possibility, if not using “narrower” property, would be in broader property, you could set more than one links, and the code would handle like this:

Despesa Publica.md
broader:: [[finPublica]]
Divida Publica.md
broader:: [[Despesa Publica]]
narrower:: [[Divida Flutuante]], [[Divida Fundada]]
Divida Flutuante.md
broader:: [[Despesa Publica]], [[Divida Publica]]
Divida Fundada.md
broader:: [[Divida Publica]]

Output on Despesa Publica.md
image
Now it duplicates

instead it could understand the tree hierarchy taking the nearest one as broader and then just:
image

just an parenthesis here, ofc these suggestions/feature request(if i may) that i made look dumb with few notes, but bro when you hit a lot of notes (i have more than 2k), that sense of direct hierarchies kinda lost, and that code would help a lot

And congrats for that fantastic work you made, i really appreciated was the far most well done implementation of hierarchies in any pkm that i know. And i searched a lot for this, glad that i landed here