# `Expresso.Element.Chart`
[🔗](https://github.com/rellen/expresso/blob/main/lib/expresso/element/chart.ex#L1)

An element that draws a bar chart, a line chart, a pie chart, a treemap, a
sunburst, a sankey, an alluvial chart, a parallel sets chart, a chord chart,
a scatter plot or a waterfall chart

The `chart` entity takes the kind as its first argument: `:bar`, `:line`,
`:pie`, `:treemap`, `:sunburst`, `:sankey`, `:alluvial`, `:parallel_sets` or
`:chord`. A slash in a category of a treemap or a
sunburst names a part of a group, and `Expresso.Element.Chart.Hierarchy`
draws them. The `categories` option gives the names of the categories, and each
`series` entity gives a name and one value for each category. The `src`
option gives a CSV file in place of the two: the first row holds the names
of the series, and each other row holds a category and its values.

The render function draws the chart as SVG in the document, so the chart
needs no script and no file, and it prints. The colors of the series are
`--chart-1` to `--chart-8` of the theme, in a fixed order. A chart with two
or more series has a legend, a bar shows its value, the end of a line shows
its name and its last value, and the legend of a pie shows each part in
percent. A table with the values goes into the document for a screen
reader.

A series is a child of the chart, so `reveal true` shows each series at its
own step, and `dim true` dims each series when a later series shows. The
`highlight` option shows each series at each step, and it puts one group of
series or of categories in focus at each step: the rest of the chart dims.
`check/1` makes an `Expresso.Element.Focus` for each group, and `rules/1`
writes the rules that dim the series and the marks.

A `frame` entity holds the series at one point in time, and each frame
after the first takes one step. A chart with frames, or with the effect
`:grow`, moves its marks: `Expresso.Element.Chart.Motion` draws them.
`docs/reference/chart-element.md` gives the rules.

A category of a sankey is a path of nodes. The `flow` entities give the
same data in a shorter form. `Expresso.Element.Chart.Sankey` draws a
sankey. With `reveal true`, the check makes one series for each step: a
source column of the links in a sankey or an alluvial chart, a node of the
first column in a parallel sets chart, and a source in a chord chart. An
alluvial chart is a sankey with one node for each name in each column. The
place of a name in its path sets its column. A parallel sets chart has the
nodes of an alluvial chart. `Expresso.Element.Chart.ParallelSets` draws
each of its categories as one ribbon through the columns. A chord chart
takes the flows of a sankey. `Expresso.Element.Chart.Chord` draws its
nodes as arcs of a ring.

A scatter plot holds `point` entities in place of categories and series.
`Expresso.Element.Chart.Scatter` checks it and draws it, and
`docs/scatter-plots.md` gives its design.

A waterfall chart has one series. Its first value is the start, each other
number is a change, and the atom `:total` marks a total column.
`Expresso.Element.Chart.Waterfall` checks it and draws it, and
`docs/waterfall-charts.md` gives its design.

# `t`

```elixir
@type t() :: %Expresso.Element.Chart{
  __spark_metadata__: term(),
  at: term(),
  categories: term(),
  category_label: term(),
  class: term(),
  color: term(),
  color_label: term(),
  color_mid: term(),
  color_scale: term(),
  count: term(),
  delimiter: term(),
  dim: term(),
  direction: term(),
  easing: term(),
  effect: term(),
  el: term(),
  elements: term(),
  flows: term(),
  focus: term(),
  frame_label: term(),
  frames: term(),
  highlight: term(),
  jitter: term(),
  kind: term(),
  label: term(),
  labels: term(),
  levels: term(),
  morph: term(),
  on: term(),
  opacity: term(),
  reveal: term(),
  separator: term(),
  shape: term(),
  signature: term(),
  size: term(),
  size_label: term(),
  sort: term(),
  spans: term(),
  speed: term(),
  src: term(),
  steps: term(),
  symbol: term(),
  symbol_label: term(),
  thumbnail: term(),
  timeline: term(),
  title: term(),
  totals: term(),
  trend: term(),
  value_label: term(),
  value_range: term(),
  values: term(),
  whole_first: term(),
  width: term(),
  x: term(),
  x_label: term(),
  x_range: term(),
  x_scale: term(),
  y: term(),
  y_label: term(),
  y_range: term(),
  y_scale: term()
}
```

The struct of a chart

# `build`

```elixir
@spec build(t()) :: {:ok, t()} | {:error, String.t()}
```

Read the CSV file of a chart with `src`, and make its categories and series

The first row holds a heading for the categories, then the name of each
series. Each other row holds a category, then one number for each series.
A comma divides the cells, or a tab in a file that ends in `.tsv`, or the
`delimiter` option. `Expresso.Element.Chart.Csv` tells the rules. The
function reads the file through `Expresso.DeckFile`, so the watch mode
renders the deck again after a change to the file.

# `check`

```elixir
@spec check(t()) :: {:ok, t()} | {:error, String.t()}
```

Check the options of a chart

The transform of the `chart` entity calls this function. A chart with `src`
keeps its file until `Expresso.PathTransformer` runs, because the `root`
option of the deck can change the path, and `build/1` then reads it.

# `get_assigns`

```elixir
@spec get_assigns(t()) :: map()
```

Make the assigns of the render function from the struct

The key `overlay` holds the attributes of the overlay contract, and the
`style` attribute of the `width` option. The key `series` holds each series
with its color number and its overlay attributes. A series of a chart with
the `highlight` option also gets `data-series` with its color number, and
the rules of `rules/1` select it by that number. The key `keys` is true
for a chart with a group of categories, and `key/2` then gives each mark
of a category its `data-keys` attribute.

# `key`

```elixir
@spec key(map(), non_neg_integer() | nil) :: String.t() | nil
```

Return the `data-keys` attribute of a mark of a category

`index` is the index of the category, from 0. A mark that dims at each step
of a group of categories, such as a line, takes `nil`, and it gets an empty
attribute. A chart without a group of categories gives no attribute.

    iex> Expresso.Element.Chart.key(%{keys: true}, 1)
    "c2"
    iex> Expresso.Element.Chart.key(%{keys: true}, nil)
    ""
    iex> Expresso.Element.Chart.key(%{keys: false}, 1)
    nil

# `lead`

```elixir
@spec lead(t()) :: 0 | 1
```

Return the number of steps that a chart takes before the groups of its
`highlight` option

The `whole_first` option gives the chart one step with no group in focus,
as a `pause` in front of the chart does. A waterfall chart with `reveal`
takes one step for its start and its totals before its first change.
`Expresso.Overlay.Expand` reads this number.

# `moves?`

```elixir
@spec moves?(t()) :: boolean()
```

Tell whether the marks of a chart move

The marks move in a chart with two or more frames, and in a chart with the
effect `:grow` on the chart or on a series, or on a point of a scatter
plot. `Expresso.Element.Chart.Motion`
then draws them.

# `render`

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

Make the HTML of a chart: a `figure` with the SVG and a table of the values

The SVG has `role="img"` and the title as its name. The table has the class
`chart-table`, and the style sheet hides it from the eye and not from a
screen reader.

# `rules`

```elixir
@spec rules(t()) :: [String.t()]
```

Return the CSS rules of the frames and of the `highlight` option of a chart

`Expresso.Overlay.Render.style/1` calls this function for each chart, after
`Expresso.Overlay.Render.identify/1`. A chart without frames and without
the `highlight` option has no rules.

A group of the `highlight` option gives one rule at its step. The rule sets
`--chart-dim: 1` on each series that is not in the group, or on each mark
with a `data-keys` attribute that does not hold a key of the group. The
theme dims a series or a mark with that property.

# `width`

```elixir
@spec width(t()) :: [{String.t(), String.t()}]
```

Return the `style` attribute of the `width` option of a chart, as a list of
attributes

A chart without the option returns an empty list.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
