All Projects โ†’ m1gwings โ†’ Treedrawer

m1gwings / Treedrawer

Licence: mit
treedrawer is a Go module for drawing trees on the terminal.

Programming Languages

go
31211 projects - #10 most used programming language
golang
3204 projects

Projects that are alternatives of or similar to Treedrawer

Ngx Ui
๐Ÿš€ Style and Component Library for Angular
Stars: โœญ 534 (+1141.86%)
Mutual labels:  tree, drawer
Treeify
Pretty-print a javascript object as a tree
Stars: โœญ 174 (+304.65%)
Mutual labels:  terminal, tree
Fern.vim
๐ŸŒฟ General purpose asynchronous tree viewer written in Pure Vim script
Stars: โœญ 552 (+1183.72%)
Mutual labels:  tree, drawer
Termplotlib
Plotting on the command line
Stars: โœญ 294 (+583.72%)
Mutual labels:  terminal, plotting
Unicodeplots.jl
Unicode-based scientific plotting for working in the terminal
Stars: โœญ 724 (+1583.72%)
Mutual labels:  terminal, plotting
Tty Pager
Terminal output paging - cross-platform, major ruby interpreters
Stars: โœญ 37 (-13.95%)
Mutual labels:  terminal
Dotfiles
Colourful & robust configuration files and utilities for Mac, Linux and BSD
Stars: โœญ 1,006 (+2239.53%)
Mutual labels:  terminal
Duo Navigation Drawer
A flexible, easy to use, unique drawer library for your Android project.
Stars: โœญ 986 (+2193.02%)
Mutual labels:  drawer
Sqlite Global Tool
SQLite .NET Core CLI tool that allows the user to manually enter and execute SQL statements with or without showing query result.
Stars: โœญ 37 (-13.95%)
Mutual labels:  terminal
Go Chartjs
golang library to make https://chartjs.org/ plots (this is vanilla #golang, not gopherjs)
Stars: โœญ 42 (-2.33%)
Mutual labels:  plotting
Neoterm
Wrapper of some vim/neovim's :terminal functions.
Stars: โœญ 1,007 (+2241.86%)
Mutual labels:  terminal
Far2l
Linux port of FAR v2
Stars: โœญ 1,001 (+2227.91%)
Mutual labels:  terminal
Notify.uno
Get notified when your command is done
Stars: โœญ 38 (-11.63%)
Mutual labels:  terminal
Iterm2 Snazzy
Elegant iTerm2 theme with bright colors
Stars: โœญ 1,005 (+2237.21%)
Mutual labels:  terminal
Deepdiff
Deep Difference and search of any Python object/data.
Stars: โœญ 985 (+2190.7%)
Mutual labels:  tree
G6
โ™พ A Graph Visualization Framework in JavaScript
Stars: โœญ 8,490 (+19644.19%)
Mutual labels:  tree
Bubbly
A python package for plotting animated and interactive bubble charts using Plotly
Stars: โœญ 37 (-13.95%)
Mutual labels:  plotting
Vue Treeselect
A Tree Select Plugin For Vue2.0+
Stars: โœญ 40 (-6.98%)
Mutual labels:  tree
Influx Prompt
An interactive command-line InfluxDB cli with auto completion.
Stars: โœญ 42 (-2.33%)
Mutual labels:  terminal
Timetable
Plot out your own timetable for the week and organize it
Stars: โœญ 39 (-9.3%)
Mutual labels:  plotting

treedrawer

treedrawer is a Go module for drawing trees on the terminal like the one below.

                                    โ•ญโ”€โ•ฎ                                    
                                    โ”‚9โ”‚                                    
                                    โ•ฐโ”ฌโ•ฏ                                    
                   โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ•ฎ 
        โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ                    โ•ญโ”ดโ•ฎ           โ•ญโ”ดโ•ฎ โ•ญโ”ดโ•ฎ โ•ญโ”ดโ•ฎ
        โ”‚I can handle stringsโ”‚                    โ”‚1โ”‚           โ”‚2โ”‚ โ”‚3โ”‚ โ”‚4โ”‚
        โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ                    โ•ฐโ”ฌโ•ฏ           โ•ฐโ”€โ•ฏ โ•ฐโ”€โ•ฏ โ•ฐโ”€โ•ฏ
                   โ”‚                      โ•ญโ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ•ฎ                 
  โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ   โ•ญโ”€โ”ดโ”€โ•ฎ โ•ญโ”€โ”ดโ•ฎ  โ•ญโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ•ฎ             
  โ”‚with as many children as you wantโ”‚   โ”‚124โ”‚ โ”‚13โ”‚  โ”‚a stringโ”‚             
  โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ   โ•ฐโ”€โ”€โ”€โ•ฏ โ•ฐโ”€โ”€โ•ฏ  โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ             
                   โ”‚                                                       
   โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ                                       
   โ”‚with as many layers as you wantโ”‚                                       
   โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ                                       
                   โ”‚                                                       
 โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ                                     
 โ”‚actually I can handle everything...โ”‚                                     
 โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ                                     
                   โ”‚                                                       
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ                                    
โ”‚...that satisfies NodeValue interfaceโ”‚                                    
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ                                    

