Liking cljdoc? Tell your friends :D

scicloj.plotje.impl.compositor

Composite-pose chrome layout, composite-pose->draft, and composite-draft->plan. Pure data-side: shared-scale reconciliation, chrome geometry computation, per-leaf opt adjustment. The plan-to-membrane rendering for composites lives in render/composite.clj, keeping this namespace free of membrane dependencies.

Shared scales are reconciled before drafting by stamping a forced domain on matching leaves (impl.pose/inject-shared-scales).

When the composite root carries a legend-producing mapping (:color/:size/:alpha), the chrome reserves a strip on the right of the grid; the per-leaf opts get :suppress-legend true so each cell hides its own legend, and the rendering side (render/ composite.clj) draws ONE shared legend in the reserved strip.

Composite-pose chrome layout, composite-pose->draft, and
composite-draft->plan. Pure data-side: shared-scale reconciliation,
chrome geometry computation, per-leaf opt adjustment. The
plan-to-membrane rendering for composites lives in
`render/composite.clj`, keeping this namespace free of membrane
dependencies.

Shared scales are reconciled before drafting by stamping a forced
domain on matching leaves (impl.pose/inject-shared-scales).

When the composite root carries a legend-producing mapping
(:color/:size/:alpha), the chrome reserves a strip on the right
of the grid; the per-leaf opts get :suppress-legend true so each
cell hides its own legend, and the rendering side (render/
composite.clj) draws ONE shared legend in the reserved strip.
raw docstring

