Render sparklines, line charts, candlestick charts, and bar charts directly in the terminal using Unicode block and braille characters with ANSI colors.
Pure Rust, zero dependencies. All chart types produce plain strings with embedded ANSI codes, composable with any TUI framework.
Feature clone of termchart.
Add to your Cargo.toml:
[dependencies]
plot = { version = "0.1", path = "../plot" }use plot::{spark, Bar, Orientation, Line, Candle, Color};
// Sparkline
println!("{}", spark(&[1.0, 3.0, 7.0, 2.0, 5.0, 8.0], Some(82)));
// Output: ▁▃█▂▅█ (in green)Compact single-line visualization using eighth-block characters (\u{2581}\u{2582}\u{2583}\u{2584}\u{2585}\u{2586}\u{2587}\u{2588}).
use plot::spark;
let s = spark(&[1.0, 4.0, 7.0, 2.0, 8.0, 3.0, 6.0, 9.0, 5.0], Some(82));
println!("{}", s);
// ▁▃▆▂█▃▅█▄- 8 levels of vertical resolution
- Optional 256-color
- Handles empty data and flat values (all same)
Horizontal and vertical bars with sub-cell 1/8th precision.
use plot::{Bar, Orientation};
// Horizontal
let mut bar = Bar::new(50, Orientation::Horizontal);
bar.add("Rust", 95.0, Some(208));
bar.add("Go", 78.0, Some(81));
bar.add("Python", 85.0, Some(226));
bar.add("Ruby", 72.0, Some(196));
println!("{}", bar.render()); Rust \u{2502}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588} 95
Go \u{2502}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{258E} 78
Python \u{2502}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588} 85
Ruby \u{2502}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{2588}\u{258A} 72
// Vertical
let mut vbar = Bar::new(30, Orientation::Vertical);
vbar.set_height(10);
vbar.add("Q1", 80.0, Some(82));
vbar.add("Q2", 95.0, Some(82));
vbar.add("Q3", 60.0, Some(196));
vbar.add("Q4", 110.0, Some(82));
println!("{}", vbar.render());High-resolution braille dot plotting (2x4 dots per character cell) with Y-axis labels and multi-series legend.
use plot::Line;
let mut chart = Line::new(60, 15);
chart.add(&[10.0, 15.0, 12.0, 20.0, 18.0, 25.0, 22.0, 30.0], 82, Some("Price"));
chart.add(&[5.0, 8.0, 10.0, 7.0, 12.0, 9.0, 15.0, 11.0], 226, Some("Volume"));
println!("{}", chart.render());- Braille characters (U+2800-U+28FF) for 2x resolution horizontally, 4x vertically
- Bresenham line algorithm for smooth connections
- Y-axis with min/mid/max labels
- Multi-series support with colored legend
OHLC (Open-High-Low-Close) financial charts with green (up) and red (down) candles.
use plot::Candle;
use plot::candle::OhlcBar;
let mut chart = Candle::new(50, 15);
chart.add(&[
OhlcBar { o: 100.0, h: 105.0, l: 98.0, c: 103.0 },
OhlcBar { o: 103.0, h: 107.0, l: 101.0, c: 99.0 },
OhlcBar { o: 99.0, h: 104.0, l: 97.0, c: 102.0 },
OhlcBar { o: 102.0, h: 110.0, l: 100.0, c: 108.0 },
]);
println!("{}", chart.render());- Wicks:
\u{2502}(thin vertical) - Bodies:
\u{2588}(full block) for range,\u{2500}(horizontal line) for doji - Green (82) for up candles, Red (196) for down
- Y-axis with 5 price levels
- Auto-limits visible candles to fit chart width
use plot::Color;
// 256-color palette (0-255)
let c = Color::Index(82); // green
// RGB hex
let c = Color::from_str("#FF0000").unwrap(); // red RGB
let c = Color::from_str("00FF00").unwrap(); // green RGB
// Named colors (matching termchart)
let c = Color::from_str("red").unwrap(); // → Index(196)
let c = Color::from_str("green").unwrap(); // → Index(82)
let c = Color::from_str("blue").unwrap(); // → Index(33)
let c = Color::from_str("yellow").unwrap(); // → Index(226)
let c = Color::from_str("cyan").unwrap(); // → Index(51)
let c = Color::from_str("magenta").unwrap(); // → Index(201)
let c = Color::from_str("white").unwrap(); // → Index(255)
let c = Color::from_str("gray").unwrap(); // → Index(245)
let c = Color::from_str("orange").unwrap(); // → Index(208)For custom chart types, use the Canvas and BrailleCanvas directly:
use plot::{Canvas, BrailleCanvas};
// Simple character canvas
let mut c = Canvas::new(20, 5);
c.set(0, 0, "#", Some(196), None); // red '#' at top-left
println!("{}", c.render());
// High-resolution braille canvas
let mut bc = BrailleCanvas::new(40, 10);
// Resolution: 80x40 pixels (2x4 dots per character)
bc.set_dot(10, 5, Some(82)); // green dot at pixel (10,5)
println!("{}", bc.render());| Type | Constructor | Methods |
|---|---|---|
spark() |
spark(values, color) |
Returns String |
spark_color() |
spark_color(values, color) |
Color enum variant |
Bar |
Bar::new(width, orientation) |
add(label, value, color), set_height(h), render() |
Line |
Line::new(width, height) |
add(values, color, label), render() |
Candle |
Candle::new(width, height) |
add(bars), render() |
Canvas |
Canvas::new(w, h) |
set(x,y,ch,fg,bg), get(x,y), render() |
BrailleCanvas |
BrailleCanvas::new(w, h) |
set_dot(px,py,fg), px_width(), px_height(), render() |
Color |
Color::Index(u8), Color::Rgb(r,g,b) |
from_str(s), fg_code(), bg_code() |
| Chart | Characters | Description |
|---|---|---|
| Sparkline | \u{2581}\u{2582}\u{2583}\u{2584}\u{2585}\u{2586}\u{2587}\u{2588} |
Eighth-height blocks (8 levels) |
| Bar (H) | \u{258F}\u{258E}\u{258D}\u{258C}\u{258B}\u{258A}\u{2589}\u{2588} |
Eighth-width blocks (8 levels) |
| Bar (V) | \u{2581}\u{2582}\u{2583}\u{2584}\u{2585}\u{2586}\u{2587}\u{2588} |
Eighth-height blocks (8 levels) |
| Line | U+2800-U+28FF | Braille patterns (2x4 dots per cell) |
| Candle | \u{2502} \u{2500} \u{2588} |
Wick, doji, body |
| Y-axis | \u{2524} \u{2502} |
Label marker, vertical line |
| Tool | Clones | Type |
|---|---|---|
| rush | rsh | Shell |
| crust | rcurses | TUI library |
| glow | termpix | Image display |
| plot | termchart | Charts |
| pointer | RTFM | File manager |
| kastrup | Heathrow | Messaging |
| tock | Timely | Calendar |
| scroll | brrowser | Browser |
Unlicense - public domain.
Created by Geir Isene (https://isene.org) with extensive pair-programming with Claude Code.