# `Drafter.Widget.Chart.Pixel`
[🔗](https://github.com/jaman/drafter/blob/main/lib/drafter/widget/chart/pixel.ex#L1)

Draws a chart as a terminal image, braille or block characters, all from one
drawing of the chart.

A chart `spec` (its type, data and drawing options) is described as shapes in cell
coordinates and painted at the resolution of the output: the terminal's own pixels
per cell for an image sent with kitty, iTerm2 or sixel (`picture/3`), two by four
dots per cell for braille (`braille_strips/2`), or the sub-cell grid of one of
`FrenchCurve.Backend.Cells`' glyph sets (`cells_strips/3`). `mode/2` picks the
output for a renderer setting.

# `drawing`

```elixir
@type drawing() ::
  :pixel | :braille | {:cells, FrenchCurve.Backend.Cells.set()} | :text
```

How a chart or slider draws: an image, braille, block characters of a glyph set, or text.

# `braille_strips`

```elixir
@spec braille_strips(
  map(),
  {pos_integer(), pos_integer()}
) :: [Drafter.Draw.Strip.t()] | nil
```

Renders `spec` as `rows` strips of `cols` braille cells, or `nil` when it cannot be
drawn. Labels the chart places in cells are written over the braille.

# `cell_sets`

```elixir
@spec cell_sets() :: [atom()]
```

The glyph sets accepted as modes, each drawing through `cells_strips/3`.

# `cells_strips`

```elixir
@spec cells_strips(
  map(),
  {pos_integer(), pos_integer()},
  FrenchCurve.Backend.Cells.set()
) ::
  [Drafter.Draw.Strip.t()] | nil
```

Renders `spec` as `rows` strips of `cols` cells in the glyph set `set`, or `nil` when
it cannot be drawn. Labels the chart places in cells are written over the glyphs.

# `mode`

```elixir
@spec mode(atom() | nil, atom()) :: drawing()
```

# `modes`

```elixir
@spec modes() :: [atom()]
```

The list of mode atoms accepted by `:renderer`, `DRAFTER_MODE`, and the `mode:`
run option: `[:auto, :pixel, :kitty, :iterm2, :sixel, :braille, :text, :half, :quad, :sextant, :octant]`.

# `picture`

```elixir
@spec picture(map(), atom() | nil, {pos_integer(), pos_integer()}) ::
  Drafter.Render.Picture.t() | nil
```

Draws `spec` as a `Drafter.Render.Picture` filling a `cols` by `rows` cell box at the
widget's top left, to be drawn with `protocol`.

The image has the terminal's own pixel size per cell: `:cell_size` in `spec`, else
the size the session's terminal reported (`Drafter.Session.Context.cell_size/0`),
else `:scale` pixels across (default `4`) and twice that down. `:overlay` cells in
`spec`, `{col, row, text, fg, bg}`, are drawn over the chart, and `:marker`, a
`{col, color}` pair, shades that column behind it. Returns `nil` when `protocol`
is `nil` or the chart cannot be drawn.

# `protocol`

```elixir
@spec protocol(atom() | nil) :: atom() | nil
```

The graphics protocol to draw with, or `nil` when the terminal has none.

A `renderer` naming a protocol (`:kitty`, `:iterm2`, `:sixel`) is used as given;
any mode that is not `:auto` or `:pixel` has no protocol and returns `nil`.

`:auto` and `:pixel` take what the terminal answered when it was probed at
startup — see `Drafter.Terminal.Probe`. A terminal that was never probed, or
that answered the probe without naming a protocol, is guessed at from its
environment instead, through `FrenchCurve.Capability.detect/1`.

Either way the terminal in question is the one this session is attached to, which
for a session served over ssh or telnet is the connecting client's rather than
the host's.

# `resolve`

```elixir
@spec resolve(atom() | nil) :: atom()
```

Resolve an effective mode from precedence: the `DRAFTER_MODE` env var forces and
wins over everything; otherwise an explicit per-widget `renderer` (any mode atom),
then the runtime `:drafter` `:render_mode` application env, then `:text`.

# `supported`

```elixir
@spec supported() :: [atom()]
```

# `terminal`

```elixir
@spec terminal() :: atom() | nil
```

The graphics protocol of this session's terminal, whatever mode is in force.

What the terminal answered when it was probed at startup, or, when it was never
probed or named no protocol, what its environment suggests through
`FrenchCurve.Capability.detect/1`. `nil` when neither names one. An iTerm2 session is
always judged by its environment, whatever it answered: `:iterm2`, or `:kitty` when
`FRENCH_CURVE_ITERM2=kitty` is set (see `FrenchCurve.Capability`).

# `value_range`

```elixir
@spec value_range(
  map(),
  {pos_integer(), pos_integer()}
) :: {number(), number()} | nil
```

The value range `spec` is drawn against in a `cols` by `rows` box, `{low, high}`, or
`nil` when it cannot be drawn. Axis labels read it.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