scicloj.plotje.impl.draft-schema

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. The schemas here document the top-level structure -- the keys on the records themselves -- without enumerating every key a layer map may carry. That post-scope-merge layer shape would essentially duplicate the pose mapping schema in a different state, and the drift risk would outweigh the documentation value.

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. The schemas
here document the top-level structure -- the keys on the records
themselves -- without enumerating every key a layer map may carry.
That post-scope-merge layer shape would essentially duplicate the
pose mapping schema in a different state, and the drift risk
would outweigh the documentation value.

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`.
raw docstring

scicloj.plotje.impl.extract

Extract data-space geometry from resolved draft layers and stat results. Produces layer descriptor maps — plain Clojure maps with mark type, style, and groups of data-space coordinates.

Extract data-space geometry from resolved draft layers and stat results.
Produces layer descriptor maps — plain Clojure maps with mark type,
style, and groups of data-space coordinates.
raw docstring

scicloj.plotje.impl.layout

Layout inference pipeline. Three pure functions turn scene facts and configuration into concrete pixel dimensions.

Under the new semantics, :width and :height in opts mean the TOTAL SVG dimensions. Panel dimensions are derived by subtracting layout overhead (titles, axis labels, legends, facet strips) from the total. :panel-width/:panel-height are escape hatches: when set, they pin the panel size on that axis and :width/:height become the derived total.

The classic width→tick-count→label-width→y-label-pad→panel-width cycle is broken by a single reformulation: max-label-pixel-width runs the tick picker at a pixel budget equal to the user-supplied :height (or :width), not the actual panel size. Label width is monotonic non-decreasing in tick count across every scale type we support (verified at the REPL), so this over-estimate is always safe.

Pipeline:

compute-scene scene data from resolved draft layers + opts (no pixels) compute-padding scene + cfg + opts -> padding map (no pixel dims yet) compute-dims scene + padding + cfg + opts -> pw/ph/total-w/total-h

None of these need actual per-panel tick positions -- the tick budget is baked into y-label-pad in compute-padding via the over-estimate trick. Real per-panel ticks are computed AFTER compute-dims when the final pw/ph are known.

Layout inference pipeline. Three pure functions turn scene facts
and configuration into concrete pixel dimensions.

Under the new semantics, `:width` and `:height` in opts mean the
TOTAL SVG dimensions. Panel dimensions are derived by subtracting
layout overhead (titles, axis labels, legends, facet strips) from
the total. `:panel-width`/`:panel-height` are escape hatches: when
set, they pin the panel size on that axis and `:width`/`:height`
become the derived total.

The classic width→tick-count→label-width→y-label-pad→panel-width
cycle is broken by a single reformulation: `max-label-pixel-width`
runs the tick picker at a pixel budget equal to the user-supplied
`:height` (or `:width`), not the actual panel size. Label width is
monotonic non-decreasing in tick count across every scale type we
support (verified at the REPL), so this over-estimate is always safe.

Pipeline:

  compute-scene    scene data from resolved draft layers + opts (no pixels)
  compute-padding  scene + cfg + opts -> padding map (no pixel dims yet)
  compute-dims     scene + padding + cfg + opts -> pw/ph/total-w/total-h

None of these need actual per-panel tick positions -- the tick
budget is baked into y-label-pad in `compute-padding` via the
over-estimate trick. Real per-panel ticks are computed AFTER
`compute-dims` when the final pw/ph are known.
raw docstring

scicloj.plotje.impl.membrane-schema

Malli schema for the metadata Plotje stamps onto the vector returned by plan->membrane (and so by pj/membrane).

The vector itself is a Membrane drawable tree -- a sequence of things satisfying membrane.ui/IOrigin. That structural contract belongs to Membrane (see membrane.ui protocols) and is not modeled here. This schema is strictly Plotje's own contract: the keys we attach as metadata so that membrane->plot defmethods (and any third-party backend) can read plan-derived dimensions and title without re-walking the tree.

Malli schema for the metadata Plotje stamps onto the vector
returned by `plan->membrane` (and so by `pj/membrane`).

The vector itself is a Membrane drawable tree -- a sequence of
things satisfying `membrane.ui/IOrigin`. That structural contract
belongs to Membrane (see `membrane.ui` protocols) and is not
modeled here. This schema is strictly Plotje's own contract: the
keys we attach as metadata so that `membrane->plot` defmethods
(and any third-party backend) can read plan-derived dimensions
and title without re-walking the tree.
raw docstring

scicloj.plotje.impl.plan

Draft-to-plan pipeline: domains, ticks, legends, layout, and grid inference. Takes draft maps (from pose/leaf->draft) and produces a Plan record with all geometry needed for rendering.

Draft-to-plan pipeline: domains, ticks, legends, layout, and grid inference.
Takes draft maps (from pose/leaf->draft) and produces a Plan record
with all geometry needed for rendering.
raw docstring

scicloj.plotje.impl.pose

Pose substrate -- the recursive plain-map type that is the library's spec vocabulary. This namespace holds the pure tree operations (resolve, layout, shared-scale injection) and the leaf->draft emitter that feeds plan.clj.

Shape of a pose: {:data ? dataset (inherited from ancestor if absent) :mapping ? aesthetic mappings (merges with ancestors) :layers ? layers at this level (accumulate into leaves) :poses ? sub-poses; absence = leaf :layout ? {:direction :horizontal|:vertical :weights [pos-num ...]} :opts ? plot options (inheritable) :share-scales ? #{:x :y} for composites}

Pose substrate -- the recursive plain-map type that is the
library's spec vocabulary. This namespace holds the pure tree
operations (resolve, layout, shared-scale injection) and the
leaf->draft emitter that feeds plan.clj.

Shape of a pose:
  {:data         ?  dataset (inherited from ancestor if absent)
   :mapping      ?  aesthetic mappings (merges with ancestors)
   :layers       ?  layers at this level (accumulate into leaves)
   :poses       ?  sub-poses; absence = leaf
   :layout       ?  {:direction :horizontal|:vertical
                     :weights   [pos-num ...]}
   :opts         ?  plot options (inheritable)
   :share-scales ?  #{:x :y}  for composites}
raw docstring

scicloj.plotje.impl.pose-schema

Malli schema for the Pose data model.

A pose is a plain recursive map. A leaf pose has no :poses (or an empty :poses vector). A composite pose has :poses and an optional :layout describing how sub-poses tile a bounding rectangle.

Validation is not wired into any runtime path yet; Phase 6 of the pre-alpha refactor adds validation at public API boundaries. Until then, impl.pose operates on structurally-valid poses by convention; this schema is the authoritative definition of that convention.

Decisions made in Phase 2:

  • A leaf with no :data and no :mapping is valid -- leaves inherit context from ancestors via impl.pose/resolve-tree.
  • :share-scales is structurally allowed on any pose; it is a no-op on leaves (nothing to share).
  • :layout :weights length is not required to equal (count :poses); impl.pose/compute-layout tolerates short/long weight vectors.
Malli schema for the Pose data model.

A pose is a plain recursive map. A leaf pose has no :poses (or
an empty :poses vector). A composite pose has :poses and an
optional :layout describing how sub-poses tile a bounding
rectangle.

Validation is not wired into any runtime path yet; Phase 6 of the
pre-alpha refactor adds validation at public API boundaries. Until
then, impl.pose operates on structurally-valid poses by convention;
this schema is the authoritative definition of that convention.

Decisions made in Phase 2:
- A leaf with no :data and no :mapping is valid -- leaves inherit
  context from ancestors via impl.pose/resolve-tree.
- :share-scales is structurally allowed on any pose; it is a no-op
  on leaves (nothing to share).
- :layout :weights length is not required to equal (count :poses);
  impl.pose/compute-layout tolerates short/long weight vectors.
raw docstring

scicloj.plotje.impl.position

Position adjustment — composable transforms on layer descriptors. Runs between extract-layer and build-panels in the plan pipeline.

Position types: :identity — no adjustment (default) :dodge — side-by-side within a categorical band (annotation) :stack — cumulative y-values across groups (data transform) :fill — normalized cumulative y, sums to 1.0 (data transform)

Position adjustment — composable transforms on layer descriptors.
Runs between extract-layer and build-panels in the plan pipeline.

Position types:
  :identity — no adjustment (default)
  :dodge    — side-by-side within a categorical band (annotation)
  :stack    — cumulative y-values across groups (data transform)
  :fill     — normalized cumulative y, sums to 1.0 (data transform)
raw docstring

scicloj.plotje.layer-type

Layer-type registry — keyword → layer-type map (mark + stat + position). Layer types are plain data maps. The registry makes them discoverable and extensible. Use lookup to get a layer type by keyword, registered to enumerate all layer types, and register! to add new ones.

Layer-type registry — keyword → layer-type map (mark + stat + position).
Layer types are plain data maps. The registry makes them discoverable
and extensible. Use `lookup` to get a layer type by keyword, `registered`
to enumerate all layer types, and `register!` to add new ones.
raw docstring

scicloj.plotje.render.bufimg

Render membrane drawable trees to java.awt.image.BufferedImage via membrane's Java2D backend. Faster than SVG for large plots and produces raster output that Clay renders automatically.

Render membrane drawable trees to java.awt.image.BufferedImage via
membrane's Java2D backend. Faster than SVG for large plots and
produces raster output that Clay renders automatically.
raw docstring

scicloj.plotje.render.composite

Composite plan -> membrane rendering. The CompositePlan dispatch of the plan->membrane multimethod, plus the membrane drawables for composite chrome (title, strip labels, shared legend).

Pure data-side composite logic -- chrome geometry, layout computation, composite-pose->draft, composite-draft->plan -- stays in impl/compositor.clj. This namespace only handles the rendering side and depends on membrane, keeping impl/ free of membrane dependencies.

Composite plan -> membrane rendering. The CompositePlan dispatch of
the plan->membrane multimethod, plus the membrane drawables for
composite chrome (title, strip labels, shared legend).

Pure data-side composite logic -- chrome geometry, layout
computation, composite-pose->draft, composite-draft->plan -- stays
in `impl/compositor.clj`. This namespace only handles the rendering
side and depends on membrane, keeping `impl/` free of membrane
dependencies.
raw docstring

No vars found in this namespace.

scicloj.plotje.render.membrane

Build a membrane drawable tree from a plan. Plan → membrane is format-agnostic: the drawable tree can be converted to SVG, PNG, or any other format membrane supports.

Build a membrane drawable tree from a plan.
Plan → membrane is format-agnostic: the drawable tree can be converted
to SVG, PNG, or any other format membrane supports.
raw docstring

scicloj.plotje.render.svg

Convert membrane drawable trees to SVG hiccup.

Convert membrane drawable trees to SVG hiccup.
raw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close