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
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
@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 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\"."}
Return each part of the tree, a parent before its 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"}
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"]
@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}]
@spec render(map()) :: Phoenix.HTML.safe()
Draw a treemap or a sunburst
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.
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}}]
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.