Mark types that render as annotations (rules, bands) rather than data layers.
Mark types that render as annotations (rules, bands) rather than data layers.
(check-type-override! option-key written ds col)Report a type override the column cannot carry out, naming the option and the column rather than dying in the scale several stages later.
:categorical is the override that does something: every value can
be the name of a group, so a column of numbers, dates or strings can
all be read as categories, and reading numbers that way -- hours,
years, identifiers -- is why the option exists.
The other two only ever confirm what the column already holds. There
is no number in "setosa" and no instant either, so :numerical on
a column of strings has nothing to read, and neither has :temporal
on a column of numbers. Both used to reach the cast, which reported
a String or a LocalDate and named neither the column nor the option
that sent it there.
Report a type override the column cannot carry out, naming the option and the column rather than dying in the scale several stages later. `:categorical` is the override that does something: every value can be the name of a group, so a column of numbers, dates or strings can all be read as categories, and reading numbers that way -- hours, years, identifiers -- is why the option exists. The other two only ever confirm what the column already holds. There is no number in "setosa" and no instant either, so `:numerical` on a column of strings has nothing to read, and neither has `:temporal` on a column of numbers. Both used to reach the cast, which reported a String or a LocalDate and named neither the column nor the option that sent it there.
(column-ref? v)True if v is a column reference (keyword or string). Both keyword and string column names are valid references.
True if v is a column reference (keyword or string). Both keyword and string column names are valid references.
(column-type ds col)Classify a dataset column as :categorical, :numerical, or :temporal.
The column name must literally match a column in the dataset.
Classify a dataset column as `:categorical`, `:numerical`, or `:temporal`. The column name must literally match a column in the dataset.
(composite-draft? x)True if x is a composite draft (a tree of sub-drafts with chrome-spec).
True if x is a composite draft (a tree of sub-drafts with chrome-spec).
(composite-plan? x)True if x is a composite plan (a tree of sub-plots with chrome).
True if x is a composite plan (a tree of sub-plots with chrome).
(cross xs ys)Cartesian product of two sequences.
Cartesian product of two sequences.
(draft? x)True if x is a draft (leaf or composite).
True if x is a draft (leaf or composite).
(epoch-ms->local-date-time ms)The inverse of temporal->epoch-ms, read at UTC -- the offset that
function converts with, so a value round-trips.
Needed wherever an epoch-ms number has to be shown as a date again:
an axis holds epoch-ms, and wadogo's :datetime scale formats
LocalDateTime and refuses a LocalDate.
The inverse of `temporal->epoch-ms`, read at UTC -- the offset that function converts with, so a value round-trips. Needed wherever an epoch-ms number has to be shown as a date again: an axis holds epoch-ms, and wadogo's `:datetime` scale formats `LocalDateTime` and refuses a `LocalDate`.
(format-local-date-time ldt)A LocalDateTime as a date string, dropping a midnight time of day so
a value that began life as a LocalDate reads back as one.
A `LocalDateTime` as a date string, dropping a midnight time of day so a value that began life as a `LocalDate` reads back as one.
(infer-column-types ds v)Detect x and y column types (:categorical, :numerical, :temporal).
Temporal columns are converted to epoch-ms numbers; their original
extents (as LocalDateTime) are preserved for wadogo :datetime ticks.
Returns a map with keys :ds, :x-type, :y-type, :x-temporal?,
:y-temporal?, :x-temporal-extent, :y-temporal-extent,
:x-resolved, :y-resolved.
Detect x and y column types (`:categorical`, `:numerical`, `:temporal`). Temporal columns are converted to epoch-ms numbers; their original extents (as `LocalDateTime`) are preserved for wadogo `:datetime` ticks. Returns a map with keys `:ds`, `:x-type`, `:y-type`, `:x-temporal?`, `:y-temporal?`, `:x-temporal-extent`, `:y-temporal-extent`, `:x-resolved`, `:y-resolved`.
(infer-grouping v color-type color-col color-drawn?)Build the grouping vector from explicit :group and categorical color column. Explicit groups are passed through; categorical color columns are appended. Returns a vector of column references (keywords or strings).
A color column drawn as it stands -- {:color {:column :c :scale false}}, where the column already holds colors -- is not a grouping.
Reading a column through its scale turns each distinct value into a
category and splits the rows into a group per category: the stat is
computed once per group, the legend says which group is which, and a
bar divides its band between them. :scale false says the values are
drawn rather than read, and the library already acts on that by
drawing no legend for them, so no categories come out of the column
and the rows are not split. :size and :alpha have never grouped in
either spelling.
Build the grouping vector from explicit :group and categorical color column.
Explicit groups are passed through; categorical color columns are appended.
Returns a vector of column references (keywords or strings).
A color column drawn as it stands -- `{:color {:column :c :scale
false}}`, where the column already holds colors -- is not a grouping.
Reading a column through its scale turns each distinct value into a
category and splits the rows into a group per category: the stat is
computed once per group, the legend says which group is which, and a
bar divides its band between them. `:scale false` says the values are
drawn rather than read, and the library already acts on that by
drawing no legend for them, so no categories come out of the column
and the rows are not split. `:size` and `:alpha` have never grouped in
either spelling.(infer-layer-type v x-type y-type x-temporal? y-temporal?)Choose mark and stat from column types when the user hasn't specified them. Rules:
x-type/y-type come from infer-column-types, which reports
temporal columns as :numerical (they're stored as epoch-ms);
x-temporal?/y-temporal? flag the original temporal classification.
When the user provides an explicit mark, stat defaults to :identity
unless they also provided an explicit stat.Choose mark and stat from column types when the user hasn't specified them. Rules: - x only, categorical → :rect + :count (bar chart) - x only, non-categorical → :bar + :bin (histogram) - temporal x + numerical y → :line + :identity (time-series line) - categorical x + numerical y → :boxplot + :boxplot (vertical) - numerical x + categorical y → :boxplot + :boxplot (horizontal) - otherwise → :point + :identity (scatter) `x-type`/`y-type` come from `infer-column-types`, which reports temporal columns as `:numerical` (they're stored as epoch-ms); `x-temporal?`/`y-temporal?` flag the original temporal classification. When the user provides an explicit mark, stat defaults to :identity unless they also provided an explicit stat.
(layer-type? x)True if x is a layer-type (mark + stat + position bundle).
True if x is a layer-type (mark + stat + position bundle).
(leaf-draft? x)True if x is a leaf draft (a vector of draft layers + pose-level opts).
True if x is a leaf draft (a vector of draft layers + pose-level opts).
(leaf-plan? x)True if x is a leaf plan (single-pose resolved geometry).
True if x is a leaf plan (single-pose resolved geometry).
(literal-position? v)True of a value that places a mark on its own, as {:x 6.5} does,
rather than naming a column to read one from. Numbers are the whole of
it today; a temporal value is coerced by the scale like any other, so
it counts too.
True of a value that places a mark on its own, as `{:x 6.5}` does,
rather than naming a column to read one from. Numbers are the whole of
it today; a temporal value is coerced by the scale like any other, so
it counts too.(plan-layer? x)True if x is a plan-layer (resolved geometry for one mark).
True if x is a plan-layer (resolved geometry for one mark).
(plan? x)True if x is a plan (leaf or composite).
True if x is a plan (leaf or composite).
The aesthetics whose literal value becomes a constant column before
anything else reads the mapping. Derived from
defaults/aesthetic-registry, which is where a new one is added.
Narrower than the glossary's positional aesthetics: the band bounds place a mark too, but their marks read the value straight from the mapping, so turning it into a column would take it from the only code that wants it.
The aesthetics whose literal value becomes a constant column before anything else reads the mapping. Derived from `defaults/aesthetic-registry`, which is where a new one is added. Narrower than the glossary's positional aesthetics: the band bounds place a mark too, but their marks read the value straight from the mapping, so turning it into a column would take it from the only code that wants it.
(resolve-aesthetics ds v)Classify each aesthetic channel (:color, :size, :alpha, :text) as either a column reference or a fixed value it is drawn as.
The data decides, uniformly: a value is a column reference when
the layer's data carries a column of that exact name, and is drawn
as it stands otherwise. That one rule replaces three that disagreed
-- :color looked the value up, :size and :alpha called anything
keyword-or-string a column without checking, and each was written
out separately here. impl.aesthetics/source is where it now lives,
and impl.pose/validate-columns reports a value that is neither a
column nor something the aesthetic can draw, so nothing arrives here
having failed both readings.
:text keeps the older test on purpose. Its drawn reading exists
only on a layer with no data -- impl.pose/resolve-positional-values
holds it -- and this function is only ever called with a dataset, so
asking the data here would turn a reported mistake into a layer that
draws no labels.
Returns a map with keys :color, :color-is-col?, :color-type, :fixed-color, :size, :size-is-col?, :fixed-size, :alpha, :alpha-is-col?, :fixed-alpha, :text-col, :tooltip-col, :fixed-tooltip.
Classify each aesthetic channel (:color, :size, :alpha, :text) as either a column reference or a fixed value it is drawn as. **The data decides**, uniformly: a value is a column reference when the layer's data carries a column of that exact name, and is drawn as it stands otherwise. That one rule replaces three that disagreed -- `:color` looked the value up, `:size` and `:alpha` called anything keyword-or-string a column without checking, and each was written out separately here. `impl.aesthetics/source` is where it now lives, and `impl.pose/validate-columns` reports a value that is neither a column nor something the aesthetic can draw, so nothing arrives here having failed both readings. `:text` keeps the older test on purpose. Its drawn reading exists only on a layer with no data -- `impl.pose/resolve-positional-values` holds it -- and this function is only ever called with a dataset, so asking the data here would turn a reported mistake into a layer that draws no labels. Returns a map with keys :color, :color-is-col?, :color-type, :fixed-color, :size, :size-is-col?, :fixed-size, :alpha, :alpha-is-col?, :fixed-alpha, :text-col, :tooltip-col, :fixed-tooltip.
(resolve-col-name _ds ref)Look up a column name in a dataset. Returns the name unchanged
whether or not the dataset contains it; the existence check is
informational. Matching is strict: :x does not match a column
literally named "x". The reference and the dataset column name
must be identical (same type, same characters).
Look up a column name in a dataset. Returns the name unchanged whether or not the dataset contains it; the existence check is informational. Matching is strict: `:x` does not match a column literally named `"x"`. The reference and the dataset column name must be identical (same type, same characters).
(resolve-draft-layer v)Resolve a single draft layer: infer column types, aesthetics, grouping, and layer type.
Delegates to infer-column-types, resolve-aesthetics, infer-grouping,
and infer-layer-type — each named for the inference step it performs.
Also normalizes user-facing shorthand options:
:bandwidth → :cfg {:<stat>-bandwidth ...} (routed per stat):tile with :fill → stat :identityResolve a single draft layer: infer column types, aesthetics, grouping, and layer type.
Delegates to `infer-column-types`, `resolve-aesthetics`, `infer-grouping`,
and `infer-layer-type` — each named for the inference step it performs.
Also normalizes user-facing shorthand options:
- `:bandwidth` → `:cfg {:<stat>-bandwidth ...}` (routed per stat)
- `:tile` with `:fill` → stat `:identity`(temporal->epoch-ms v)Convert a temporal value to epoch-milliseconds (double), through the
one reading temporal-readings gives it. Returns ##NaN for nil, and
coerces a number as it stands.
Every type goes by way of LocalDateTime at UTC rather than by a
shortcut of its own: two routes to one number are two things to keep
in step, and this list has already grown past the four it started
with.
Convert a temporal value to epoch-milliseconds (double), through the one reading `temporal-readings` gives it. Returns ##NaN for nil, and coerces a number as it stands. Every type goes by way of `LocalDateTime` at UTC rather than by a shortcut of its own: two routes to one number are two things to keep in step, and this list has already grown past the four it started with.
A temporal value as the LocalDateTime the tick generators read.
impl.temporal/->local-date-time.
A temporal value as the `LocalDateTime` the tick generators read. `impl.temporal/->local-date-time`.
True of a value a temporal axis reads as a date.
impl.temporal/temporal-value?, named here because this namespace is
where most callers already look.
True of a value a temporal axis reads as a date. `impl.temporal/temporal-value?`, named here because this namespace is where most callers already look.
What :x-type, :y-type and :color-type accept.
What `:x-type`, `:y-type` and `:color-type` accept.
(validate-continuous-aesthetics ds v)Throw a clear error when :size, :alpha or :fill names a
categorical column. Without it the column reaches the encoder and
dies casting a string to a number, naming neither the aesthetic nor
the column.
Throw a clear error when `:size`, `:alpha` or `:fill` names a categorical column. Without it the column reaches the encoder and dies casting a string to a number, naming neither the aesthetic nor the column.
(warn-unread-temporal! aesthetic ds col)Report a column of values that name a stretch of time rather than a moment, which an axis reads as categories.
A YearMonth is the one a reader meets: grouping by month is what
->year-month is for, and the column that comes back was drawn with
one tick per value -- a hundred and eighty of them over fifteen
years -- rather than on a calendar axis. Year and MonthDay are
the same shape.
Reported rather than converted. A YearMonth has no instant of its
own, so reading it as the first of the month is a decision, and one
the writer can make in a line. dev-notes/backlog.md holds the
question of whether Plotje should make it.
Report a column of values that name a stretch of time rather than a moment, which an axis reads as categories. A `YearMonth` is the one a reader meets: grouping by month is what `->year-month` is for, and the column that comes back was drawn with one tick per value -- a hundred and eighty of them over fifteen years -- rather than on a calendar axis. `Year` and `MonthDay` are the same shape. Reported rather than converted. A `YearMonth` has no instant of its own, so reading it as the first of the month is a decision, and one the writer can make in a line. `dev-notes/backlog.md` holds the question of whether Plotje should make it.
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 |