Tree

The Tree renderable shows hierarchical structures:

import Term.Trees: Tree

data = Dict(
    "a" => 1,
    "b" => Int64,
    "c" => (1, 2, 3),
)

print(Tree(data))
Dict("c" => (1, 2, 3), "b" => Int64, "a"
  => 1)
  ├─ c  (1, 2, 3)
        ├─ 1  1
        ├─ 2  2
        └─ 3  3
  ├─ b  Int64
  └─ a  1

As you can see, the starting point is a Dict with key -> value entries which get rendered as leaves in the tree. Also, the Type of value is shown by colors in the tree.

If you have nested data, just create nested dictionaries!

data = Dict(
    "a" => 1,
    "b" => Int64,
    "deep" => Dict(
            "x" => 1,
            "y" => :x
    ),
)

print(Tree(data))
Dict("deep" => Dict("x" => 1, "y" => :x),
  "b" => Int64, "a" => 1)
  ├─ deep  Dict("x" => 1, "y" => :x)
           ├─ x  1
           └─ y  x
  ├─ b  Int64
  └─ a  1

Under the hood, Tree just leverages AbstractTrees.jl to handle tree-like data structures, so anything that is compatible with that framework will printed as a Tree.

# expressions
Tree(:(print, (:x, :(y+1)))) |> print

# arrays
Tree([1, [1, 2, [:a, :b, :c]]]) |> print

# and more!
(print, (:x, :(y + 1)))
  ├─ 1  print
  └─ 2  (:x, :(y + 1))
         ├─ 1  :x
         └─ 2  :(y + 1)
                └─ 1  y + 1
                       ├─ 1  +
                       ├─ 2  y
                       └─ 3  1

Any[1, Any[1, 2, [:a, :b, :c]]]
  ├─ 1  1
  └─ 2  Any[1, 2, [:a, :b, :c]]
         ├─ 1  1
         ├─ 2  2
         └─ 3  [:a, :b, :c]
                ├─ 1  a
                ├─ 2  b
                └─ 3  c

Essentially Tree work's with AbstractTrees to just produce stylized output.

!!! tip Tree is not a tree Tree is an AbstractRenderable, it is not a datastructure for handling tree-like data. It's only meant to be used to display trees in your terminal. As such you can't do operations like finding children of nodes or getting a subtree etc. All of that should be done with AbstractTrees and Tree is only there to display the output

As per the note above, Tree is a AbstractRenderable type so it plays well with other renderables in term.

import Term: Panel

data = Dict(
    "a" => 1,
    "b" => Int64,
    "c" => (1, 2, 3),
)

_tree = Tree(data)
_info = Panel("This is a panel\nYou can use it to explain\nwhat the contents of the\ntree are!"; width=30, height=_tree.measure.h, subtitle="description")

print(_tree * "  " *_info)
Dict("c" => (1, 2, 3), "b" => Int64, "a"  ╭────────────────────────────╮
  => 1)                                   │  This is a panel           │
  ├─ c  (1, 2, 3)                        │  You can use it to         │
        ├─ 1  1                         │  explain                   │
        ├─ 2  2                         │  what the contents         │
        └─ 3  3                         │  of the                    │
  ├─ b  Int64                            │  tree are!                 │
  └─ a  1                                │                            │
                                          ╰──── description ───────────╯

Styling

Easy! Tree has lots of options to allow you to style it as you like. The style is set by the Theme.

import Term: Theme
using MyterialColors

# create a new theme editing the tree style
theme = Theme(
    tree_mid             = blue,
    tree_terminator       = blue,
    tree_skip           = blue,
    tree_dash           = blue,
    tree_trunc         = blue,
    tree_pair           = red_light,
    tree_keys           = yellow,
    tree_max_leaf_width = 22,
)

print(
    Tree(data,
        theme=theme
    )
)

tree_max_leaf_width sets the max width of the display of each leaf while the other values set the color of different elements of the Tree. In particular mid, terminator, dash refer to the lines (or guides) of the tree.

And since we're talking about guides you can also use different ones

print(
    Tree(data,
        guides=:asciitree
    )
)
Dict("c" => (1, 2, 3), "b" => Int64, "a"
  => 1)
  +---- c => (1, 2, 3)
  |        +---- 1 => 1
  |        +---- 2 => 2
  |        `---- 3 => 3
  +---- b => Int64
  `---- a => 1

there's a couple named guides style, but you can customize things even further using an AbstractTree.TreeCharSet if you wish.

TypeTree

As you know, Julia allows for hierarchical types structures. Trees are for visualizing hierarchical data structures. So...

import Term: typestree

typestree(AbstractFloat)
╭────────────────────────────────────────────────────────── Types hierarchy ───╮
                                                                              
                                                                             
   ├─ Complex                                                                
   └─ Real                                                                  
             ├─ Rational                                                     
             ├─ AbstractIrrational                                           
             ├─ AbstractFloat                                               
                                                           ├─ BigFloat      
                                                           ├─ Float32       
                                                           ├─ Float64       
                                                           └─ Float16       
             └─ Integer                                                      
                                                                              
                                                                              
╰──────────────────────────────────────────────────────────────────────────────╯

Enjoy!