AshNeo4j.Mermaid (AshNeo4j v0.10.1)

Copy Markdown View Source

Render a graph query result as a Mermaid flowchart 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".
  • :propertiestrue (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\"]"

Summary

Functions

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

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

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

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

Functions

flowchart(result, opts \\ [])

@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(opts \\ [])

@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()

@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()

@spec untap() :: :ok

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