The nodes and edges of a canvas.
graph =
Hakushi.Graph.new(
nodes: [
%{id: "users", type: "table", x: 0, y: 0, data: %{name: "users"}},
%{id: "orders", type: "table", x: 320, y: 40, data: %{name: "orders"}}
],
edges: [%{source: "orders", source_handle: "user_id", target: "users", target_handle: "id"}]
)A graph keeps the order of its nodes, which is the order in which they are drawn: a node drawn later is over the ones before it. New nodes go last.
apply/2 applies a Hakushi.Change and gives back the change that
undoes it; the canvas uses it for every change, and so can the app, to
keep its own copy of the graph or to save it.
paper is the canvas's paper when it has one of its own (people chose
it with the canvas's picker, or the app did): a Hakushi.Paper, or nil
for the canvas's background and grid.
Summary
Functions
Applies a change. Gives back the graph, the change as it applied, and the change that undoes it
The box around the nodes, {x, y, width, height}, or nil for a graph
without nodes. A node without a size counts as a point.
The ids of the nodes in a node (its children), in the order they are drawn.
The ids of the nodes in a node, and in those, all the way down, in the order they are drawn.
What changed from one graph to another: the nodes and edges that are new or not the same, the ids of those that went away, and whether the paper changed.
The graph as JSON-able maps, with string keys: for a column of the
app's database (see Hakushi.Graph.Type) or a file. data goes as it
is, so it must be JSON-able itself.
The edge of an id, or nil.
The edges, in the order they were made.
The edges of a node: those that start or end at it.
Makes a graph of nodes and edges: Hakushi.Nodes and
Hakushi.Edges, or maps and keyword lists for Hakushi.Node.new/1 and
Hakushi.Edge.new/1, and its paper (see Hakushi.Paper.new/1).
Raises on two nodes or two edges with one id, and on an edge to a node
the graph does not have.
The node of an id, or nil.
The nodes, in the order they are drawn.
Types
@type reason() :: :missing | :exists | :locked | :dangling | :nested
Why a change does not apply.
@type t() :: %Hakushi.Graph{ edge_order: [Hakushi.Edge.id()], edges: %{required(Hakushi.Edge.id()) => Hakushi.Edge.t()}, node_order: [Hakushi.Node.id()], nodes: %{required(Hakushi.Node.id()) => Hakushi.Node.t()}, paper: Hakushi.Paper.t() | nil }
Functions
@spec apply(t(), Hakushi.Change.t()) :: {:ok, t(), Hakushi.Change.t(), Hakushi.Change.t()} | {:error, reason(), String.t()}
Applies a change. Gives back the graph, the change as it applied, and the change that undoes it:
- a move of a node moves the nodes in it (
parent) too, unless the change places them itself, and a move may put a node in a group or take it out (:parent); the change lists every node it moved; - a delete lists the nodes in its nodes, and the edges of all of them, which go with them;
- the change that undoes a delete adds the nodes back, with their edges (over the other nodes, as new nodes are).
A change does not apply, and nothing changes, when it names a node or an
edge that the graph does not have (:missing), adds one it has
(:exists), moves, resizes or deletes a locked node (:locked), or
adds an edge to a node it does not have, or a node to a parent it does
not have (:dangling), or puts a node in itself or in a node inside it
(:nested). The error has the id.
The box around the nodes, {x, y, width, height}, or nil for a graph
without nodes. A node without a size counts as a point.
@spec children(t(), Hakushi.Node.id()) :: [Hakushi.Node.id()]
The ids of the nodes in a node (its children), in the order they are drawn.
@spec descendants(t(), Hakushi.Node.id()) :: [Hakushi.Node.id()]
The ids of the nodes in a node, and in those, all the way down, in the order they are drawn.
@spec diff(t(), t()) :: %{ nodes: [Hakushi.Node.t()], edges: [Hakushi.Edge.t()], deleted_nodes: [Hakushi.Node.id()], deleted_edges: [Hakushi.Edge.id()], paper: boolean() }
What changed from one graph to another: the nodes and edges that are new or not the same, the ids of those that went away, and whether the paper changed.
The graph as JSON-able maps, with string keys: for a column of the
app's database (see Hakushi.Graph.Type) or a file. data goes as it
is, so it must be JSON-able itself.
@spec edge(t(), Hakushi.Edge.id()) :: Hakushi.Edge.t() | nil
The edge of an id, or nil.
@spec edges(t()) :: [Hakushi.Edge.t()]
The edges, in the order they were made.
@spec edges_of(t(), Hakushi.Node.id()) :: [Hakushi.Edge.t()]
The edges of a node: those that start or end at it.
The graph of dump/1's maps.
Makes a graph of nodes and edges: Hakushi.Nodes and
Hakushi.Edges, or maps and keyword lists for Hakushi.Node.new/1 and
Hakushi.Edge.new/1, and its paper (see Hakushi.Paper.new/1).
Raises on two nodes or two edges with one id, and on an edge to a node
the graph does not have.
@spec node(t(), Hakushi.Node.id()) :: Hakushi.Node.t() | nil
The node of an id, or nil.
@spec nodes(t()) :: [Hakushi.Node.t()]
The nodes, in the order they are drawn.