Stack generator for creating stacked bar and area charts.
Computes a baseline value for each datum, so you can stack layers of data on top of each other.
Examples
data = [
%{month: "Jan", apples: 10, oranges: 20, bananas: 15},
%{month: "Feb", apples: 15, oranges: 25, bananas: 10},
%{month: "Mar", apples: 20, oranges: 15, bananas: 25}
]
stack = Visualize.Shape.Stack.new()
|> Visualize.Shape.Stack.keys([:apples, :oranges, :bananas])
series = Visualize.Shape.Stack.generate(stack, data)
# Returns one series per key, in key order, each with :key, :index (its position
# in the stacking order) and :points. Points have :data, :y0 (baseline), :y1 (top).
Summary
Functions
Generates the stacked series data.
Sets the keys to stack.
Creates a new stack generator
Sets the stack offset.
Sets the stack order.
Sets the value accessor function.
Types
Functions
@spec generate(t(), Visualize.Data.Table.source()) :: [series()]
Generates the stacked series data.
Returns one series per key, in key order, each a map with:
:key- The series key:index- The series' position in the stacking order (0 is the bottom):points- One point per datum with:data,:value,:y0,:y1,:index
Sets the keys to stack.
Keys determine the layers in the stack, typically field names.
@spec new() :: t()
Creates a new stack generator
Sets the stack offset.
:none- Zero baseline (default):expand- Normalize to 0-1 (100% stacked):diverging- Positive values stack up from zero, negative values stack down from zero:silhouette- Center the stack around zero:wiggle- Minimize weighted wiggle (for streamgraphs)
Sets the stack order.
:none- Use key order (default):ascending- Smallest series on bottom:descending- Largest series on bottom:reverse- Reverse key order:insideout- d3'sstackOrderInsideOut: the earliest-peaking series in the middle, later ones outward on whichever side has the smaller sum (good for streamgraphs){:keys, list}- The listed keys bottom first, then the unlisted keys in key order; a listed key the stack does not have is ignored (spec/04 §8.4)
Every order but {:keys, list} is computed from the data generate/2 is given, so over
a stream of data it can change between frames; {:keys, list} is fixed.
iex> alias Visualize.Shape.Stack
iex> Stack.new()
...> |> Stack.keys([:a, :b, :c])
...> |> Stack.order({:keys, [:c, :x, :a]})
...> |> Stack.generate([%{a: 1, b: 2, c: 3}])
...> |> Enum.map(&{&1.key, &1.index})
[a: 1, b: 2, c: 0]
Sets the value accessor function.
The function receives (datum, key) and returns a number.