Drafter.Widget.Gauge (drafter v0.3.1)

Copy Markdown View Source

A semi-circular gauge chart rendered using Unicode braille characters.

The arc spans 260° (from ~8 o'clock to ~4 o'clock through the top). The filled portion is coloured green below the low threshold, orange between thresholds, and red above the high threshold. The unfilled track is rendered in dim grey. The numeric percentage is displayed centred below the arc.

Component tag

Tag :gauge, built by Drafter.App as {:gauge, opts}:

gauge(opts)

There is no positional argument; every prop comes from opts.

Options

  • :value - float in 0.0..1.0. Default 0.0. Shown as round(value * 100)%
  • :label - String.t/0 title displayed on a row above the arc. Default nil, which reclaims that row for the arc
  • :low_threshold - fraction where the colour changes to :mid_color. Default 0.8
  • :high_threshold - fraction where the colour changes to :high_color. Default 0.9
  • :low_color - {r, g, b} for the low range. Default {80, 200, 80}
  • :mid_color - {r, g, b} for the mid range. Default {220, 140, 0}
  • :high_color - {r, g, b} for the high range. Default {220, 60, 60}
  • :track_color - {r, g, b} for the unfilled arc. Default {55, 55, 55}
  • :renderer - :text (default) draws braille cells; any terminal graphics protocol atom transmits the arc as an image, falling back to cells when that protocol is unavailable
  • :height - read only by preferred_height/2, never by mount/1. Default 5

update/2 re-reads only :value, :label and :renderer; the thresholds and every colour are mount-only. Through the component tree a re-render narrows that further to :value and :label, so :renderer is mount-only there too.

Widget value

Drafter.get_widget_value/1 is not implemented for this widget and returns nil.

Data channel

When the widget is declared with a data buffer, apply_data_buffer/3 sets :value to the last item in the buffer and ignores everything before it.

Usage

gauge(value: 0.72)
gauge(value: cpu_usage, label: "CPU", low_threshold: 0.6, high_threshold: 0.8)

Summary

Functions

Sets :value to the newest item in the widget's data buffer.

The registry tag for this widget.

Turns the {:gauge, opts} element into a props map for mount/1. The positional argument is ignored.

Bubbles every event; the gauge is not focusable and consumes no input.

Whether this gauge is drawing a transmitted image rather than braille cells.

Builds the gauge state from props.

opts[:height], or 5 when it is absent.

Draws the gauge into rect, returning exactly rect.height strips.

Callback implementation for Drafter.Widget.unmount/1.

Folds fresh props into state, re-reading only :value, :label and :renderer.

Narrows the props a re-render feeds to update/2 to :value and :label, so :renderer, the thresholds and the colours stay as mounted.

Types

rgb()

@type rgb() :: {0..255, 0..255, 0..255}

t()

@type t() :: %Drafter.Widget.Gauge{
  high_color: rgb(),
  high_threshold: float(),
  label: String.t() | nil,
  low_color: rgb(),
  low_threshold: float(),
  mid_color: rgb(),
  renderer: atom(),
  track_color: rgb(),
  value: float()
}

Functions

apply_data_buffer(state, buffer, rect)

@spec apply_data_buffer(t(), Drafter.RingBuffer.t(), Drafter.Widget.rect()) :: t()

Sets :value to the newest item in the widget's data buffer.

Everything buffered before the last item is discarded. An empty buffer leaves the state alone.

component_tag()

@spec component_tag() :: :gauge

The registry tag for this widget.

iex> Drafter.Widget.Gauge.component_tag()
:gauge

focused(state)

from_component_opts(args, opts)

@spec from_component_opts(
  term(),
  keyword()
) :: Drafter.Widget.props()

Turns the {:gauge, opts} element into a props map for mount/1. The positional argument is ignored.

iex> props = Drafter.Widget.Gauge.from_component_opts(nil, value: 0.5, label: "CPU")
iex> {props.value, props.label, props.low_threshold, props.renderer}
{0.5, "CPU", 0.8, :text}

handle_event(event, state)

@spec handle_event(Drafter.Event.t(), t()) :: {:bubble, t()}

Bubbles every event; the gauge is not focusable and consumes no input.

iex> g = Drafter.Widget.Gauge.mount(%{})
iex> Drafter.Widget.Gauge.handle_event({:key, :enter}, g) |> elem(0)
:bubble

image_active?(state)

@spec image_active?(t()) :: boolean()

Whether this gauge is drawing a transmitted image rather than braille cells.

mount(props)

@spec mount(Drafter.Widget.props()) :: t()

Builds the gauge state from props.

iex> g = Drafter.Widget.Gauge.mount(%{value: 0.72, label: "CPU"})
iex> {g.value, g.label, g.low_threshold, g.high_threshold, g.renderer}
{0.72, "CPU", 0.8, 0.9, :text}

iex> g = Drafter.Widget.Gauge.mount(%{})
iex> {g.value, g.label, g.low_color, g.mid_color, g.high_color, g.track_color}
{0.0, nil, {80, 200, 80}, {220, 140, 0}, {220, 60, 60}, {55, 55, 55}}

preferred_height(args, opts)

@spec preferred_height(
  term(),
  keyword()
) :: pos_integer()

opts[:height], or 5 when it is absent.

iex> Drafter.Widget.Gauge.preferred_height(nil, [])
5

iex> Drafter.Widget.Gauge.preferred_height(nil, height: 9)
9

render(state, rect)

@spec render(t(), Drafter.Widget.rect()) :: [Drafter.Draw.Strip.t()]

Draws the gauge into rect, returning exactly rect.height strips.

With renderer: :text, or with a graphics protocol the terminal does not support, the arc is drawn as braille cells and the percentage is overlaid on the row that falls just below the arc's centre. Otherwise blank rows are emitted for the image the widget server transmits separately, with the percentage on the last row. A :label takes the first row in either case.

unmount(state)

Callback implementation for Drafter.Widget.unmount/1.

update(props, state)

@spec update(Drafter.Widget.props(), t()) :: t()

Folds fresh props into state, re-reading only :value, :label and :renderer.

The thresholds and every colour keep the values they were mounted with, whatever props contains.

iex> g = Drafter.Widget.Gauge.mount(%{value: 0.1})
iex> updated = Drafter.Widget.Gauge.update(%{value: 0.9, high_threshold: 0.5}, g)
iex> {updated.value, updated.high_threshold}
{0.9, 0.9}

update_props_from_mount(mount_props, existing_state, opts)

@spec update_props_from_mount(Drafter.Widget.props(), t(), keyword()) ::
  Drafter.Widget.props()

Narrows the props a re-render feeds to update/2 to :value and :label, so :renderer, the thresholds and the colours stay as mounted.