# `Expresso.Element.Diagram.Pele.Plan`
[🔗](https://github.com/rellen/expresso/blob/main/lib/expresso/element/diagram/pele/plan.ex#L1)

The plan of a diagram type of Pele, and the functions that each plan uses

A plan takes the model of `parse()` and returns a function. That function
takes the `data-id` and the classes of an element of the SVG, and it returns
the name of the element and its marks for `Expresso.Element.Diagram.Outline`.
`Expresso.Element.Diagram.Pele.name/1` gives the first element of each name
its marks, and each later element of the name only its `id`.

Some types give more than one part the same `data-id`, such as two edges
of an architecture diagram between the same services. The function of such
a plan takes a third argument: the number of earlier elements with the same
`data-id` and the same classes.

A plan with three arguments also gets each node, edge, series and label
that has no `data-id`, such as a line of a mindmap, with `nil` as its
`data-id`. The classes `pele-node`, `pele-edge`, `pele-series` and
`pele-label` give these four kinds. The count of such an element is the
number of earlier elements of its kind with no `data-id`, whatever their
other classes. A label is different: its count is the number of earlier
labels in a group with the same classes, and the plan gets the classes of
that group after the classes of the label, such as `pele-point-labels`. The
plan returns the name `nil` for an element that keeps no name.

The functions of this module make the marks:

| Function | Marks |
| --- | --- |
| `node/1` | `data-graph-kind="node"`, and `data-graph-parent` |
| `container/1` | `data-graph-kind="container"`, and `data-graph-parent` |
| `edges/1` | `data-graph-kind="edge"`, `data-graph-from`, `data-graph-to`, `data-graph-arrow` and `data-graph-label` |

# `edge`

```elixir
@type edge() :: %{
  key: String.t(),
  from: String.t(),
  to: String.t(),
  arrow: String.t(),
  label: String.t() | nil,
  name: String.t() | nil
}
```

An edge of a model: its key, which is its `data-id` in the SVG, its two ends,
its arrow, its label, and the name that the source gives it, or `nil`

# `part`

```elixir
@type part() :: {String.t() | nil, [{String.t(), String.t()}]}
```

The name of an element and its marks

# `t`

```elixir
@type t() ::
  (String.t(), [String.t()] -&gt; part())
  | (String.t() | nil, [String.t()], non_neg_integer() -&gt; part())
```

The function of a plan: the `data-id` and the classes of an element give its
part. A function with three arguments takes the number of earlier elements
with the same `data-id` and the same classes too.

# `plan`

```elixir
@callback plan(model :: map()) :: t()
```

Make the function of a plan from the model of a diagram

# `container`

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

The marks of a container, with its parent or `nil`

# `edges`

```elixir
@spec edges([edge()]) :: %{required(String.t()) =&gt; part()}
```

The name and the marks of each edge, by its key

An edge without a name gets its two ends and its arrow, such as `web->api`.
A second edge between the same ends gets `:2` after its name, as for
Graphviz and D2.

    iex> edges = [
    ...>   %{key: "e0", from: "a", to: "b", arrow: "->", label: nil, name: nil},
    ...>   %{key: "e1", from: "a", to: "b", arrow: "->", label: "again", name: nil}
    ...> ]
    iex> Expresso.Element.Diagram.Pele.Plan.edges(edges)["e1"]
    {"a->b:2", [{"data-graph-kind", "edge"}, {"data-graph-from", "a"}, {"data-graph-to", "b"}, {"data-graph-arrow", "->"}, {"data-graph-label", "again"}]}

# `node`

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

The marks of a node, with its parent or `nil`

# `numbered`

```elixir
@spec numbered([String.t()], String.t()) :: %{required(String.t()) =&gt; String.t()}
```

The name of each element of a list in order, with a prefix and a number from 1

    iex> Expresso.Element.Diagram.Pele.Plan.numbered(["i6", "i9"], "note")
    %{"i6" => "note1", "i9" => "note2"}

# `plain`

```elixir
@spec plain() :: t()
```

The plan of a type with no plan: each element keeps its `data-id`, with no marks

---

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