Visualize.Layout.Tree (Visualize v0.2.25)

Copy Markdown View Source

Tree layout algorithm for hierarchical node-link diagrams.

Implements the Reingold–Tilford "tidy" algorithm as refined by Buchheim, Jünger and Leipert (linear time, threads and accumulated shifts), ported from d3-hierarchy's tree: children of one parent are placed left to right with the gap given by separation, every parent is centred over its children, and subtrees are shifted so that nodes at the same depth never overlap while adjacent subtrees keep their separation.

Examples

# Create hierarchy
data = %{
  name: "root",
  children: [
    %{name: "A", children: [%{name: "A1"}, %{name: "A2"}]},
    %{name: "B"}
  ]
}

root = Visualize.Layout.Hierarchy.new(data)

# Apply tree layout
tree = Visualize.Layout.Tree.new()
  |> Visualize.Layout.Tree.size([400, 200])

positioned = Visualize.Layout.Tree.generate(tree, root)

# Each node now has x, y coordinates
Visualize.Layout.Hierarchy.each(positioned, fn node ->
  IO.puts("#{node.data.name}: (#{node.x}, #{node.y})")
end)

Summary

Functions

Generates the tree layout, positioning all nodes.

Creates a new tree layout

Sets the fixed node size.

Sets the separation function between nodes.

Sets the size of the layout.

Types

t()

@type t() :: %Visualize.Layout.Tree{
  node_size: {number(), number()} | nil,
  separation:
    (Visualize.Layout.Hierarchy.t(), Visualize.Layout.Hierarchy.t() -> number())
    | nil,
  size: {number(), number()} | nil
}

Functions

generate(tree, root)

Generates the tree layout, positioning all nodes.

Without size or node_size the coordinates are raw: x in separation units with the root at 0, y the depth.

new()

@spec new() :: t()

Creates a new tree layout

node_size(tree, arg2)

@spec node_size(t(), [number()] | {number(), number()}) :: t()

Sets the fixed node size.

Unlike size/2, this sets a fixed spacing between nodes rather than scaling to fit a container.

separation(tree, func)

@spec separation(t(), (Visualize.Layout.Hierarchy.t(),
                 Visualize.Layout.Hierarchy.t() ->
                   number())) ::
  t()

Sets the separation function between nodes.

The function receives two nodes and returns the desired separation. Default is 1 for siblings, 2 for non-siblings.

size(tree, arg2)

@spec size(t(), [number()] | {number(), number()}) :: t()

Sets the size of the layout.

The tree will be scaled to fit within [width, height].