# `AshNeo4j.Mermaid`
[🔗](https://github.com/diffo-dev/ash_neo4j/blob/v0.10.1/lib/mermaid.ex#L5)

Render a graph query result as a [Mermaid flowchart](https://mermaid.js.org/syntax/flowchart.html)
string.

The input is what `AshNeo4j.Cypher.run/2` (and `AshNeo4j.Neo4jHelper`) return —
a `%Bolty.Response{}` or the `{:ok, response}` tuple. The output is a plain
string, with no `Kino` dependency, so it renders anywhere a Mermaid flowchart
is accepted: `Kino.Mermaid.new/1` in the AshNeo4j livebook, Artefact import, or
a Markdown fence.

Graph values in the result rows are rendered structurally:

- `%Bolty.Types.Node{}` → a flowchart node `n<id>["Label<br/>key: value"]`,
  showing its labels and stored (graph, not Ash-cast) properties.
- `%Bolty.Types.Relationship{}` → a directed edge `n<start> -->|TYPE| n<end>`.
- `%Bolty.Types.Path{}` → its nodes and relationships, with edge direction
  reconstructed from the path's traversal sequence.

Nodes are de-duplicated by graph id, so the same node returned in several rows
appears once. Scalars (strings, numbers, points, …) in the result are ignored —
only graph entities are drawn.

## Options

- `:direction` — flowchart direction, `"TD"` (default), `"LR"`, `"BT"`, `"RL"`.
- `:properties` — `true` (default, all stored properties), `false` (labels
  only), or a list of property names to keep, in that order.

## Examples
```
iex> node = %Bolty.Types.Node{id: 0, labels: ["Person"], properties: %{"name" => "Bill"}}
iex> AshNeo4j.Mermaid.flowchart(%Bolty.Response{results: [%{"n" => node}]})
"flowchart TD\n    n0[\"Person<br/>name: Bill\"]"

iex> a = %Bolty.Types.Node{id: 1, labels: ["Person"], properties: %{}}
iex> b = %Bolty.Types.Node{id: 2, labels: ["Movie"], properties: %{}}
iex> r = %Bolty.Types.Relationship{id: 9, type: "ACTED_IN", start: 1, end: 2}
iex> AshNeo4j.Mermaid.flowchart({:ok, %Bolty.Response{results: [%{"a" => a, "r" => r, "b" => b}]}})
"flowchart TD\n    n1[\"Person\"]\n    n2[\"Movie\"]\n    n1 -->|ACTED_IN| n2"

iex> node = %Bolty.Types.Node{id: 0, labels: ["Person"], properties: %{"name" => "Bill"}}
iex> AshNeo4j.Mermaid.flowchart(%Bolty.Response{results: [%{"n" => node}]}, properties: false)
"flowchart TD\n    n0[\"Person\"]"
```

# `flowchart`

```elixir
@spec flowchart(
  Bolty.Response.t() | {:ok, Bolty.Response.t()} | {:error, term()} | list(),
  keyword()
) :: String.t()
```

Renders a graph result as a Mermaid flowchart string. See the module docs for
accepted inputs and options.

# `last`

```elixir
@spec last(keyword()) :: String.t()
```

Renders the most recently captured query result as a flowchart string.

Requires a prior `tap/0` and at least one successful query since. `opts` are
passed to `flowchart/2`. Raises if nothing has been captured.

# `tap`

```elixir
@spec tap() :: :ok
```

Starts capturing the most recent query result, for `last/1`.

Attaches a `[:ash_neo4j, :query]` telemetry handler (see `AshNeo4j.Cypher.run/2`)
that stashes the most recent successful `%Bolty.Response{}` *containing graph
entities* (nodes/relationships/paths) in a small `Agent` — so a plain scalar or
stat query between graph queries won't clobber the captured view. Idempotent.
Pair with `untap/0`. Intended for interactive use (livebook, IEx); the rest of
the library never attaches a handler, so without `tap/0` the seam costs nothing.

## Example
    AshNeo4j.Mermaid.tap()
    AshNeo4j.Cypher.run("MATCH (n:Person)-[r]->(m) RETURN n, r, m")
    AshNeo4j.Mermaid.last() |> Kino.Mermaid.new()

# `untap`

```elixir
@spec untap() :: :ok
```

Stops capturing: detaches the telemetry handler and discards the stashed result.
Idempotent.

---

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