# orca.graph

> A module of morca's API.

A directed graph drawn as SVG, on the server: the pipelines and datasets that feed each other, and a snapshot's lineage.

Nodes are laid out top to bottom, a row of boxes per level: a node's level
is its longest path from a node with no edge in (such a node itself just
above the first node it points to), and arrows point down. A level holds at
most `PER_ROW` boxes side by side and wraps onto more rows, so the drawing
is about as wide as a phone and grows downward with the graph's depth. In a
level, nodes are ordered by where the nodes pointing to them are, then as
given, which keeps most arrows short and uncrossed. Each node is a box with a
label, a second line, a kind (`dataset`, `pipeline` or `snapshot`, which
the stylesheet shapes) and optionally a link and a class, such as `start`
for the snapshot a lineage page is about. Edges that close a cycle
(a pipeline that reads the dataset it writes, `back_edges`) are drawn round
the right-hand side, back up, and don't move a node down.

## Structs

### `Node`

```mojo
struct Node
```

Implements: `Copyable`, `Movable`

Fields:

- `label: String`
- `sub: String`
- `kind: String`
- `href: String`: Empty for no link.
- `cls: String`: An extra class, or empty.
- `title: String`: Its tooltip; empty for the label and the second line.

#### `__init__`

```mojo
def __init__(out self, label: String, sub: String, kind: String, href: String, cls: String, title: String = "")
```

### `Edge`

```mojo
struct Edge
```

Implements: `Copyable`, `Movable`

Fields:

- `src: Int`
- `dst: Int`

## Functions

### `back_edges`

```mojo
def back_edges(n: Int, edges: List[Edge]) -> List[Bool]
```

Which edges close a cycle: those a depth-first walk, from each node in the order given, finds pointing back to a node it is still inside. Without them the graph has no cycle.

### `graph_svg`

```mojo
def graph_svg(nodes: List[Node], edges: List[Edge], label: String) -> String
```

The graph as an `<svg>` element, sized to fit; `label` names it for screen readers.

## Aliases

### `PER_ROW`

```mojo
comptime PER_ROW = 2
```

Boxes side by side at most: two fit a phone's width.