Import

import "github.com/m1gwings/treedrawer/tree"

Quick start

# Assume the following code is in example.go file
$ cat example.go
package main

import (
	"fmt"

	"github.com/m1gwings/treedrawer/tree"
)

func main() {
	// Creating a tree with 5 as the value of the root node
	t := tree.NewTree(tree.NodeInt64(5))

	// Adding children
	t.AddChild(tree.NodeString("adding a string"))
	t.AddChild(tree.NodeInt64(4))
	t.AddChild(tree.NodeInt64(3))

	// Drawing the tree
	fmt.Println(t)
}
$ go run example.go
           โ•ญโ”€โ•ฎ           
           โ”‚5โ”‚           
           โ•ฐโ”ฌโ•ฏ           
        โ•ญโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ•ฎ 
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ โ•ญโ”ดโ•ฎ โ•ญโ”ดโ•ฎ
โ”‚adding a stringโ”‚ โ”‚4โ”‚ โ”‚3โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ โ•ฐโ”€โ•ฏ โ•ฐโ”€โ•ฏ

Usage

Building the tree

Creating the tree with 1 as the value of the root node

t := tree.NewTree(tree.NodeInt64(1))

Adding the first child to t with value 2

t.AddChild(tree.NodeInt64(2))

Adding more children

t.AddChild(tree.NodeInt64(3))
t.AddChild(tree.NodeInt64(4))
t.AddChild(tree.NodeInt64(5))

We've just built the tree below

      โ•ญโ”€โ•ฎ      
      โ”‚1โ”‚      
      โ•ฐโ”ฌโ•ฏ      
 โ•ญโ”€โ”€โ”€โ”ฌโ”€โ”ดโ”€โ”ฌโ”€โ”€โ”€โ•ฎ 
โ•ญโ”ดโ•ฎ โ•ญโ”ดโ•ฎ โ•ญโ”ดโ•ฎ โ•ญโ”ดโ•ฎ
โ”‚2โ”‚ โ”‚3โ”‚ โ”‚4โ”‚ โ”‚5โ”‚
โ•ฐโ”€โ•ฏ โ•ฐโ”€โ•ฏ โ•ฐโ”€โ•ฏ โ•ฐโ”€โ•ฏ

Navigating the tree

