Visualize.Chart.Builder.Chain (Visualize v0.8.1)

Copy Markdown View Source

A typed color as a chain: a base, then the transforms applied to it in order (spec/14 §19.10, D-178).

A color a design writes as color(:red) |> shade(700) |> alpha(0.8) is the term {:alpha, {:shade, {:color, :red}, 700}, 0.8}: transforms nested inside out. The picker shows it the way it reads — the base red, then shade 700, then alpha 0.8 — and edits it step by step: a step added at the end, an amount changed, a step removed, the base replaced with the steps kept. Every edit is a function of the value to the value, so what the picker builds is exactly the term Visualize.Color's helpers would.

A blend is a base whose operands are chains of their own, addressed by a path of operand positions: [] is the color itself, [1] the blend's second operand, [1, 0] the first operand of a blend that operand is.

Summary

Types

One step after the base: a transform and its amount, or :contrast.

Functions

The color at path in a chain — a blend's operand — or nil.

The color with one edit made at the chain path addresses ([] the color itself, an operand's position into a blend at each level)

A base and steps joined back into the color they mean; split/1's inverse.

A color picked for a field that holds current (spec/14 §19.10): where current is a chain with steps, the picked color is its new base and the steps are kept; otherwise the picked color is the whole value.

The chain as the picker draws it: the base's word and color, and after each step the color reached so far, each resolved through theme in :literal mode — nil where a name the value reads is not the theme's.

The span a step's amount takes: {min, max, step}.

A color as its base and its steps, in the order they are applied.

The steps the picker offers, in order.

Types

step()

@type step() :: {atom(), number()} | :contrast

One step after the base: a transform and its amount, or :contrast.

Functions

at(value, list)

@spec at(term(), [non_neg_integer()]) :: term()

The color at path in a chain — a blend's operand — or nil.

edit(value, path, change)

@spec edit(term(), [non_neg_integer()], term()) :: term()

The color with one edit made at the chain path addresses ([] the color itself, an operand's position into a blend at each level):

  • {:add, op} — a step at the end, at its starting amount; :blend makes the color the first operand of a blend with the theme's background;

  • {:amount, i, n} — step i's amount;

  • {:remove, i} — step i taken out;

  • {:base, base} — the base replaced, the steps kept;

  • {:operand, :add} / {:operand, {:remove, i}} — a blend's operands.

    iex> alias Visualize.Chart.Builder.Chain iex> red = {:color, :red} iex> red |> Chain.edit([], {:add, :shade}) |> Chain.edit([], {:amount, 0, 700}) |> Chain.edit([], {:add, :alpha}) {:alpha, {:shade, {:color, :red}, 700}, 0.5} iex> Chain.edit({:alpha, {:color, :red}, 0.5}, [], {:base, {:color, :blue}}) {:alpha, {:color, :blue}, 0.5} iex> Chain.edit({:color, :red}, [], {:add, :blend}) {:blend, [{:color, :red}, {:color, :background}]} iex> Chain.edit({:blend, [{:color, :red}, {:color, :blue}]}, [1], {:add, :intensity}) {:blend, [{:color, :red}, {:intensity, {:color, :blue}, 0.5}]}

join(base, steps)

@spec join(term(), [step()]) :: term()

A base and steps joined back into the color they mean; split/1's inverse.

iex> Visualize.Chart.Builder.Chain.join({:color, :red}, [{:shade, 700}, {:alpha, 0.8}])
{:alpha, {:shade, {:color, :red}, 700}, 0.8}

rebase(current, picked)

@spec rebase(term(), term()) :: term()

A color picked for a field that holds current (spec/14 §19.10): where current is a chain with steps, the picked color is its new base and the steps are kept; otherwise the picked color is the whole value.

iex> Visualize.Chart.Builder.Chain.rebase({:alpha, {:color, :red}, 0.5}, {:color, :blue})
{:alpha, {:color, :blue}, 0.5}

iex> Visualize.Chart.Builder.Chain.rebase({:color, :red}, "#123456")
"#123456"

rows(value, theme)

@spec rows(term(), Visualize.Theme.t() | nil) :: [map()]

The chain as the picker draws it: the base's word and color, and after each step the color reached so far, each resolved through theme in :literal mode — nil where a name the value reads is not the theme's.

iex> theme = Visualize.Theme.default()
iex> [base, step] = Visualize.Chart.Builder.Chain.rows({:alpha, "#ff0000", 0.5}, theme)
iex> {base.word, base.color, step.word, step.color}
{"#ff0000", "#ff0000", "alpha", "#ff000080"}

span(arg1)

@spec span(atom()) :: {number(), number(), number()}

The span a step's amount takes: {min, max, step}.

iex> Visualize.Chart.Builder.Chain.span(:shade)
{0, 1000, 50}

iex> Visualize.Chart.Builder.Chain.span(:alpha)
{0, 1, 0.05}

split(base)

@spec split(term()) :: {term(), [step()]}

A color as its base and its steps, in the order they are applied.

iex> Visualize.Chart.Builder.Chain.split({:alpha, {:shade, {:color, :red}, 700}, 0.8})
{{:color, :red}, [{:shade, 700}, {:alpha, 0.8}]}

iex> Visualize.Chart.Builder.Chain.split({:contrast, {:color, :bad}})
{{:color, :bad}, [:contrast]}

iex> Visualize.Chart.Builder.Chain.split("#abc")
{"#abc", []}

steps()

@spec steps() :: [atom(), ...]

The steps the picker offers, in order.