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

The treemap, the sunburst and the Voronoi treemap: charts of the parts of a
whole in groups

A category with a slash names a part in a group, such as
`"Production/Press"`, and the `separator` option of the chart can give a
different text than the slash. A category can also be a list of its
levels, such as `["Production", "Press"]`, and the `levels` option reads
such lists from the columns of a CSV file. The categories therefore give a
tree, and the one series gives the value of each leaf. A group has the sum
of its parts.

A treemap divides its box into rectangles in proportion to the values, with
the squarified layout of Bruls, Huizing and van Wijk, so the rectangles are
close to squares. A group holds its parts, with its name in a strip at its
top. A sunburst draws each level of the tree as a ring around a center, and
each part as an arc of its ring.

A Voronoi treemap divides a convex container into cells, with the layout of
`Expresso.Element.Chart.Voronoi`. Each part is a cell, and a group is the
cell that holds the cells of its parts, with a thicker outline. A leaf has
its label in its cell, in smaller text when the cell is narrow, and a
legend gives the top-level groups.
The chart has one frame and no effect `:grow`.

Each top-level group has a color of the palette, and its parts have lighter
tints of the same color. The drawing of a treemap and of a sunburst uses the
channels of `Expresso.Element.Chart.Motion`, so the parts move from frame to
frame, and the effect `:grow` opens the chart.

# `part`

```elixir
@type part() :: %{
  name: String.t(),
  id: pos_integer(),
  index: non_neg_integer() | nil,
  depth: pos_integer(),
  color: pos_integer(),
  children: [part()]
}
```

A part of the tree, or a group of parts

# `check`

```elixir
@spec check([String.t() | [String.t()]], String.t()) :: :ok | {:error, String.t()}
```

Check the categories of a treemap or a sunburst

A category is a string with the separator between its levels, such as
`"A/x"`, or a list of its levels, such as `["A", "x"]`. Each level has a
name, each category shows one time, a category is not also a group of
another category, and the top level has at most 8 groups.

    iex> Expresso.Element.Chart.Hierarchy.check(["A/x", "A/y", "B"], "/")
    :ok

    iex> Expresso.Element.Chart.Hierarchy.check([["A", "x"], ["A", "y"], ["B"]], "/")
    :ok

    iex> Expresso.Element.Chart.Hierarchy.check(["A", "A/x"], "/")
    {:error, "the category \"A\" is a group of \"A/x\", so it takes no value of its own. Give the value to a part, such as \"A/Other\"."}

# `flatten`

```elixir
@spec flatten([part()]) :: [part()]
```

Return each part of the tree, a parent before its parts

# `inner_block`
*macro* 

# `keys`

```elixir
@spec keys([part()]) :: %{required(pos_integer()) =&gt; String.t()}
```

Return the keys of the marks of each part, as a map from the id of a part

The marks of a part hold the key of the part, of each group above it and of
each part under it, such as `"p1 p2"`. A group of the `highlight` option
with a part therefore keeps the part, the groups around it and its own
parts in full color.

    iex> ["A/x", "A/y", "B"] |> Expresso.Element.Chart.Hierarchy.tree("/") |> Expresso.Element.Chart.Hierarchy.keys()
    %{1 => "p1 p2 p3", 2 => "p1 p2", 3 => "p1 p3", 4 => "p4"}

# `path`

```elixir
@spec path(String.t() | [String.t()], String.t()) :: [String.t()]
```

Return the levels of a category: the parts of a string between two
separators, or the names of a list, with no spaces at their ends

    iex> Expresso.Element.Chart.Hierarchy.path("Production > Press", " > ")
    ["Production", "Press"]

    iex> Expresso.Element.Chart.Hierarchy.path(["I/O", " Disks "], "/")
    ["I/O", "Disks"]

# `paths`

```elixir
@spec paths([String.t() | [String.t()]], String.t()) :: [
  {[String.t()], pos_integer()}
]
```

Return the path of each part and of each group, with its id

The path holds the names of the levels from the top level down, so
`["Production", "Press"]` is the part "Press" of the group "Production".
The `highlight` option of a chart names a part or a group with its path.

    iex> Expresso.Element.Chart.Hierarchy.paths(["A/x", "A/y", "B"], "/")
    [{["A"], 1}, {["A", "x"], 2}, {["A", "y"], 3}, {["B"], 4}]

# `render`

```elixir
@spec render(map()) :: Phoenix.HTML.safe()
```

Draw a treemap or a sunburst

# `render_slot`
*macro* 

# `scene`

```elixir
@spec scene(map()) :: map()
```

Return the places of the parts of a chart in each frame, and the channels

`Expresso.Element.Chart.Motion` calls this function for a treemap and for a
sunburst.

# `squarify`

```elixir
@spec squarify([{term(), number()}], map()) :: [{term(), map()}]
```

Divide a rectangle into rectangles of the given areas, close to squares

The items are pairs of a key and an area, from the largest, and the sum of
the areas is the area of the rectangle. This is the squarified layout of
Bruls, Huizing and van Wijk.

    iex> Expresso.Element.Chart.Hierarchy.squarify([{:a, 6}, {:b, 2}], %{x: 0, y: 0, w: 4, h: 2})
    [{:a, %{x: 0, y: 0, w: 3.0, h: 2.0}}, {:b, %{x: 3.0, y: 0, w: 1.0, h: 2.0}}]

# `tree`

```elixir
@spec tree([String.t() | [String.t()]], String.t()) :: [part()]
```

Make the tree of the categories

Each part has an `id` in the order of the tree, a parent before its parts,
and a leaf has the `index` of its category. The parts of a group keep the
order of their first category. Call `check/2` first.

---

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