Navigating to first child of t (we're still working with the tree above)

// This method returns an error if the i-th child does not exist
// in this case i = 0
tFirstChild, err := t.Child(0)

Adding children to first child

tFirstChild.AddChild(tree.NodeInt64(6))
tFirstChild.AddChild(tree.NodeInt64(7))
tFirstChild.AddChild(tree.NodeInt64(8))

Going back to parent

// ok would be equal to false if tFirstChild were the root of the tree
tFirstChildParent, ok := tFirstChild.Parent()

_ := tFirstChildParent == t // true, we have gone back to the root of the tree

Navigating to third child of t

tThirdChild, err := t.Child(2)

Adding a string child to third child

tThirdChild.AddChild(tree.NodeString("I'm a string"))

Getting a pointer to the root of the tree

tRoot := tThirdChild.Root()

_ := tRoot == t // true

Now the tree looks like this

                โ•ญโ”€โ•ฎ                
                โ”‚1โ”‚                
                โ•ฐโ”ฌโ•ฏ                
     โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ 
    โ•ญโ”ดโ•ฎ     โ•ญโ”ดโ•ฎ       โ•ญโ”ดโ•ฎ       โ•ญโ”ดโ•ฎ
    โ”‚2โ”‚     โ”‚3โ”‚       โ”‚4โ”‚       โ”‚5โ”‚
    โ•ฐโ”ฌโ•ฏ     โ•ฐโ”€โ•ฏ       โ•ฐโ”ฌโ•ฏ       โ•ฐโ”€โ•ฏ
 โ•ญโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ•ฎ             โ”‚           
โ•ญโ”ดโ•ฎ โ•ญโ”ดโ•ฎ โ•ญโ”ดโ•ฎ     โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ•ฎ     
โ”‚6โ”‚ โ”‚7โ”‚ โ”‚8โ”‚     โ”‚I'm a stringโ”‚     
โ•ฐโ”€โ•ฏ โ•ฐโ”€โ•ฏ โ•ฐโ”€โ•ฏ     โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ     

Getting and setting values from the tree

Getting the value of a node

v := t.Val()

Setting the value of a node

t.SetVal(tree.NodeInt64(3))

Drawing the tree

*tree.Tree implements the Stringer interface, just use package fmt to draw trees to terminal

fmt.Println(t)

Implementing NodeValue interface

The tree can handle every type that satisfies the NodeValue interface

// NodeValue is the interface that wraps the Draw method.
//
// The Draw method allows to convert data into its unicode canvas representation.
// With the Draw method you can control how your data is going to appear on the tree.
type NodeValue interface {
	Draw() *drawer.Drawer
}

The wrappers for built-in are defined inside the package treedrawer/tree like tree.NodeInt64 or tree.NodeString used above, so you don't need to worry about them.
Continue reading this section if you want to draw custom types instead.

  • Importing treedrawer/drawer

First of all we need access to the drawer.Drawer type. Just import the following

import "github.com/m1gwings/treedrawer/drawer"

drawer.Drawer under the hood is just a 2D slice of runes on which you can draw a rune specifying its coordinates or another entire drawer.Drawer specifying the coordinates of its upper-left corner.

  • Defining a custom type
type NodeAsterisk struct {
	Width, Height int
}

NodeAsterisk represents a rectangle of width NodeAsterisk.Width and height NodeAsterisk.Height.

  • Implementing NodeAsterisk.Draw() in order to satisfy NodeValue interface
func (nA NodeAsterisk) Draw() *drawer.Drawer {
	d, err := drawer.NewDrawer(nA.Width, nA.Height)
	if err != nil {
		log.Fatal(err)
	}
	for x := 0; x < nA.Width; x++ {
		for y := 0; y < nA.Height; y++ {
			err = d.DrawRune('*', x, y)
			if err != nil {
				log.Fatal(err)
			}
		}
	}
	return d
}

The method allocates a new drawer with width nA.Width and height nA.Height, then loops over each cell and fills it with an '*'.
You can implement this method to represent your data as you want.

  • Adding instances of NodeAsterisk to a tree
t := tree.NewTree(NodeAsterisk{3, 4})
t.AddChild(NodeAsterisk{1, 2})
t.AddChild(NodeAsterisk{3, 3})
  • Drawing the tree
fmt.Println(t)
  โ•ญโ”€โ”€โ”€โ•ฎ  
  โ”‚***โ”‚  
  โ”‚***โ”‚  
  โ”‚***โ”‚  
  โ”‚***โ”‚  
  โ•ฐโ”€โ”ฌโ”€โ•ฏ  
 โ•ญโ”€โ”€โ”ดโ”€โ•ฎ  
โ•ญโ”ดโ•ฎ โ•ญโ”€โ”ดโ”€โ•ฎ
โ”‚*โ”‚ โ”‚***โ”‚
โ”‚*โ”‚ โ”‚***โ”‚
โ•ฐโ”€โ•ฏ โ”‚***โ”‚
    โ•ฐโ”€โ”€โ”€โ•ฏ

Examples

You can find these examples inside the ./examples folder

HTML tree

# Assume the following code is in htmltree.go file
$ cat htmltree.go
package main

import (
	"fmt"
	"log"
	"strings"

	"github.com/m1gwings/treedrawer/tree"
	"golang.org/x/net/html"
)

func main() {
	s := `<p>Links:</p><ul><li><a href="foo">Foo</a><li><a href="/bar/baz">BarBaz</a></ul>`
	doc, err := html.Parse(strings.NewReader(s))
	if err != nil {
		log.Fatal(err)
	}

	t := tree.NewTree(tree.NodeString(""))

	var f func(*html.Node, *tree.Tree)
	f = func(n *html.Node, t *tree.Tree) {
		t.SetVal(tree.NodeString(n.Data))
		for c := n.FirstChild; c != nil; c = c.NextSibling {
			tChild := t.AddChild(tree.NodeString(""))
			f(c, tChild)
		}
	}
	// Starting from FirstChild because the DocumentRoot has an empty Val
	f(doc.FirstChild, t)

	fmt.Println(t)
}
$ go run htmltree.go
             โ•ญโ”€โ”€โ”€โ”€โ•ฎ              
             โ”‚htmlโ”‚              
             โ•ฐโ”€โ”€โ”ฌโ”€โ•ฏ              
   โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ•ฎ            
โ•ญโ”€โ”€โ”ดโ”€โ•ฎ           โ•ญโ”€โ”€โ”ดโ”€โ•ฎ          
โ”‚headโ”‚           โ”‚bodyโ”‚          
โ•ฐโ”€โ”€โ”€โ”€โ•ฏ           โ•ฐโ”€โ”€โ”ฌโ”€โ•ฏ          
            โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ•ฎ       
           โ•ญโ”ดโ•ฎ         โ•ญโ”€โ”ดโ•ฎ      
           โ”‚pโ”‚         โ”‚ulโ”‚      
           โ•ฐโ”ฌโ•ฏ         โ•ฐโ”€โ”ฌโ•ฏ      
            โ”‚       โ•ญโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ•ฎ    
        โ•ญโ”€โ”€โ”€โ”ดโ”€โ”€โ•ฎ  โ•ญโ”€โ”ดโ•ฎ    โ•ญโ”€โ”ดโ•ฎ   
        โ”‚Links:โ”‚  โ”‚liโ”‚    โ”‚liโ”‚   
        โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ  โ•ฐโ”€โ”ฌโ•ฏ    โ•ฐโ”€โ”ฌโ•ฏ   
                    โ”‚       โ”‚    
                   โ•ญโ”ดโ•ฎ     โ•ญโ”ดโ•ฎ   
                   โ”‚aโ”‚     โ”‚aโ”‚   
                   โ•ฐโ”ฌโ•ฏ     โ•ฐโ”ฌโ•ฏ   
                    โ”‚       โ”‚    
                  โ•ญโ”€โ”ดโ”€โ•ฎ โ•ญโ”€โ”€โ”€โ”ดโ”€โ”€โ•ฎ 
                  โ”‚Fooโ”‚ โ”‚BarBazโ”‚ 
                  โ•ฐโ”€โ”€โ”€โ•ฏ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ 

File system tree

# Assume the following code is in filesystemtree.go file
$ cat filesystemtree.go
package main

import (
	"fmt"
	"log"
	"strings"

	"github.com/m1gwings/treedrawer/tree"
	"golang.org/x/net/html"
)

func main() {
	s := `<p>Links:</p><ul><li><a href="foo">Foo</a><li><a href="/bar/baz">BarBaz</a></ul>`
	doc, err := html.Parse(strings.NewReader(s))
	if err != nil {
		log.Fatal(err)
	}

	t := tree.NewTree(tree.NodeString(""))

	var f func(*html.Node, *tree.Tree)
	f = func(n *html.Node, t *tree.Tree) {
		t.SetVal(tree.NodeString(n.Data))
		for c := n.FirstChild; c != nil; c = c.NextSibling {
			tChild := t.AddChild(tree.NodeString(""))
			f(c, tChild)
		}
	}
	// Starting from FirstChild because the DocumentRoot has an empty Val
	f(doc.FirstChild, t)

	fmt.Println(t)
}
$ go run filesystemtree.go
                                                                                โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ                                                                                 
                                                                                โ”‚treedrawerโ”‚                                                                                 
                                                                                โ•ฐโ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ•ฏ                                                                                 
     โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ                                      
โ•ญโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ•ฎ            โ•ญโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ•ฎ             โ•ญโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ•ฎ           โ•ญโ”€โ”€โ”€โ”ดโ”€โ”€โ•ฎ            โ•ญโ”€โ”€โ”€โ”ดโ”€โ”€โ•ฎ                                     โ•ญโ”€โ”€โ”ดโ”€โ•ฎ                                    
โ”‚README.mdโ”‚            โ”‚examplesโ”‚             โ”‚LICENSEโ”‚           โ”‚drawerโ”‚            โ”‚go.sumโ”‚                                     โ”‚treeโ”‚                                    
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ            โ•ฐโ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ•ฏ             โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ           โ•ฐโ”€โ”€โ”€โ”ฌโ”€โ”€โ•ฏ            โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ                                     โ•ฐโ”€โ”€โ”ฌโ”€โ•ฏ                                    
                  โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ                            โ•ญโ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ                         โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ       
            โ•ญโ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ•ฎ โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ           โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ  โ•ญโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ•ฎ           โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ  โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ•ฎ  โ•ญโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ•ฎ โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ•ฎ 
            โ”‚htmltree.goโ”‚ โ”‚filesystemtree.goโ”‚           โ”‚drawer_test.goโ”‚  โ”‚drawer.goโ”‚           โ”‚examples_test.goโ”‚  โ”‚stringify.goโ”‚  โ”‚tree.goโ”‚ โ”‚nodevalues.goโ”‚ โ”‚tree_test.goโ”‚ 
            โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ           โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ  โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ           โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ  โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ  โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ 

Benchmarks

You can find the code used for the benchmark inside ./tree/stringify_test.go
In order to profile the module we first create trees with l layers and c children for each node, except leaf nodes. Each node has a tree.NodeString("*") as value.
For example the tree below has 3 layers and 2 children for each node.

      โ•ญโ”€โ•ฎ      
      โ”‚*โ”‚      
      โ•ฐโ”ฌโ•ฏ      
   โ•ญโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ•ฎ   
  โ•ญโ”ดโ•ฎ     โ•ญโ”ดโ•ฎ  
  โ”‚*โ”‚     โ”‚*โ”‚  
  โ•ฐโ”ฌโ•ฏ     โ•ฐโ”ฌโ•ฏ  
 โ•ญโ”€โ”ดโ”€โ•ฎ   โ•ญโ”€โ”ดโ”€โ•ฎ 
โ•ญโ”ดโ•ฎ โ•ญโ”ดโ•ฎ โ•ญโ”ดโ•ฎ โ•ญโ”ดโ•ฎ
โ”‚*โ”‚ โ”‚*โ”‚ โ”‚*โ”‚ โ”‚*โ”‚
โ•ฐโ”€โ•ฏ โ•ฐโ”€โ•ฏ โ•ฐโ”€โ•ฏ โ•ฐโ”€โ•ฏ

In our benchmark function we print to /dev/null a tree with the specified l and c parameter.
Name|Iterations|Time|Children per Node|Layers|Total of Nodes|Memory|Allocations -|-|-|-|-|-|-|-| BenchmarkDrawing3L3C-12|10000|100063 ns/op|3.00 children|3.00 layers|13.0 nodes|135576 B/op|722 allocs/op BenchmarkDrawing100L1C-12|382|3096956 ns/op|1.00 children|100 layers|100 nodes|3727628 B/op|23297 allocs/op BenchmarkDrawing6L3C-12|9|119789317 ns/op|3.00 children|6.00 layers|364 nodes|366549320 B/op|33606 allocs/op BenchmarkDrawing1000L1C-12|7|161607620 ns/op|1.00 children|1000 layers|1000 nodes|373048737 B/op|2033004 allocs/op BenchmarkDrawing10L2C-12|2|733952840 ns/op|2.00 children|10.0 layers|1023 nodes|4375790984 B/op|114909 allocs/op BenchmarkDrawing11L2C-12|1|3661883138 ns/op|2.00 children|11.0 layers|2047 nodes|20557038432 B/op|249910 allocs/op BenchmarkDrawing8L3C-12|1|8550947886 ns/op|3.00 children|8.00 layers|3280 nodes|50574173168 B/op|387828 allocs/op BenchmarkDrawing12L2C-12|1|13559015034 ns/op|2.00 children|12.0 layers|4095 nodes|96166288000 B/op|538283 allocs/op

Generated using go version go1.15.1 linux/amd64

Known issues ๐Ÿ›

  • Emojis are larger than normal characters
fmt.Println(tree.NewTree(tree.NodeString("emojis are buggy ๐Ÿคช")))
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ 
โ”‚emojis are buggy ๐Ÿคชโ”‚ 
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ 

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].