rcbench
Servo and ESC test bench: panel, IOmcu and shared C
Loading...
Searching...
No Matches
ui_plot.h File Reference

A multi-series plot on one time base, with a scale per series. More...

#include <stdbool.h>
#include <stdint.h>
#include "gfx.h"
#include "ui_layout.h"

Go to the source code of this file.

Data Structures

struct  ui_plot_series_t
struct  ui_plot_t

Macros

#define UI_PLOT_MAX_SERIES   6
 The most series one plot draws.
#define UI_PLOT_HISTORY   UI_PANEL_W
 The samples a series keeps: one per pixel column of a plot as wide as the panel, UI_PANEL_W, 1,024. At 20 samples a second that is 51.2s; a plot of the ring's 6 series takes 24,576B for it.

Functions

float ui_plot_nice_ceil (float v)
 Round v up to 1, 1.2, 1.5, 2, 2.5, 3, 4, 5, 6, 8 or 10 times a power of ten.
void ui_plot_init (ui_plot_t *p, const ui_plot_series_t *series, int count, float span_s)
 An empty, running plot of series.
void ui_plot_push (ui_plot_t *p, const float *values)
 Push one sample per series, newest last.
void ui_plot_set_running (ui_plot_t *p, bool running)
 Start or stop the trace. Stopping holds it; starting does not clear it.
void ui_plot_clear (ui_plot_t *p)
 Drop every sample and return each scale to its floor. Keeps the series, the time base, the focus and what is hidden.
float ui_plot_sample (const ui_plot_t *p, int series, int back)
 A sample of a series.
void ui_plot_update_scales (ui_plot_t *p, int visible_samples)
 Recompute the scales.
void ui_plot_touch_series (ui_plot_t *p, int series)
 Tap a legend chip: focus it, or hide it if it was already focused.
int ui_plot_map_y (const ui_plot_t *p, int series, float value, int y0, int h)
 Where value lands inside a plot h tall.
void ui_plot_render (const ui_plot_t *p, gfx_canvas_t *c, gfx_rect_t r)
 The plot body: grid, traces, the focused series' scale. One sample a pixel column, in the first UI_PLOT_HISTORY columns from the left edge, the newest in the last of them.
void ui_plot_render_legend (const ui_plot_t *p, gfx_canvas_t *c, gfx_rect_t r)
 A row of swatch + name + full scale, one entry per series.

Detailed Description

A multi-series plot on one time base, with a scale per series.

Voltage, current, power and rpm (revolutions per minute) differ by three orders of magnitude and cannot share a Y axis. Tick labels for four scales would take a third of the plot width, so the scales are shown two ways: the legend prints each series' full scale beside its name, and the focused series prints its full scale and zero inside the plot in its own colour.

State lives in the caller's struct rather than in file statics, so a screen that wants a plot owns one. The motor, supply and servo screens do.

SPDX-License-Identifier: MIT

Function Documentation

◆ ui_plot_clear()

void ui_plot_clear ( ui_plot_t * p)

Drop every sample and return each scale to its floor. Keeps the series, the time base, the focus and what is hidden.

Parameters
pThe plot.

◆ ui_plot_init()

void ui_plot_init ( ui_plot_t * p,
const ui_plot_series_t * series,
int count,
float span_s )

An empty, running plot of series.

Parameters
pThe plot.
seriesThe series, copied.
countHow many, at most UI_PLOT_MAX_SERIES.
span_sThe width of the time base, for the axis label.

◆ ui_plot_map_y()

int ui_plot_map_y ( const ui_plot_t * p,
int series,
float value,
int y0,
int h )

Where value lands inside a plot h tall.

Parameters
pThe plot.
seriesThe series whose scale it is on.
valueThe value.
y0The plot's top.
hThe plot's height.
Returns
The row, clamped to the box.

◆ ui_plot_nice_ceil()

float ui_plot_nice_ceil ( float v)

Round v up to 1, 1.2, 1.5, 2, 2.5, 3, 4, 5, 6, 8 or 10 times a power of ten.

The finer steps keep a 6S pack (25.2V) on a 0 to 30V scale rather than the 0 to 50V a 1/2/5 ladder gives.

Parameters
vThe value.
Returns
The step at or above it.

◆ ui_plot_push()

void ui_plot_push ( ui_plot_t * p,
const float * values )

Push one sample per series, newest last.

A non-finite value is a gap: not drawn and not in the autorange. A stopped plot counts the call and drops the sample.

Parameters
pThe plot.
valuesOne value per series: count of them.

◆ ui_plot_render()

void ui_plot_render ( const ui_plot_t * p,
gfx_canvas_t * c,
gfx_rect_t r )

The plot body: grid, traces, the focused series' scale. One sample a pixel column, in the first UI_PLOT_HISTORY columns from the left edge, the newest in the last of them.

Parameters
pThe plot.
cCanvas.
rThe plot's box.

◆ ui_plot_render_legend()

void ui_plot_render_legend ( const ui_plot_t * p,
gfx_canvas_t * c,
gfx_rect_t r )

A row of swatch + name + full scale, one entry per series.

Parameters
pThe plot.
cCanvas.
rThe legend's row.

◆ ui_plot_sample()

float ui_plot_sample ( const ui_plot_t * p,
int series,
int back )

A sample of a series.

Parameters
pThe plot.
seriesThe series.
backHow far back: the newest is 0.
Returns
The sample; 0 for one that has not arrived or out of range, and not-a-number for a gap pushed as a non-finite value.

◆ ui_plot_set_running()

void ui_plot_set_running ( ui_plot_t * p,
bool running )

Start or stop the trace. Stopping holds it; starting does not clear it.

Two calls rather than one setter that also empties the ring: this widget has no idea what a run is, and a start that silently wiped the samples would be a trap for the next caller that wanted to resume one.

Parameters
pThe plot.
runningWhether the trace advances.

◆ ui_plot_touch_series()

void ui_plot_touch_series ( ui_plot_t * p,
int series )

Tap a legend chip: focus it, or hide it if it was already focused.

Parameters
pThe plot.
seriesThe series of the chip.

◆ ui_plot_update_scales()

void ui_plot_update_scales ( ui_plot_t * p,
int visible_samples )

Recompute the scales.

A scale grows immediately and shrinks only after 60 consecutive samples (3s at 20Hz) below it, so a brief spike does not rescale the plot twice.

Parameters
pThe plot.
visible_samplesThe newest samples the plot shows.