Malli schemas for the draft data model -- the records returned by
pj/pose->draft (and pj/draft).
Drafts are the intermediate stage between pose and plan. They are
user-observable (the pj/draft shortcut and the predicates
pj/leaf-draft? / pj/composite-draft? are public) but are
primarily inspected, not traversed programmatically.
DraftLayer models the post-scope-merge layer shape. It takes its
aesthetic value grammar from impl.pose-schema, so the two states
are one description read at two points rather than a copy that can
drift -- which is what an earlier version of this namespace declined
to write down. What the draft adds is
PositionalAestheticsNameColumns: the invariant
impl.pose/resolve-positional-values establishes, which is the one
the appearance aesthetics would extend if they were ever normalized
the same way.
Backend authors who consume drafts directly should rely on
destructuring :layers and :opts on a leaf draft, or
:sub-drafts / :chrome-spec / :layout on a composite, and
apply the layer-type registry to interpret each layer's
:layer-type, :mark, and :stat.
Malli schemas for the draft data model -- the records returned by `pj/pose->draft` (and `pj/draft`). Drafts are the intermediate stage between pose and plan. They are user-observable (the `pj/draft` shortcut and the predicates `pj/leaf-draft?` / `pj/composite-draft?` are public) but are primarily inspected, not traversed programmatically. `DraftLayer` models the post-scope-merge layer shape. It takes its aesthetic value grammar from `impl.pose-schema`, so the two states are one description read at two points rather than a copy that can drift -- which is what an earlier version of this namespace declined to write down. What the draft adds is `PositionalAestheticsNameColumns`: the invariant `impl.pose/resolve-positional-values` establishes, which is the one the appearance aesthetics would extend if they were ever normalized the same way. Backend authors who consume drafts directly should rely on destructuring `:layers` and `:opts` on a leaf draft, or `:sub-drafts` / `:chrome-spec` / `:layout` on a composite, and apply the layer-type registry to interpret each layer's `:layer-type`, `:mark`, and `:stat`.
A composite draft -- produced by pj/pose->draft for a composite
pose. Canonical contract for the CompositeDraft defrecord in
impl/resolve.clj.
Sub-drafts wrap leaf drafts in an envelope (path + rect + opts),
parallel to plan-schema's SubPlot. :chrome-spec is shaped like
CompositeChrome from plan-schema; the chrome-spec on a draft is
the same value that flows through to the plan stage's :chrome.
:layout maps each sub-draft's pose-tree path to its rectangle
inside the composite.
:width, :height and :layout are drawing-space geometry, which
a leaf draft carries none of. The stage boundary is arity rather
than availability: a leaf draft is a vector of per-layer maps with
nowhere to put a fact about the whole plot.
A composite draft -- produced by `pj/pose->draft` for a composite pose. Canonical contract for the `CompositeDraft` defrecord in `impl/resolve.clj`. Sub-drafts wrap leaf drafts in an envelope (path + rect + opts), parallel to plan-schema's SubPlot. `:chrome-spec` is shaped like `CompositeChrome` from plan-schema; the chrome-spec on a draft is the same value that flows through to the plan stage's `:chrome`. `:layout` maps each sub-draft's pose-tree path to its rectangle inside the composite. `:width`, `:height` and `:layout` are drawing-space geometry, which a leaf draft carries none of. The stage boundary is arity rather than availability: a leaf draft is a vector of per-layer maps with nowhere to put a fact about the whole plot.
One element of a draft: a layer type plus every mapping that reached it, plus the data it draws from. Specification, not yet computed.
One element of a draft: a layer type plus every mapping that reached it, plus the data it draws from. Specification, not yet computed.
The keys a draft layer carries, as impl.pose/leaf->draft emits
them. Open on purpose: the merged mapping brings along every layer
option that is not :data, :mark, :stat or :position --
:jitter, :in, :nudge-x, :font-size, :bandwidth and the
rest -- and a layer type's :defaults arrive the same way.
:data is always present and may be nil (an annotation layer that
names no data). :mark and :stat are absent on a layer whose
layer type is still to be inferred: leaf->draft emits the
:infer sentinel and then drops both, leaving the choice to
impl.resolve/infer-layer-type at plan time.
The keys a draft layer carries, as `impl.pose/leaf->draft` emits them. Open on purpose: the merged mapping brings along every layer option that is not `:data`, `:mark`, `:stat` or `:position` -- `:jitter`, `:in`, `:nudge-x`, `:font-size`, `:bandwidth` and the rest -- and a layer type's `:defaults` arrive the same way. `:data` is always present and may be nil (an annotation layer that names no data). `:mark` and `:stat` are absent on a layer whose layer type is still to be inferred: `leaf->draft` emits the `:infer` sentinel and then drops both, leaving the choice to `impl.resolve/infer-layer-type` at plan time.
Top-level draft schema -- accepts either shape.
Top-level draft schema -- accepts either shape.
(explain x)Explain why x does not conform to the draft schema. Returns nil if valid.
Explain why x does not conform to the draft schema. Returns nil if valid.
(explain-layer x)Explain why x does not conform to DraftLayer, or nil if it does.
Explain why x does not conform to `DraftLayer`, or nil if it does.
(layer-valid? x)True if x conforms to DraftLayer. Separate from valid? because
a composite sub-draft's layers are reached without a LeafDraft
wrapper.
True if x conforms to `DraftLayer`. Separate from `valid?` because a composite sub-draft's layers are reached without a `LeafDraft` wrapper.
A leaf draft -- the post-scope-merge intermediate produced by
pj/pose->draft for a leaf pose. Canonical contract for the
LeafDraft defrecord in impl/resolve.clj.
:layers is one DraftLayer per applicable layer, multiplied over
facet values when the leaf is faceted.
A leaf draft -- the post-scope-merge intermediate produced by `pj/pose->draft` for a leaf pose. Canonical contract for the `LeafDraft` defrecord in `impl/resolve.clj`. `:layers` is one `DraftLayer` per applicable layer, multiplied over facet values when the leaf is faceted.
(names-column? layer k)True if a draft layer's k names a column rather than carrying a
literal value. A keyword or a string always counts; anything else
counts when the layer's :data has a column of that name, which is
how an integer column name is written.
True if a draft layer's `k` names a column rather than carrying a literal value. A keyword or a string always counts; anything else counts when the layer's `:data` has a column of that name, which is how an integer column name is written.
In a draft layer that carries data, :x, :y and :x-end all name
columns. impl.pose/resolve-positional-values gets them there: a
literal value beside a column becomes a constant column, and a layer
where every one of them is a literal becomes a one-row dataset. So
the stat, the extract, the domains and every mark see one shape.
The exception is a layer with no data anywhere. There is nothing to
add a column to, so {:x :some-column :y 5} keeps its 5 and
resolves to nothing downstream, as the column reference beside it
does.
In a draft layer that carries data, `:x`, `:y` and `:x-end` all name
columns. `impl.pose/resolve-positional-values` gets them there: a
literal value beside a column becomes a constant column, and a layer
where every one of them is a literal becomes a one-row dataset. So
the stat, the extract, the domains and every mark see one shape.
The exception is a layer with no data anywhere. There is nothing to
add a column to, so `{:x :some-column :y 5}` keeps its 5 and
resolves to nothing downstream, as the column reference beside it
does.One entry in a CompositeDraft's :sub-drafts: a leaf placed at a
pose-tree path with its rect inside the composite, plus per-leaf
:opts (suppress-x-label / suppress-y-label / suppress-legend
flags applied during composite drafting). Parallel to SubPlot
in plan-schema.
Note: :draft here is a bare vector of layer maps (not a
LeafDraft record). Composite sub-drafts skip the LeafDraft
wrapper -- the layers travel directly through the compositor's
per-leaf draft->plan call.
One entry in a CompositeDraft's `:sub-drafts`: a leaf placed at a pose-tree path with its rect inside the composite, plus per-leaf `:opts` (suppress-x-label / suppress-y-label / suppress-legend flags applied during composite drafting). Parallel to `SubPlot` in plan-schema. Note: `:draft` here is a bare vector of layer maps (not a `LeafDraft` record). Composite sub-drafts skip the `LeafDraft` wrapper -- the layers travel directly through the compositor's per-leaf draft->plan call.
(valid? x)True if x conforms to a draft schema (leaf or composite).
True if x conforms to a draft schema (leaf or composite).
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |