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

The values of a tree: the sums, the order, the limit, the depth and the text

`prepare/2` changes the tree before the layout, in this order:

1. `depth` cuts the tree at a level. A node at the last level gets the
   total of its subtree as its value.
2. `sum` gives a node with no value the sum of the values of its nodes.
3. `sort` puts the nodes under each node in the order of their values.
4. `limit` keeps a number of nodes under each node, and one more node holds
   the sum of the rest.

`text/3` writes a value in the format of the `value_format` option. The
layout and the renderer then read the prepared tree only, so each part of
the drawing shows the same values.

# `options`

```elixir
@type options() :: [
  depth: pos_integer() | nil,
  sum: boolean(),
  sort: :value | :none,
  limit: pos_integer() | nil
]
```

The options of the tree that change the values

# `more_name`

```elixir
@spec more_name(Expresso.Element.Node.t()) :: String.t()
```

Return the name of the node that holds the rest of the nodes under a node

The name starts with a character that no name of the data holds, so it
cannot be the name of a different node.

# `prepare`

```elixir
@spec prepare(Expresso.Element.Node.t(), options()) :: Expresso.Element.Node.t()
```

Return the tree with the values, the order and the levels of the options

    iex> alias Expresso.Element.Node
    iex> root = %Node{name: "/", elements: [%Node{name: "a", value: 1}, %Node{name: "b", value: 5}, %Node{name: "c", value: 2}]}
    iex> root = Expresso.Element.Hierarchy.Values.prepare(root, sum: true, sort: :value, limit: 2)
    iex> root.value
    8
    iex> Enum.map(root.elements, &{&1.label || &1.name, &1.value})
    [{"b", 5}, {"c", 2}, {"1 more", 1}]

# `text`

```elixir
@spec text(number(), :number | :bytes | :percent, number() | nil) :: String.t()
```

Write a value in a format

`total` is the value of the root, for the format `:percent`.

    iex> alias Expresso.Element.Hierarchy.Values
    iex> Values.text(1250, :number, nil)
    "1,250"
    iex> Values.text(2.0 / 3, :number, nil)
    "0.67"
    iex> Values.text(412_000_000_000, :bytes, nil)
    "412 GB"
    iex> Values.text(4_150_000, :bytes, nil)
    "4.2 MB"
    iex> Values.text(512, :bytes, nil)
    "512 B"
    iex> Values.text(25, :percent, 200)
    "12.5%"
    iex> Values.text(200, :percent, 200)
    "100%"

# `total`

```elixir
@spec total(Expresso.Element.Node.t()) :: number() | nil
```

Return the value of a node, or the total of the values under it

    iex> alias Expresso.Element.Node
    iex> Expresso.Element.Hierarchy.Values.total(%Node{name: "a", elements: [%Node{name: "b", value: 2}, %Node{name: "c", value: 3.5}]})
    5.5
    iex> Expresso.Element.Hierarchy.Values.total(%Node{name: "a"})
    nil

---

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