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

The marks of a chart that move: the frames and the effect `:grow`

`Expresso.Element.Chart` calls this module for a chart with two or more
frames, and for a chart with the effect `:grow`. The module draws each mark
one time, at the origin of the SVG, and a CSS transform moves the mark to its
place. The place comes from a custom property of the chart, a **channel**,
such as `--b1-3` for the top of the bar of series 1 in category 3. The style
attribute of the mark reads the channel, with the value of the first frame
as the fallback.

The generated style block of the deck sets the channels of each later frame
at the steps of that frame. `rules/3` writes these rules. A mark copies the
channel into a registered property of the theme, such as `--chart-v`, and the
theme gives that property a transition. Therefore the mark moves from one
frame to the next with the time and the easing of the element.

A text that changes, such as the value of a bar, has one copy for each
frame, and the channel `--k<n>` of frame `n` is 1 for the copy of the frame
that shows. The copies fade. With the `count` option, the text has one copy
instead, and the presenter script writes the number from the registered
property `--chart-n` at each frame of the animation. At the end of the
animation, the script writes a label from the attribute `data-texts`, so
the number shows each digit of the value.

The effect `:grow` multiplies each place by `--chart-shown`, which the theme
sets from `--shown` on a chart or a series with that effect. A bar then
grows from the base line, and a pie opens from the top. The line of a line
chart opens from the left with a clip.

`docs/reference/chart-element.md` gives the rules for the author, and
`docs/architecture.md` gives the design.

# `changing`

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

Draw a text that changes from frame to frame

The text has one copy for each frame that fades, or one copy with a number
that the script counts. `text_assigns/4` makes the assigns.

# `channels`

```elixir
@spec channels(map()) :: [{String.t(), [number()]}]
```

Return the channels of a chart: the name and the value for each frame

The function leaves out a channel that has the same value in each frame,
because the mark then holds the value itself.

# `flags`

```elixir
@spec flags([map()]) :: [{String.t(), [0 | 1]}]
```

Return the channel `--k<n>` of each frame `n`: 1 at frame `n`, else 0

# `frame_label`

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

Draw the label of the frame that shows, at the top of the chart

A chart of one frame has no label, and a chart with `frame_label: :none`
has no label. The label has one copy for each frame. At each step, the
opacity of one copy changes to 0, and the opacity of the next copy
changes to 1.

# `grow`

```elixir
@spec grow(String.t(), number()) :: String.t()
```

Return a place that the effect `:grow` moves from `from`

# `inner_block`
*macro* 

# `rank`

```elixir
@spec rank(%{values: [[number()]]}, non_neg_integer(), boolean()) :: non_neg_integer()
```

Return the place of a category in a frame of a bar chart, from 0

Without `sort`, the place is the index of the category. With `sort`, the
category with the largest total of the frame takes place 0, and two equal
totals keep the order of their categories.

    iex> frame = %{values: [[1, 30, 10]]}
    iex> Enum.map(0..2, &Expresso.Element.Chart.Motion.rank(frame, &1, true))
    [2, 0, 1]

# `ref`

```elixir
@spec ref(String.t(), [number()]) :: String.t()
```

Return the value of a channel for a style attribute

The value is the custom property with the value of the first frame as its
fallback, or the value alone when no frame changes it. The value of a
channel of a number, such as `n1-0`, keeps each digit, and the value of a
channel of a coordinate keeps one decimal.

# `render`

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

Draw the marks of a chart

The assigns hold the keys of `Expresso.Element.Chart` and the box of the
plot, the function `y` from a value to a coordinate, and the function
`category_x` from the index of a category to its center.

# `render_slot`
*macro* 

# `rules`

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

Return the CSS rules of the frames of one chart

`el` is the value of the `data-el` attribute of the chart, and `steps` holds
the steps of each frame after the first. Each rule sets the channels of one
frame at its steps. The last rule sets the channels of the frame of the
`thumbnail` option on the overview and on the menu of the slides, because
they show the last step of the slide.

# `style`

```elixir
@spec style([{String.t(), String.t() | number()}]) :: String.t()
```

Write pairs of a property and a value as the text of a style attribute

# `text_assigns`

```elixir
@spec text_assigns([String.t()], [number()], String.t(), keyword()) :: map()
```

Make the assigns of `changing/1`

`texts` holds the text of each frame, `numbers` the number of each frame for
the `count` option, and `name` the channel of the number. The option `keys`
gives the `data-keys` attribute of each text, from `Expresso.Element.Chart.key/2`.

---

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