Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

The Canvas Widget

The canvas widget provides a low-level drawing surface for custom graphics. You can draw lines, circles, rectangles, points, and text labels at specific coordinates, making it perfect for diagrams, plots, and custom visualizations.

APIs

mod canvas: sig {
    type Bounds = {min: f64, max: f64};
    type Shape = [
        `Line({color: Color, x1: f64, y1: f64, x2: f64, y2: f64}),
        `Circle({color: Color, x: f64, y: f64, radius: f64}),
        `Rectangle({color: Color, x: f64, y: f64, width: f64, height: f64}),
        `Points({color: Color, coords: Array<(f64, f64)>}),
        `Label({line: Line, x: f64, y: f64})
    ];

    /// Creates a canvas widget for custom graphics
    val canvas: fn(
        ?#background_color: &Color,
        ?#marker: &Marker,
        #x_bounds: &Bounds,
        #y_bounds: &Bounds,
        &Array<&Shape>
    ) -> Widget;
}

Parameters

  • background_color - Background color for the canvas
  • marker - Marker type: Dot, Braille (default), or Block
  • x_bounds - X-axis range with min and max fields (required)
  • y_bounds - Y-axis range with min and max fields (required)

Shape Types

Line

`Line({color: `Red, x1: 0.0, y1: 0.0, x2: 10.0, y2: 5.0})

Circle

`Circle({color: `Blue, x: 5.0, y: 5.0, radius: 2.0})

Rectangle

`Rectangle({color: `Green, x: 2.0, y: 2.0, width: 3.0, height: 4.0})

Points

`Points({color: `Yellow, coords: [(1.0, 1.0), (2.0, 3.0), (3.0, 1.5)]})

Label

`Label({line: line("Hello"), x: 5.0, y: 0.5})

Examples

Basic Usage

use tui;
use tui::canvas;

let line = `Line({color: `Red, x1: 0.0, y1: 0.0, x2: 10.0, y2: 5.0});
let circle = `Circle({color: `Blue, x: 5.0, y: 5.0, radius: 2.0});

canvas(
    #x_bounds: &{min: 0.0, max: 10.0},
    #y_bounds: &{min: 0.0, max: 10.0},
    &[&line, &circle]
)

Basic Canvas

Function Plotting

use tui;
use tui::canvas;

let coords = [
    (0.0, 0.0), (0.5, 0.48), (1.0, 0.84), (1.5, 1.0),
    (2.0, 0.91), (2.5, 0.60), (3.0, 0.14), (3.5, -0.35),
    (4.0, -0.76), (4.5, -0.98), (5.0, -0.96)
];

let plot = `Points({color: `Cyan, coords});

canvas(
    #x_bounds: &{min: 0.0, max: 10.0},
    #y_bounds: &{min: -1.0, max: 1.0},
    &[&plot]
)

Scatter Plot

Network Diagram

use tui;
use tui::canvas;
use tui::text;

let circle1 = `Circle({color: `Blue, x: 2.0, y: 5.0, radius: 0.5});
let circle2 = `Circle({color: `Blue, x: 8.0, y: 5.0, radius: 0.5});
let circle3 = `Circle({color: `Blue, x: 5.0, y: 8.0, radius: 0.5});

let line1 = `Line({color: `White, x1: 2.0, y1: 5.0, x2: 8.0, y2: 5.0});
let line2 = `Line({color: `White, x1: 2.0, y1: 5.0, x2: 5.0, y2: 8.0});
let line3 = `Line({color: `White, x1: 8.0, y1: 5.0, x2: 5.0, y2: 8.0});

let all_shapes = [&line1, &line2, &line3, &circle1, &circle2, &circle3];

canvas(
    #x_bounds: &{min: 0.0, max: 10.0},
    #y_bounds: &{min: 0.0, max: 10.0},
    &all_shapes
)

Network Diagram

Animated Graphics

use tui;
use tui::canvas;

let clock = time::timer(duration:0.1s, true);
let x = 0.0;
x <- {
    let new_x = (clock ~ x) + 0.1;
    select new_x > 10.0 { true => 0.0, false => new_x }
};

let moving_circle = `Circle({color: `Red, x, y: 5.0, radius: 1.0});

canvas(
    #x_bounds: &{min: 0.0, max: 10.0},
    #y_bounds: &{min: 0.0, max: 10.0},
    &[&moving_circle]
)

Animated Canvas

Marker Comparison

  • Braille: Highest resolution, smoothest curves, best for detailed graphics
  • Dot: Fast rendering, lower resolution, good for simple shapes
  • Block: High contrast, blocky appearance, good for filled areas

Coordinate System

  • Origin (0, 0) is at the bottom-left
  • X increases to the right
  • Y increases upward
  • Shapes outside bounds are clipped

See Also

  • chart - For pre-built line charts
  • barchart - For bar-based visualizations