
Security News
CISA’s 2025 SBOM Guidance Adds Hashes, Licenses, Tool Metadata, and Context
CISA’s 2025 draft SBOM guidance adds new fields like hashes, licenses, and tool metadata to make software inventories more actionable.
Tree structure visualization function library
** Installation
Install as a standalone gem
#+BEGIN_SRC shell $ gem install tree_support #+END_SRC
Or install within application using Gemfile
#+BEGIN_SRC shell $ bundle add tree_support $ bundle install #+END_SRC
** How to use in one line
Just pass the object that has the parent, children method to =TreeSupport.tree=
#+BEGIN_SRC ruby require "tree_support" puts TreeSupport.tree(TreeSupport.example)
#+END_SRC
** Detailed usage
*** Prepare a node class like this
#+BEGIN_SRC ruby class Node attr_accessor :name, :parent, :children
def initialize(name = nil, &block) @name = name @children = [] if block_given? instance_eval(&block) end end
def add(*args, &block) tap do children << self.class.new(*args, &block).tap { |v| v.parent = self } end end end #+END_SRC
*** Create a tree
#+BEGIN_SRC ruby root = Node.new("root") do add "Battle" do add "Attack" do add "Shake the sword" add "Attack magic" do add "Summoned Beast X" add "Summoned Beast Y" end add "Repel sword in length" end add "Defense" end add "Withdraw" do add "To stop" do add "Place a trap" add "Shoot a bow and arrow" end add "To escape" end add "Break" do add "Stop" add "Recover" do add "Recovery magic" add "Drink recovery medicine" end end end #+END_SRC
*** Visualization
#+BEGIN_SRC ruby puts TreeSupport.tree(root)
#+END_SRC
*** Troublesome writing TreeSupport.tree
=include TreeSupport::Stringify=
#+BEGIN_SRC ruby Node.include(TreeSupport::Stringify) puts root.to_s_tree
#+END_SRC
*** How do I change the label of a node?
We look for =to_s_tree_name=, =name=, =subject=, =title=, =to_s= defined by =TreeSupport.name_methods= in that order, so we define the method by considering the priority
*** How do I change labels without defining methods?
Add a block to tree
#+BEGIN_SRC ruby puts TreeSupport.tree(root) { |node| node.object_id }
#+END_SRC
*** How to use methods that are common in tree structure?
The following methods become available in include of =TreeSupport::Treeable=
*** How to convert to Gviz object?
#+BEGIN_SRC ruby gv = TreeSupport.graphviz(root) #+END_SRC
*** How to image it?
#+BEGIN_SRC ruby gv.output("tree.png") #+END_SRC
[[https://raw.github.com/akicho8/tree_support/master/images/tree.png]]
*** How do I change the color of a particular node?
Return the graphviz attribute as a hash in TreeSupport.graphviz block
#+BEGIN_SRC ruby gv = TreeSupport.graphviz(root) do |node| if node.name.include?("Attack") {fillcolor: "lightblue", style: "filled"} elsif node.name.include?("Recover") {fillcolor: "lightpink", style: "filled"} end end gv.output("tree_color.png") #+END_SRC
[[https://raw.github.com/akicho8/tree_support/master/images/tree_color.png]]
*** How do I change the label of a particular node?
As with the above method, it returns a hash containing the label value
#+BEGIN_SRC ruby gv = TreeSupport.graphviz(root) do |node| {label: node.name.chars.first} end gv.output("tree_label.png") #+END_SRC
[[https://raw.github.com/akicho8/tree_support/master/images/tree_label.png]]
*** How can I check the dot format of Graphviz?
#+BEGIN_SRC ruby puts gv.to_dot
#+END_SRC
*** How can I check the image conversion immediately when debugging?
#+BEGIN_SRC ruby TreeSupport.graph_open(root) #+END_SRC
Equivalent to the next shortcut
#+BEGIN_SRC ruby
TreeSupport.graphviz(root).output("_output.png")
open _output.png
#+END_SRC
*** Troublesome making node classes yourself
You can use =TreeSupport::Node= as it is.
#+BEGIN_SRC ruby TreeSupport::Node.new("root") do add "Battle" do add "Attack" do add "Shake the sword" add "Attack magic" do add "Summoned Beast X" add "Summoned Beast Y" end end end end #+END_SRC
*** Troublesome making trees
#+BEGIN_SRC ruby TreeSupport.example #+END_SRC
There is a simple sample tree
*** How to trace leaves?
If you include =TreeSupport::Treeable= you can use each_node
#+BEGIN_SRC ruby root = TreeSupport.example root.each_node.with_index { |n, i| p [i, n.name] }
#+END_SRC
*** I do not want to display the root
#+BEGIN_SRC ruby puts TreeSupport.tree(root, drop: 1)
#+END_SRC
*** Since the trees are too big, it is enough up to the depth 3
#+BEGIN_SRC ruby puts TreeSupport.tree(root, take: 3)
#+END_SRC
*** When you combine both
#+BEGIN_SRC ruby puts TreeSupport.tree(root, take: 3, drop: 1)
#+END_SRC
*** Image version also has similar options
#+BEGIN_SRC ruby gv = TreeSupport.graphviz(root, drop: 1) gv.output("drop.png") #+END_SRC
[[https://raw.github.com/akicho8/tree_support/master/images/drop.png]]
#+BEGIN_SRC ruby gv = TreeSupport.graphviz(root, take: 3) gv.output("take.png") #+END_SRC
[[https://raw.github.com/akicho8/tree_support/master/images/take.png]]
#+BEGIN_SRC ruby gv = TreeSupport.graphviz(root, take: 3, drop: 1) gv.output("take_drop.png") #+END_SRC
[[https://raw.github.com/akicho8/tree_support/master/images/take_drop.png]]
*** Methods for easily making trees from data like CSV
Conversion from Array to Tree
#+BEGIN_SRC ruby require "tree_support"
records = [ {key: :a, parent: nil}, {key: :b, parent: :a}, {key: :c, parent: :b}, ]
puts TreeSupport.records_to_tree(records).first.to_s_tree
puts TreeSupport.records_to_tree(records, root_key: :root).to_s_tree
#+END_SRC
Conversion from Tree to Array
#+BEGIN_SRC ruby tree = TreeSupport.records_to_tree(records) pp TreeSupport.tree_to_records(tree.first)
#+END_SRC
*** How to use acts_as_tree equivalent?
Migration
#+BEGIN_SRC ruby create_table :nodes do |t| t.belongs_to :parent end #+END_SRC
Model
#+BEGIN_SRC ruby class Node < ActiveRecord::Base ar_tree_model end #+END_SRC
Difference from https://github.com/amerine/acts_as_tree
- simple
- Safely delete all safe_destroy_all (accident with destroy_all in combination with acts_as_list)
- Node.roots is defined by scope
- Arguments are different. =:order => :id= if you want to do it =scope: -> { order(:id) }=. By doing this you can also pass the where condition.
*** How do I correspond to memory_record gem?
Just as with ordinary classes, we need parent and children methods
#+BEGIN_SRC ruby class TreeModel include MemoryRecord memory_record [ {key: :a, parent: nil}, {key: :b, parent: :a}, {key: :c, parent: :b}, ]
include TreeSupport::Treeable include TreeSupport::Stringify
def parent self.class[super] end
def children self.class.find_all { |e| e.parent == self } end end
puts TreeModel.find_all(&:root?).collect(&:to_s_tree)
#+END_SRC
** With concern
FAQs
Unknown package
We found that tree_support demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
CISA’s 2025 draft SBOM guidance adds new fields like hashes, licenses, and tool metadata to make software inventories more actionable.
Security News
A clarification on our recent research investigating 60 malicious Ruby gems.
Security News
ESLint now supports parallel linting with a new --concurrency flag, delivering major speed gains and closing a 10-year-old feature request.