The transform behavior (spec/04 §1.1): one step of a data pipeline, a table in and a table out, declared once so the validator, a drawer's forms and vocabulary, the JSON forms and the sandbox all read the same declaration (visualize#886).
defmodule MyApp.Ops.Clip do
@behaviour Macaw.Data.Transform
alias Macaw.Data.Operations.Option
@impl true
def name, do: "clip"
@impl true
def options, do: [{"field", %Option{type: :field, required: true}}]
@impl true
def needs, do: []
@impl true
def outputs(_node, columns), do: columns
@impl true
def run(node, table, _context), do: ...
endA member is pure and deterministic: no processes, ETS, NIFs, Regex, clock or
randomness. run/3 and outputs/2 are given the node checked
(Macaw.Data.Operations.validate/3): its keys strings, every option present with its
default filled in, an enum value its atom, a frame-bound "plot" already a number.
Summary
Types
Columns in order, each with its Macaw.Data.Table type.
Context a transform may need beyond the data: a drawer's frame, projection, text.
A checked node: the op's options by their strings, each holding its value.
Callbacks
The op a node names, unique in a registry.
The context the op requires beyond the data: [] for a table operation.
Every key the op reads, in order, each declared.
The columns run/3 answers for the node over input columns.
Computed once per design and shared by its marks, under the context's prepared.
A reducer's count option and the rows each unit of it keeps at most (spec/04 §7).
The step: the table after it.
Types
@type columns() :: [{Macaw.Data.Table.name(), Macaw.Data.Table.type()}]
Columns in order, each with its Macaw.Data.Table type.
@type need() :: :frame | :projection | :text
Context a transform may need beyond the data: a drawer's frame, projection, text.
A checked node: the op's options by their strings, each holding its value.
Callbacks
@callback name() :: String.t()
The op a node names, unique in a registry.
@callback needs() :: [need()]
The context the op requires beyond the data: [] for a table operation.
@callback options() :: [{String.t(), Macaw.Data.Operations.Option.t()}]
Every key the op reads, in order, each declared.
The columns run/3 answers for the node over input columns.
@callback prepare([node_map()], Macaw.Data.Table.t(), map()) :: term()
Computed once per design and shared by its marks, under the context's prepared.
@callback reduces() :: {String.t(), pos_integer()}
A reducer's count option and the rows each unit of it keeps at most (spec/04 §7).
@callback run(node_map(), Macaw.Data.Table.t(), map()) :: Macaw.Data.Table.t()
The step: the table after it.