# `Expresso.Element.Hierarchy.Data`
[🔗](https://github.com/rellen/expresso/blob/main/lib/expresso/element/hierarchy/data.ex#L1)

The nodes of a tree from a flat list: the rows of a CSV file, or nodes with
the `parent` option

A CSV file gives a tree in one of two forms:

| Form | Columns |
| --- | --- |
| Parent | `id`, `parent`, and the other columns. An empty `parent` makes the root. |
| Path | `path`, and the other columns. The separator divides a path into its levels. |

The other columns have the names of the options of a node: `label`,
`detail`, `image`, `icon`, `value`, `color`, `layout` and `class`. The
`fields` option of the tree names more columns, and each one becomes a
field of the box with its heading as its name.

In the path form, a level without a row of its own becomes a node with no
options, so `home/photos` makes the node `home` too. The identity of a node
is its path without a separator at the start or at the end, such as
`home/photos`. When the paths start with more than one level, such as
`home` and `var`, a root with the label of the separator holds them.

`assemble/1` makes the tree from the parent of each node, for both forms of
a file and for the `parent` option of the DSL.

# `entry`

```elixir
@type entry() :: {Expresso.Element.Node.t(), String.t() | nil, String.t()}
```

A node, the name of its parent or `nil`, and the place that gives it, for an error

# `assemble`

```elixir
@spec assemble([entry()]) :: {:ok, [Expresso.Element.Node.t()]} | {:error, String.t()}
```

Return the roots of a tree from its entries, in the order of the entries

Each node holds the nodes whose parent it is, after the nodes that it
already holds. The function returns an error for two nodes with one name,
for a parent that no node has, and for a loop of parents.

    iex> alias Expresso.Element.Node
    iex> entries = [{%Node{name: "a"}, nil, "a"}, {%Node{name: "b"}, "a", "b"}, {%Node{name: "c"}, "b", "c"}]
    iex> {:ok, [root]} = Expresso.Element.Hierarchy.Data.assemble(entries)
    iex> {root.name, hd(root.elements).name, hd(hd(root.elements).elements).name}
    {"a", "b", "c"}

# `rows`

```elixir
@spec rows([{pos_integer(), [String.t()]}], String.t(), keyword()) ::
  {:ok, [Expresso.Element.Node.t()]} | {:error, String.t()}
```

Return the roots of a tree from the rows of a CSV file

`rows` are the rows of `Expresso.Element.Chart.Csv.rows/3`, with the
headings first. `fields` names the columns of the fields, and `separator`
divides a path.

    iex> rows = [{1, ["path", "value"]}, {2, ["/home/photos", "412"]}, {3, ["/var", "21"]}]
    iex> {:ok, [root]} = Expresso.Element.Hierarchy.Data.rows(rows, "a.csv", fields: [], separator: "/")
    iex> {root.label, Enum.map(root.elements, & &1.name)}
    {"/", ["home", "var"]}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
