The stack of styles at one site (spec/14 §18.18).
§3.6 gives every style site a stack — a reference, an inline node, or a list of either. This is the control over it: one row per entry in resolution order, the first applied first and the last winning, because that is the order the cascade is defined in and a panel that reversed it would teach the opposite of the specification.
A row is the control, as a layer row is (§18.17): it carries the click and the drag
itself, because a <button> spanning a draggable row defeats both gestures. Each row can
be selected, removed, and dragged to a position.
An inline entry is drawn as local: it is where an edit at the site lands, there is at
most one, and it is created on first edit rather than sitting empty in every document
(D-98).
This module compiles only when Phoenix.Component is loaded (spec/10 §1.1, D-45, D-85).
Summary
Functions
The names a style entry may take, grouped (spec/14 §18.14, §18.18, #685): what the stacked design declares, then the theme's palette group by group — the built-in four are its furniture.
The columns a site's data has, offered by + field (spec/14 §18.18, #686): the declared
fields of the source the node's data names, and the columns of pool's rows for it,
sorted; none where the node binds no source.
A style value as the rows to draw (spec/14 §18.18).
The generators a builder knows, offered by + generator (spec/14 §18.18, #686): the
registry of modules and the host's configuration, each as {name, arguments} — its
arity less the context — by name.
Which entry supplied each key of the resolved style (spec/14 §18.19), by its path: a
whole element's key by its key, a part's by part.key — one part is often several
entries' (a stroke's color from series, its width from local).
Renders the stack at a site (spec/10 §15.3).
The site's stack cascaded in its parts, as the panel shows it (spec/14 §18.19, D-178).
Types
@type entry() :: %{ index: non_neg_integer(), name: String.t(), local: boolean(), default: boolean() }
One row of the stack: what it is, what to call it, and where it sits.
Functions
@spec choices(map(), Visualize.Theme.t()) :: [{String.t(), [atom()]}]
The names a style entry may take, grouped (spec/14 §18.14, §18.18, #685): what the stacked design declares, then the theme's palette group by group — the built-in four are its furniture.
iex> choices = Visualize.Chart.Builder.StyleStack.choices(%{styles: %{series: %{}}}, Visualize.Theme.default())
iex> hd(choices)
{"design", [:series]}
iex> {"furniture", furniture} = List.keyfind(choices, "furniture", 0)
iex> Enum.all?([:axis, :grid, :label, :title], &(&1 in furniture))
true
The columns a site's data has, offered by + field (spec/14 §18.18, #686): the declared
fields of the source the node's data names, and the columns of pool's rows for it,
sorted; none where the node binds no source.
iex> design = %{sources: %{"load" => %{fields: ["t", "v"]}}}
iex> Visualize.Chart.Builder.StyleStack.columns(design, %{data: "load"}, %{load: [%{t: 0, v: 1, host: "a"}]})
["host", "t", "v"]
iex> Visualize.Chart.Builder.StyleStack.columns(%{}, %{}, %{})
[]
A style value as the rows to draw (spec/14 §18.18).
Total over the three shapes of §3.6, and over a site that carries no style key at all:
the schema's default for that site is shown as the row it will resolve as, marked
default: true so the panel can say it is not something the design states.
iex> Visualize.Chart.Builder.StyleStack.entries(:series, nil)
[%{index: 0, name: "series", kind: :name, local: false, default: false}]
iex> Visualize.Chart.Builder.StyleStack.entries([:series, {:field, :health}, {:generate, :tenant_style, [{:field, :tenant}]}, %{stroke: %{width: 5}}], nil)
[
%{index: 0, name: "series", kind: :name, local: false, default: false},
%{index: 1, name: "field health", kind: :field, local: false, default: false},
%{index: 2, name: "generate tenant_style(field tenant)", kind: :generator, local: false, default: false},
%{index: 3, name: "local", kind: :local, local: true, default: false}
]
iex> Visualize.Chart.Builder.StyleStack.entries(nil, :label)
[%{index: 0, name: "label", kind: :name, local: false, default: true}]
iex> Visualize.Chart.Builder.StyleStack.entries(nil, nil)
[]
@spec generators([module()]) :: [{atom(), non_neg_integer()}]
The generators a builder knows, offered by + generator (spec/14 §18.18, #686): the
registry of modules and the host's configuration, each as {name, arguments} — its
arity less the context — by name.
@spec origins(map(), term(), Visualize.Theme.t()) :: %{ required(atom() | String.t()) => String.t() }
Which entry supplied each key of the resolved style (spec/14 §18.19), by its path: a
whole element's key by its key, a part's by part.key — one part is often several
entries' (a stroke's color from series, its width from local).
A resolved style is a cascade, so a value belongs to the last entry that set it. This is
Visualize.Chart.explain/1's question asked at a site: which style said this.
iex> design = %{styles: %{series: %{stroke: "#111", stroke_width: 2}, faded: %{opacity: 0.5}}}
iex> Visualize.Chart.Builder.StyleStack.origins(design, [:series, :faded, %{stroke: %{width: 5}}], Visualize.Theme.default())
%{:opacity => "faded", "stroke.color" => "series", "stroke.type" => "series", "stroke.width" => "local"}
Renders the stack at a site (spec/10 §15.3).
An <ol class="vis-builder-style-stack"> carrying BuilderHook at scope style, with
one <li class="vis-builder-style-entry"> per entry at its zero-based position.
Attributes
id(:string) (required) - the hook element's id.value(:any) - the site'sstylevalue, in any shape of §3.6. Defaults tonil.fallback(:atom) - the schema's default for this site. Defaults tonil.design(:map) - the stacked design, for the names on offer. Defaults to%{}.theme(:any) - the theme whose palette is on offer; the default's when nil. Defaults tonil.columns(:list) - the columns the site's data has, for + field. Defaults to[].generators(:list) - the generators the builder knows,{name, arguments}, for + generator. Defaults to[].open(:integer) - the entry the context panel is on. Defaults tonil.target(:any) - thephx-targetof the panel's events. Defaults tonil.class(:string) - appended to the panel's class. Defaults tonil.
@spec resolved(map(), term(), Visualize.Theme.t()) :: map()
The site's stack cascaded in its parts, as the panel shows it (spec/14 §18.19, D-178).
The design's declared styles over the palette of theme — the design's own, the one
its chart is drawn with (#685) — then the entries resolved left
to right by §3.6 and merged part by part by §3.5 — Visualize.Chart.Style's own rule,
asked here for one site, before any projection onto the element keys. A field entry
and a generator lay nothing, since the panel has no datum to read.
iex> design = %{styles: %{series: %{stroke: "#111", stroke_width: 2}}}
iex> Visualize.Chart.Builder.StyleStack.resolved(design, [:series, %{stroke: %{width: 5}}], Visualize.Theme.default())
%{stroke: %{type: :solid, color: "#111", width: 5}}