Expresso.Element.Chart.Hierarchy (expresso v0.1.0)

Copy Markdown View Source

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.

Summary

Types

A part of the tree, or a group of parts

Functions

Check the categories of a treemap or a sunburst

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

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

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

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

Draw a treemap or a sunburst

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

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

Make the tree of the categories

Types

part()

@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

Functions

check(categories, separator)

@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(parts)

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

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

inner_block(name, list)

(macro)

keys(parts)

@spec keys([part()]) :: %{required(pos_integer()) => 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(category, separator)

@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(categories, separator)

@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(assigns)

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

Draw a treemap or a sunburst

render_slot(slot, arg)

(macro)

scene(assigns)

@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(items, rect)

@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(categories, separator)

@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.