Functional Weave
Code in Python

charts.stack@1.0.0

README.md

1,968 bytes · view raw

# charts.stack

Stacks several series so they can be drawn as stacked bars or stacked areas.
`series[i][j]` is series `i` at position `j` (a category or an x value); the
result has the same shape, and each entry is that value's band `[y0, y1]` in
data units. Map both edges through a scale and hand them to
`charts.shape`'s `areaPath` (as `y0`/`y1`) or `barRects` (as `base`/`value`).

Series are stacked in the order given, first at the bottom. The offsets are
d3-shape's:

- `zero` (d3.stackOffsetNone): each band starts where the one below ended. A
  negative value makes a band whose top is below its bottom, overlapping the
  one beneath, which is what d3 does and is fine for areas of mostly positive
  data. For bars with negatives use `diverging`.
- `expand` (d3.stackOffsetExpand): each value is first divided by its
  position's total, then stacked, so every position runs from 0 to 1, a 100%
  chart. Multiply by 100 for percentages (or format with
  `charts.format`'s `formatPercent`). A position whose values are all zero
  stays at 0. Negative values have no meaning as shares of a total and are an
  error (d3 produces nonsense for them).
- `diverging` (d3.stackOffsetDiverging): positive values stack upwards from
  zero and negative values downwards from zero, each in series order; a zero
  value is an empty band at 0. This is the right one for bars that go both
  ways, such as profit and loss.

Running totals are kept at full precision and only the returned edges are
rounded, to 6 decimal places by `math.round-float`. So `0.1 + 0.2` stacks to
`0.3`, not `0.30000000000000004`, and an `expand` stack ends at exactly 1.

Every series must have the same length; there are no gaps (pass 0 for a
missing value, which is what a stack means by it). d3's stackOrder options are
not offered: reorder the series before calling.

Source: d3-shape, "Stacks" (github.com/d3/d3-shape#stacks): stack,
stackOffsetNone, stackOffsetExpand, stackOffsetDiverging.