d3-shape's stack (spec/04 §4.8): a baseline for each datum, so layers of data stack on
one another. The engine of the stack transform, ported from visualize's
Visualize.Shape.Stack.
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 = Macaw.Data.Stack.new()
|> Macaw.Data.Stack.keys([:apples, :oranges, :bananas])
series = Macaw.Data.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(), Macaw.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 §4.8)
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 Macaw.Data.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.