cstat/demo_glossary.rs
Zachery Aaron Shores-Chmielewski cced49e3ed Archive overcomplicated workspace, restore legacy cstat at root
The milestone-1 multi-crate representation stack overshot the goal.
Move it to archive/overcomplicated/ to keep for reference, and bring
the original single-package cstat back to /workspace as the active
codebase. Also commit demo_glossary.rs and ignore the build binary
plus .loop/.stash/.

Authored by Claude, lovingly guided by Zachery Aaron Shores-Chmielewski
2026-07-12 11:00:45 +04:00

2123 lines
86 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// rustc demo_glossary.rs -o demo_glossary && ./demo_glossary
// Full glossary of terminal rendering primitives
fn main() {
println!("\n{}", "═".repeat(70));
println!(" TERMINAL RENDERING GLOSSARY — COMPLETE CATALOG");
println!("{}\n", "═".repeat(70));
section_pixel_blocks();
section_line_drawing();
section_color_and_style();
section_palettes();
section_chart_primitives();
section_text_symbols();
section_layout_patterns();
section_terminal_features();
section_distribution_viz();
section_comparison_viz();
section_relational_viz();
section_matrix_grid_viz();
section_part_to_whole_viz();
section_temporal_viz();
section_text_integrated_viz();
}
// ── Helpers ──────────────────────────────────────────────────────────
fn fg(r: u8, g: u8, b: u8, text: &str) -> String {
format!("\x1b[38;2;{};{};{}m{}\x1b[0m", r, g, b, text)
}
fn bg(r: u8, g: u8, b: u8, text: &str) -> String {
format!("\x1b[48;2;{};{};{}m{}\x1b[0m", r, g, b, text)
}
fn fgbg(fr: u8, fgg: u8, fb: u8, br: u8, bgg: u8, bb: u8, text: &str) -> String {
format!("\x1b[38;2;{};{};{}m\x1b[48;2;{};{};{}m{}\x1b[0m", fr, fgg, fb, br, bgg, bb, text)
}
fn lerp(c1: (u8,u8,u8), c2: (u8,u8,u8), t: f64) -> (u8,u8,u8) {
let t = t.clamp(0.0, 1.0);
(
(c1.0 as f64 + (c2.0 as f64 - c1.0 as f64) * t) as u8,
(c1.1 as f64 + (c2.1 as f64 - c1.1 as f64) * t) as u8,
(c1.2 as f64 + (c2.2 as f64 - c1.2 as f64) * t) as u8,
)
}
fn heat(t: f64) -> (u8,u8,u8) {
if t < 0.5 { lerp((80,200,120),(240,200,60),t*2.0) }
else { lerp((240,200,60),(220,60,60),(t-0.5)*2.0) }
}
fn viridis(t: f64) -> (u8,u8,u8) {
let t = t.clamp(0.0, 1.0);
let s = [(0.0,(68,1,84)),(0.25,(59,82,139)),(0.5,(33,145,140)),(0.75,(94,201,98)),(1.0,(253,231,37))];
for i in 0..s.len()-1 { if t <= s[i+1].0 { return lerp(s[i].1,s[i+1].1,(t-s[i].0)/(s[i+1].0-s[i].0)); } }
s[4].1
}
fn magma(t: f64) -> (u8,u8,u8) {
let t = t.clamp(0.0, 1.0);
let s = [(0.0,(0,0,4)),(0.25,(81,18,124)),(0.5,(183,55,121)),(0.75,(252,137,97)),(1.0,(252,253,191))];
for i in 0..s.len()-1 { if t <= s[i+1].0 { return lerp(s[i].1,s[i+1].1,(t-s[i].0)/(s[i+1].0-s[i].0)); } }
s[4].1
}
fn inferno(t: f64) -> (u8,u8,u8) {
let t = t.clamp(0.0, 1.0);
let s = [(0.0,(0,0,4)),(0.25,(87,16,110)),(0.5,(188,55,84)),(0.75,(249,142,9)),(1.0,(252,255,164))];
for i in 0..s.len()-1 { if t <= s[i+1].0 { return lerp(s[i].1,s[i+1].1,(t-s[i].0)/(s[i+1].0-s[i].0)); } }
s[4].1
}
fn plasma(t: f64) -> (u8,u8,u8) {
let t = t.clamp(0.0, 1.0);
let s = [(0.0,(13,8,135)),(0.25,(126,3,168)),(0.5,(204,71,120)),(0.75,(248,149,64)),(1.0,(240,249,33))];
for i in 0..s.len()-1 { if t <= s[i+1].0 { return lerp(s[i].1,s[i+1].1,(t-s[i].0)/(s[i+1].0-s[i].0)); } }
s[4].1
}
fn cividis(t: f64) -> (u8,u8,u8) {
let t = t.clamp(0.0, 1.0);
let s = [(0.0,(0,32,77)),(0.25,(60,77,110)),(0.5,(127,127,127)),(0.75,(186,173,107)),(1.0,(255,234,70))];
for i in 0..s.len()-1 { if t <= s[i+1].0 { return lerp(s[i].1,s[i+1].1,(t-s[i].0)/(s[i+1].0-s[i].0)); } }
s[4].1
}
fn coolwarm(t: f64) -> (u8,u8,u8) {
let t = t.clamp(0.0, 1.0);
let s = [(0.0,(59,76,192)),(0.25,(124,159,230)),(0.5,(221,221,221)),(0.75,(230,145,113)),(1.0,(180,4,38))];
for i in 0..s.len()-1 { if t <= s[i+1].0 { return lerp(s[i].1,s[i+1].1,(t-s[i].0)/(s[i+1].0-s[i].0)); } }
s[4].1
}
fn turbo(t: f64) -> (u8,u8,u8) {
let t = t.clamp(0.0, 1.0);
let s = [(0.0,(48,18,59)),(0.17,(69,117,180)),(0.33,(64,190,166)),(0.5,(145,224,79)),(0.67,(241,187,41)),(0.83,(237,105,37)),(1.0,(122,4,3))];
for i in 0..s.len()-1 { if t <= s[i+1].0 { return lerp(s[i].1,s[i+1].1,(t-s[i].0)/(s[i+1].0-s[i].0)); } }
s[6].1
}
fn heading(id: &str, title: &str) {
println!("\n\x1b[1;96m╔{}╗\x1b[0m", "═".repeat(68));
println!("\x1b[1;96m║\x1b[0m \x1b[1;97m{}\x1b[0m. \x1b[1;93m{:<62}\x1b[0m\x1b[1;96m║\x1b[0m", id, title);
println!("\x1b[1;96m╚{}╝\x1b[0m\n", "═".repeat(68));
}
fn sub(id: &str, name: &str, desc: &str) {
println!(" \x1b[1;33m{}.\x1b[0m \x1b[1m{}\x1b[0m", id, name);
println!(" \x1b[2m{}\x1b[0m", desc);
}
// =====================================================================
// A. PIXEL/BLOCK ELEMENTS
// =====================================================================
fn section_pixel_blocks() {
heading("A", "PIXEL / BLOCK ELEMENTS");
// A1: Horizontal fractional blocks
sub("A1", "Horizontal Fractional Blocks", "Sub-character bar precision (8 levels per cell)");
println!(" chars: █ ▉ ▊ ▋ ▌ ▍ ▎ ▏");
print!(" demo: ");
let fracs = ['█','▉','▊','▋','▌','▍','▎','▏'];
for (i, &c) in fracs.iter().enumerate() {
let t = i as f64 / 7.0;
let (r,g,b) = heat(1.0 - t);
print!("{}", fg(r,g,b, &format!("{} ", c)));
}
println!();
print!(" bar: ");
for i in 0..30 {
let t = i as f64 / 29.0;
let (r,g,b) = viridis(t);
print!("{}", fg(r,g,b,"█"));
}
print!("{}",fg(94,201,98,"▌"));
println!(" ← fractional end cap");
println!();
// A2: Vertical block elements (sparkline chars)
sub("A2", "Vertical Block Elements", "Height encoding (8 levels per cell, used in sparklines)");
println!(" chars: ▁ ▂ ▃ ▄ ▅ ▆ ▇ █");
let vblocks = ['▁','▂','▃','▄','▅','▆','▇','█'];
print!(" demo: ");
let vals = [1,3,5,8,6,4,7,8,5,3,2,4,6,8,7,5,3,2,1,3,5,7,8,6,4,2,1,2,4,6];
for &v in &vals {
let t = v as f64 / 8.0;
let (r,g,b) = heat(t);
print!("{}", fg(r,g,b, &vblocks[(v-1) as usize].to_string()));
}
println!();
println!();
// A3: Half blocks
sub("A3", "Half Blocks (▀ ▄)", "2 vertical pixels per cell — doubles vertical resolution");
println!(" chars: ▀ (upper) ▄ (lower) █ (both)");
print!(" demo: ");
// Show a mini gradient with 2 rows packed per line
for i in 0..30 {
let t_top = i as f64 / 29.0;
let t_bot = (i as f64 + 0.5) / 29.0;
let top = viridis(t_top);
let bot = viridis(t_bot.min(1.0));
print!("{}", fgbg(top.0,top.1,top.2, bot.0,bot.1,bot.2, "▀"));
}
println!(" ← 2 color rows in 1 line");
// Show as mini heatmap
print!(" matrix: ");
let cells = [[0.1,0.3,0.8,0.9],[0.2,0.5,0.7,0.4],[0.6,0.2,0.1,0.3],[0.9,0.8,0.4,0.2]];
for pair in cells.chunks(2) {
for col in 0..4 {
let top = viridis(pair[0][col]);
let bot = if pair.len() > 1 { viridis(pair[1][col]) } else { (0,0,0) };
print!("{}", fgbg(top.0,top.1,top.2, bot.0,bot.1,bot.2, "▀▀"));
}
print!(" ");
}
println!("← 4×4 matrix in 2 lines");
println!();
// A4: Quadrant blocks
sub("A4", "Quadrant Blocks", "2×2 pixel grid per cell (4 sub-pixels)");
println!(" chars: ▖ ▗ ▘ ▙ ▚ ▛ ▜ ▝ ▌ ▐ ▀ ▄ █ (space)");
let quads = [' ','▘','▝','▀','▖','▌','▞','▛','▗','▚','▐','▜','▄','▙','▟','█'];
print!(" all: ");
for (i, &q) in quads.iter().enumerate() {
let t = i as f64 / 15.0;
let (r,g,b) = viridis(t);
print!("{}", fg(r,g,b, &format!("{} ", q)));
}
println!();
print!(" pattern:");
let pattern = "▘▀▜█▛▀▘ ▖▄▟█▙▄▖ ";
for ch in pattern.chars() {
print!("{}", fg(100,180,255, &ch.to_string()));
}
println!();
println!();
// A5: Braille patterns
sub("A5", "Braille Patterns", "2×4 pixel grid per cell (8 sub-pixels, 256 combinations)");
println!(" base: U+2800, bits: ⠁⠂⠄⡀ (left col) ⠈⠐⠠⢀ (right col)");
print!(" gradient: ");
let braille_densities: [u8; 9] = [0x00, 0x40, 0x44, 0x64, 0x66, 0x76, 0x77, 0xF7, 0xFF];
for &b in &braille_densities {
let ch = char::from_u32(0x2800 + b as u32).unwrap();
print!("{} ", fg(100,180,255, &ch.to_string()));
}
println!(" (empty → full)");
// Mini scatter
print!(" scatter: ");
let mut seed: u64 = 42;
let mut canvas = [[0u8; 25]; 6]; // 6 rows × 25 cols of braille cells
for _ in 0..120 {
seed = seed.wrapping_mul(6364136223846793005).wrapping_add(1);
let x = ((seed >> 33) as f64 / u32::MAX as f64 * 50.0) as usize; // pixel x
seed = seed.wrapping_mul(6364136223846793005).wrapping_add(1);
let raw_y = (seed >> 33) as f64 / u32::MAX as f64;
let y = (raw_y * raw_y * 24.0) as usize; // pixel y, clustered low
let cx = x / 2; let cy = y / 4;
if cx < 25 && cy < 6 {
let lx = x % 2; let ly = y % 4;
let bit = match (lx, ly) { (0,0)=>0,(0,1)=>1,(0,2)=>2,(0,3)=>6,(1,0)=>3,(1,1)=>4,(1,2)=>5,(1,3)=>7,_=>0 };
canvas[cy][cx] |= 1 << bit;
}
}
for row in 0..6 {
if row > 0 { print!(" "); }
for col in 0..25 {
let ch = char::from_u32(0x2800 + canvas[row][col] as u32).unwrap();
if canvas[row][col] == 0 { print!("\x1b[2m·\x1b[0m"); }
else { print!("{}", fg(80,200,120, &ch.to_string())); }
}
println!();
}
println!();
// A6: Shade blocks
sub("A6", "Shade/Fill Blocks", "4 density levels for area fills and backgrounds");
println!(" chars: ░ (light 25%) ▒ (medium 50%) ▓ (dark 75%) █ (full)");
print!(" demo: ");
let shades = ['░','▒','▓','█'];
for &s in &shades {
let t = match s { '░'=>0.25,'▒'=>0.5,'▓'=>0.75,_=>1.0 };
let (r,g,b) = heat(t);
print!("{}", fg(r,g,b, &format!("{}{}{} ", s, s, s)));
}
println!();
// Show as background fill
print!(" fill: ");
print!("{}",bg(40,40,60," empty "));
print!("{}",bg(60,60,80," ░░░25%░░░ "));
print!("{}",bg(80,80,100," ▒▒50%▒▒ "));
print!("{}",bg(100,100,120," ▓▓75%▓▓ "));
print!("{}",bg(120,120,140," ██100%██ "));
println!();
println!();
// A7: Block sextants (Unicode 13.0)
sub("A7", "Block Sextants (Unicode 13.0+)", "2×3 pixel grid per cell (64 combinations). Newer — check terminal support.");
println!(" chars: 🬀🬁🬂🬃🬄🬅🬆🬇🬈🬉🬊🬋🬌🬍🬎🬏🬐🬑🬒🬓🬔🬕🬖🬗🬘🬙🬚🬛🬜🬝🬞🬟🬠🬡🬢🬣🬤🬥🬦🬧🬨🬩🬪🬫🬬🬭🬮🬯🬰🬱🬲🬳🬴🬵🬶🬷🬸🬹🬺🬻");
print!(" sample: ");
let sextants = ['🬀','🬁','🬃','🬇','🬏','🬟','🬯','🬻'];
for &s in &sextants {
print!("{} ", fg(100,180,255, &s.to_string()));
}
println!(" (empty → full, may not render in all terminals)");
println!();
// A8: Left/Right half blocks
sub("A8", "Left/Right Half Blocks", "2 horizontal pixels per cell");
println!(" chars: ▌ (left half) ▐ (right half)");
print!(" demo: ");
for i in 0..20 {
let t = i as f64 / 19.0;
let left = viridis(t);
let right = viridis((t + 0.025).min(1.0));
print!("{}", fgbg(left.0,left.1,left.2, right.0,right.1,right.2, "▌"));
}
println!(" ← 40 color columns in 20 chars");
println!();
}
// =====================================================================
// B. LINE DRAWING
// =====================================================================
fn section_line_drawing() {
heading("B", "LINE / BOX DRAWING");
sub("B1", "Thin Lines", "Standard box-drawing (current cstat style)");
println!(" ┌───┬───┐");
println!(" │ │ │");
println!(" ├───┼───┤");
println!(" │ │ │");
println!(" └───┴───┘");
println!();
sub("B2", "Rounded Corners", "Softer look, same weight");
println!(" ╭───┬───╮");
println!(" │ │ │");
println!(" ├───┼───┤");
println!(" │ │ │");
println!(" ╰───┴───╯");
println!();
sub("B3", "Heavy/Thick Lines", "For emphasis or outer borders");
println!(" ┏━━━┳━━━┓");
println!(" ┃ ┃ ┃");
println!(" ┣━━━╋━━━┫");
println!(" ┃ ┃ ┃");
println!(" ┗━━━┻━━━┛");
println!();
sub("B4", "Double Lines", "For major section boundaries");
println!(" ╔═══╦═══╗");
println!(" ║ ║ ║");
println!(" ╠═══╬═══╣");
println!(" ║ ║ ║");
println!(" ╚═══╩═══╝");
println!();
sub("B5", "Mixed Weight", "Heavy outer, thin inner — visual hierarchy");
println!(" ┏━━━┯━━━┓");
println!(" ┃ │ ┃");
println!(" ┠───┼───┨");
println!(" ┃ │ ┃");
println!(" ┗━━━┷━━━┛");
println!();
sub("B6", "Dashed/Dotted Lines", "For optional/weak connections");
println!(" ╌╌╌ dashed thin ┄┄┄ dotted thin");
println!(" ╍╍╍ dashed heavy ┅┅┅ dotted heavy");
println!(" ┆ dashed thin vert ┇ dashed heavy vert");
println!(" ┈┈┈ more dotted ┉┉┉ more dashed heavy");
println!();
sub("B7", "Diagonal Lines", "For crossings, X marks, slashes");
println!(" chars: ╱ ╲ ╳");
println!(" ╱╲╱╲╱╲ ╳╳╳╳");
println!(" ╲╱╲╱╲╱ ╳╳╳╳");
println!();
sub("B8", "Arc Corners", "For connecting curved paths");
println!(" ╭─╮ ╭──────╮");
println!(" │ │ │ text │");
println!(" │ ╰────╯ │");
println!(" ╰─────────────╯");
println!();
}
// =====================================================================
// C. COLOR AND STYLE
// =====================================================================
fn section_color_and_style() {
heading("C", "COLOR & STYLE MODES");
sub("C1", "Basic 8-Color", "Maximum compatibility (current cstat approach)");
print!(" ");
for (name, code) in [("black",30),("red",31),("green",32),("yellow",33),("blue",34),("magenta",35),("cyan",36),("white",37)] {
print!("\x1b[{}m{}\x1b[0m ", code, name);
}
println!();
println!();
sub("C2", "Bright/Bold 8-Color", "16 colors total with bright variants");
print!(" ");
for code in 90..=97 {
print!("\x1b[{}m████\x1b[0m", code);
}
println!();
println!();
sub("C3", "256-Color (8-bit)", "Wider palette, good compatibility");
print!(" ");
for i in (16..232).step_by(6) {
print!("\x1b[38;5;{}m█\x1b[0m", i);
}
println!();
print!(" ");
for i in 232..=255 {
print!("\x1b[38;5;{}m█\x1b[0m", i);
}
println!(" ← grayscale ramp");
println!();
sub("C4", "True Color (24-bit)", "16.7 million colors, smooth gradients");
print!(" ");
for i in 0..60 {
let t = i as f64 / 59.0;
let r = (t * 255.0) as u8;
let g = ((1.0 - (t - 0.5).abs() * 2.0).max(0.0) * 255.0) as u8;
let b = ((1.0 - t) * 255.0) as u8;
print!("{}", fg(r, g, b, "█"));
}
println!();
println!();
sub("C5", "Text Styles", "Decorations available via ANSI SGR codes");
println!(" \x1b[1mbold\x1b[0m \x1b[2mdim\x1b[0m \x1b[3mitalic\x1b[0m \x1b[4munderline\x1b[0m \x1b[9mstrikethrough\x1b[0m \x1b[7mreverse\x1b[0m \x1b[53moverline\x1b[0m");
println!();
sub("C6", "Colored Underlines", "Underline with independent color (modern terminals)");
println!(" \x1b[4m\x1b[58;2;255;80;80mred underline\x1b[0m \x1b[4m\x1b[58;2;80;255;80mgreen underline\x1b[0m \x1b[4m\x1b[58;2;80;80;255mblue underline\x1b[0m");
println!(" \x1b[4:3m\x1b[58;2;255;180;0mcurly/wavy underline\x1b[0m \x1b[4:4m\x1b[58;2;100;200;255mdotted underline\x1b[0m \x1b[4:5m\x1b[58;2;200;100;255mdashed underline\x1b[0m");
println!();
sub("C7", "Combined Foreground + Background", "Text on colored backgrounds for cells/badges");
print!(" ");
print!("{} ", fgbg(255,255,255, 220,60,60, " CRITICAL "));
print!("{} ", fgbg(0,0,0, 240,200,60, " WARNING "));
print!("{} ", fgbg(255,255,255, 80,200,120, " OK "));
print!("{} ", fgbg(200,200,200, 60,60,80, " INFO "));
println!();
println!();
}
// =====================================================================
// D. COLOR PALETTES
// =====================================================================
fn section_palettes() {
heading("D", "COLOR PALETTES");
let palettes: Vec<(&str, fn(f64)->(u8,u8,u8), &str)> = vec![
("heat", heat, "red←bad good→green (current intent, but smooth)"),
("viridis", viridis, "perceptually uniform, colorblind-safe"),
("magma", magma, "dark→hot, high contrast on dark backgrounds"),
("inferno", inferno, "similar to magma, more yellow"),
("plasma", plasma, "purple→yellow, vivid"),
("cividis", cividis, "blue→yellow, fully colorblind-safe"),
("coolwarm",coolwarm, "diverging: blue=low, neutral=mid, red=high"),
("turbo", turbo, "rainbow-like, high contrast (not perceptually uniform)"),
];
for (i, (name, pal, desc)) in palettes.iter().enumerate() {
print!(" \x1b[1;33mD{}.\x1b[0m {:<10}", i+1, name);
for j in 0..50 {
let t = j as f64 / 49.0;
let (r,g,b) = pal(t);
print!("{}", fg(r,g,b, "█"));
}
println!();
println!(" \x1b[2m{}\x1b[0m", desc);
}
println!("\n \x1b[1;33mD9.\x1b[0m \x1b[1mCustom semantic\x1b[0m");
println!(" \x1b[2mMap meaning to color, not just position\x1b[0m");
print!(" ");
// Semantic: green=safe, yellow=caution, red=danger, with smooth blending
let semantic = [(0.0,(40,160,80)),(0.3,(40,160,80)),(0.5,(220,200,40)),(0.7,(220,200,40)),(0.85,(200,60,60)),(1.0,(200,60,60))];
for j in 0..50 {
let t = j as f64 / 49.0;
let mut c = semantic[0].1;
for k in 0..semantic.len()-1 {
if t >= semantic[k].0 && t <= semantic[k+1].0 {
let local = (t - semantic[k].0) / (semantic[k+1].0 - semantic[k].0);
c = lerp(semantic[k].1, semantic[k+1].1, local);
break;
}
}
print!("{}", fg(c.0,c.1,c.2, "█"));
}
println!(" safe──caution──danger");
println!();
}
// =====================================================================
// E. CHART PRIMITIVES
// =====================================================================
fn section_chart_primitives() {
heading("E", "CHART / VISUALIZATION PRIMITIVES");
// E1: Horizontal bar variants
sub("E1", "Horizontal Bar Variants", "Different fill styles for bars");
let _w = 30.0_f64;
let fills: [(&str, &str); 6] = [
("solid", "█"),
("shade-grad",""), // special
("dotted", "⣿"),
("hash", "▓"),
("half", "▌"),
("pipe", "┃"),
];
for (name, ch) in &fills {
print!(" {:<12}", name);
if *name == "shade-grad" {
let shades = ['░','▒','▓','█'];
for i in 0..30 {
let t = i as f64 / 29.0;
let idx = (t * 3.0).round() as usize;
let (r,g,b) = heat(t);
print!("{}", fg(r,g,b, &shades[idx.min(3)].to_string()));
}
} else {
for i in 0..30 {
let t = i as f64 / 29.0;
let (r,g,b) = viridis(t);
print!("{}", fg(r,g,b, ch));
}
}
println!();
}
println!();
// E2: Stacked bars
sub("E2", "Stacked Bars", "Multiple values in one bar row");
let stacks = [
("module_a", vec![(12, (80,200,120)), (8, (100,180,255)), (3, (240,200,60))]),
("module_b", vec![(20, (80,200,120)), (5, (100,180,255)), (1, (240,200,60))]),
("module_c", vec![(6, (80,200,120)), (15,(100,180,255)), (10,(240,200,60))]),
];
for (name, segments) in &stacks {
print!(" {:<12}", name);
for (len, (r,g,b)) in segments {
print!("{}", fg(*r,*g,*b, &"█".repeat(*len)));
}
println!();
}
print!(" {:<12}", "");
print!("{} code ", fg(80,200,120, "██"));
print!("{} tests ", fg(100,180,255, "██"));
print!("{} docs", fg(240,200,60, "██"));
println!();
println!();
// E3: Grouped bars
sub("E3", "Grouped Bars", "Side-by-side comparison per category");
let groups = [("v1.0", 15), ("v1.1", 22), ("v2.0", 18)];
let colors = [(220,80,80),(80,200,120),(100,180,255)];
for (i, (label, val)) in groups.iter().enumerate() {
let (r,g,b) = colors[i];
println!(" {:<6} {} {}", label, fg(r,g,b, &"█".repeat(*val)), val);
}
println!();
// E4: Vertical bars (column chart)
sub("E4", "Vertical Column Charts", "Bottom-up using vertical block chars");
let col_vals = [3,7,5,8,4,6,2,7,5,3,6,8,4,5,7,3];
let max_h = 8;
for row in (1..=max_h).rev() {
print!(" ");
for &v in &col_vals {
if v >= row {
let t = v as f64 / max_h as f64;
let (r,g,b) = heat(t);
print!("{}", fg(r,g,b, "██"));
} else if v == row - 1 {
// fractional top
let t = v as f64 / max_h as f64;
let (r,g,b) = heat(t);
print!("{}", fg(r,g,b, "▄ "));
} else {
print!(" ");
}
}
println!();
}
print!(" ");
for _ in &col_vals { print!("──"); }
println!();
println!();
// E5: Gauge/meter
sub("E5", "Gauge / Progress Meter", "Bounded bar with track");
let gauges = [("Health", 0.78), ("Coverage", 0.45), ("Coupling", 0.92)];
for (label, val) in &gauges {
let filled = (*val * 25.0) as usize;
let empty = 25 - filled;
let (r,g,b) = heat(*val);
let bar = format!("{}{}",
fg(r,g,b, &"█".repeat(filled)),
"\x1b[2m░\x1b[0m".repeat(empty));
println!(" {:<12} [{}] {:>5.1}%", label, bar, val * 100.0);
}
println!();
// E6: Waffle/grid chart
sub("E6", "Waffle Chart", "Grid of filled/empty squares showing proportion");
let total = 100;
let filled_count = 73;
print!(" 73/100: ");
for i in 0..total {
if i > 0 && i % 25 == 0 { print!(" "); }
if i < filled_count {
let t = i as f64 / total as f64;
let (r,g,b) = viridis(t);
print!("{}", fg(r,g,b, "■"));
} else {
print!("\x1b[2m□\x1b[0m");
}
}
println!();
println!();
// E7: Dot matrix / LED digits
sub("E7", "Large Numeral Display", "Big digits for hero metrics using braille/blocks");
// Simple 3x5 font
let digits_3x5: [&[&str]; 10] = [
&["▄█▄","█ █","█ █","█ █","▀█▀"], // 0
&[" █ "," █ "," █ "," █ "," █ "], // 1
&["▄█▄"," █","▄█▄","█ ","▀█▀"], // 2
&["▄█▄"," █","▄█▄"," █","▀█▀"], // 3
&["█ █","█ █","▀█▀"," █"," █"], // 4
&["▀█▀","█ ","▀█▀"," █","▄█▄"], // 5
&["▄█▄","█ ","██▄","█ █","▀█▀"], // 6
&["▀█▀"," █"," █"," █"," █"], // 7
&["▄█▄","█ █","▄█▄","█ █","▀█▀"], // 8
&["▄█▄","█ █","▀██"," █","▀█▀"], // 9
];
let number = [7, 8]; // display "78"
for row in 0..5 {
print!(" ");
for &d in &number {
print!("{} ", fg(253,231,37, digits_3x5[d][row]));
}
println!();
}
println!(" \x1b[2m(hero score display)\x1b[0m");
println!();
// E8: Flame chart style
sub("E8", "Flame / Waterfall Bars", "Nested indented colored bars showing hierarchy/depth");
let flames = [
(0, "main()", 40),
(1, "analyze()", 35),
(2, "parse_all()", 20),
(3, "parse_file()", 15),
(2, "compute_metrics()", 12),
(1, "render()", 5),
];
for (depth, name, width) in &flames {
let indent = " ".repeat(*depth);
let t = *depth as f64 / 3.0;
let (r,g,b) = inferno(0.3 + t * 0.5);
print!(" {}", indent);
for _ in 0..*width { print!("{}", fg(r,g,b, "▓")); }
println!(" {}", name);
}
println!();
// E9: Trend arrows / indicators
sub("E9", "Trend Indicators", "Compact directional symbols for changes");
println!(" ↑ ↗ → ↘ ↓ (arrows)");
println!(" ▲ △ ▶ ▽ ▼ (triangles)");
println!(" {} {} {} {} {}",
fg(220,60,60, "▲+15%"),
fg(220,60,60, "↑ 8%"),
fg(150,150,150, "→ 0%"),
fg(80,200,120, "↓ 3%"),
fg(80,200,120, "▼-12%"),
);
println!();
// E10: Area under sparkline
sub("E10", "Filled Sparklines", "Sparkline with area fill underneath");
let spark_vals = [2,4,3,6,8,7,5,8,6,4,3,5,7,8,6,4,2,3,5,7,6,4,3,2,4,6,7,5,3,2];
let max_v = 8;
let blocks = ['▁','▂','▃','▄','▅','▆','▇','█'];
print!(" line: ");
for &v in &spark_vals {
let t = v as f64 / max_v as f64;
let (r,g,b) = viridis(t);
print!("{}", fg(r,g,b, &blocks[((v-1) as usize).min(7)].to_string()));
}
println!();
print!(" filled: ");
for &v in &spark_vals {
let t = v as f64 / max_v as f64;
let top = viridis(t);
let bot = viridis(t * 0.5);
print!("{}", fgbg(top.0,top.1,top.2, bot.0,bot.1,bot.2, &blocks[((v-1) as usize).min(7)].to_string()));
}
println!();
println!();
// E11: Box plot
sub("E11", "Inline Box Plot", "Min, Q1, median, Q3, max in one line");
// ├──────┤ ╞══════╡ │ ┣━━━╋━━━┫
print!(" ");
print!("\x1b[2m├──────\x1b[0m");
print!("{}", fg(100,180,255, "┤█████████"));
print!("{}", fg(253,231,37, "│"));
print!("{}", fg(100,180,255, "██████████┤"));
print!("\x1b[2m──────────┤\x1b[0m");
println!();
println!(" \x1b[2mmin Q1 med Q3 max\x1b[0m");
println!();
// E12: Dot strip / strip plot
sub("E12", "Dot/Strip Plot", "Individual data points on a number line");
print!(" \x1b[2m0\x1b[0m");
let dots = [3,5,5,6,8,8,8,12,14,15,15,16,18,22,25,30];
let max_d = 35;
let mut line = vec![' '; max_d + 1];
for &d in &dots {
line[d] = '●';
}
for (i, &ch) in line.iter().enumerate() {
if ch == '●' {
let t = i as f64 / max_d as f64;
let (r,g,b) = heat(t);
print!("{}", fg(r,g,b, "●"));
} else {
print!("\x1b[2m·\x1b[0m");
}
}
println!(" \x1b[2m{}\x1b[0m", max_d);
println!();
}
// =====================================================================
// F. TEXT & SYMBOL ELEMENTS
// =====================================================================
fn section_text_symbols() {
heading("F", "TEXT & SYMBOL ELEMENTS");
sub("F1", "Status Indicators", "Semantic symbols for pass/fail/warn states");
println!(" {} pass {} fail {} warn {} info {} skip {} pending",
fg(80,200,120, "✓"),
fg(220,60,60, "✗"),
fg(240,200,60, "⚠"),
fg(100,180,255, "ℹ"),
fg(150,150,150, "⊘"),
fg(200,200,200, "◌"),
);
println!(" {} {} {} {} {} {}",
fg(80,200,120, "●"),
fg(220,60,60, "●"),
fg(240,200,60, "●"),
fg(100,180,255, "●"),
fg(150,150,150, "○"),
fg(200,200,200, "◐"),
);
println!();
sub("F2", "Bullets & List Markers", "For ranked lists, trees, enumerations");
println!(" • ◦ ‣ ⁃ ▸ ▹ ▪ ▫ ◆ ◇ ◈ ❖");
println!();
sub("F3", "Arrows & Connectors", "For flow, relationships, direction");
println!(" → ← ↑ ↓ ↔ ↕ ↗ ↘ ↙ ↖");
println!(" ⟶ ⟵ ⟷ ⇒ ⇐ ⇔ ⇨ ⇦");
println!(" ↳ ↱ ↰ ↲ (turns)");
println!(" ➜ ➤ ▶ ◀ (filled)");
println!();
sub("F4", "Superscript & Subscript Numbers", "For footnotes, exponents, indices");
println!(" super: ⁰ ¹ ² ³ ⁴ ⁵ ⁶ ⁷ ⁸ ⁹ ⁺ ⁻ ⁼ ⁽ ⁾ ⁿ");
println!(" sub: ₀ ₁ ₂ ₃ ₄ ₅ ₆ ₇ ₈ ₉ ₊ ₋ ₌ ₍ ₎");
println!(" usage: O(n²) σ₃=1.2 f⁽ⁿ⁾");
println!();
sub("F5", "Mathematical Symbols", "For formulas, stats, annotations");
println!(" μ σ Σ Π ∫ ∂ ∇ √ ∞ ≈ ≠ ≤ ≥ ± ÷ × ∈ ∉ ⊂ ⊃ ∪ ∩ ∅ ∀ ∃");
println!(" usage: μ=12.3 σ=4.1 n=312 Σ=3847");
println!();
sub("F6", "Stars & Ratings", "For scores, quality ratings");
print!(" ");
for i in 0..5 {
if i < 3 { print!("{}", fg(253,231,37, "★")); }
else { print!("{}", fg(80,80,80, "☆")); }
}
println!(" 3/5 stars");
print!(" ");
// Fractional rating with half star
for i in 0..5 {
if i < 3 { print!("{}", fg(253,231,37, "★")); }
else if i == 3 { print!("{}",fg(253,231,37,"⯪")); }
else { print!("{}", fg(80,80,80, "☆")); }
}
println!(" 3.5/5 stars");
println!();
sub("F7", "Enclosed/Circled Characters", "For labels, badges, numbered references");
println!(" numbers: ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩");
println!(" filled: ❶ ❷ ❸ ❹ ❺ ❻ ❼ ❽ ❾ ❿");
println!(" letters: Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ ⓐ ⓑ ⓒ ⓓ ⓔ");
println!();
sub("F8", "Dice & Cards", "Fun alternative for small integer values");
println!(" dice: ⚀ ⚁ ⚂ ⚃ ⚄ ⚅ (1-6)");
println!();
sub("F9", "Separators & Ornaments", "Section dividers beyond plain lines");
println!(" ─ ═ ━ ╌ ╍ ┄ ┅ ┈ ┉");
println!(" ····· ‧‧‧‧‧ ⋯⋯⋯⋯⋯ …………");
print!(" ");
for i in 0..50 {
let t = i as f64 / 49.0;
let (r,g,b) = viridis(t);
print!("{}", fg(r,g,b, "─"));
}
println!();
print!(" ");
for i in 0..50 {
let t = i as f64 / 49.0;
let (r,g,b) = magma(t);
if i % 2 == 0 { print!("{}", fg(r,g,b, "═")); }
else { print!("{}", fg(r,g,b, " ")); }
}
println!();
println!();
}
// =====================================================================
// G. LAYOUT PATTERNS
// =====================================================================
fn section_layout_patterns() {
heading("G", "LAYOUT PATTERNS");
sub("G1", "Side-by-Side Panels", "Two data views sharing one row of terminal lines");
let left = vec![
"╭──── Stats ────╮",
"│ Files: 47 │",
"│ Funcs: 312 │",
"│ LoC: 12,847 │",
"╰────────────────╯",
];
let right = vec![
"╭──── Health ───╮",
"│ Score: 78% │",
"│ Trend: ↗ │",
"│ Grade: B+ │",
"╰────────────────╯",
];
for i in 0..left.len() {
println!(" {} {}", left[i], right.get(i).unwrap_or(&""));
}
println!();
sub("G2", "Tree / Indent View", "Hierarchical data with connecting lines");
let tree = [
("src/", 0, false),
("├── main.rs", 1, false),
("├── render.rs", 1, false),
("├── analysis/", 1, false),
("│ ├── loc.rs", 2, false),
("│ ├── complexity.rs", 2, false),
("│ └── deps/", 2, false),
("│ ├── mod.rs", 3, false),
("│ └── render.rs",3, true),
("└── summary/", 1, false),
(" ├── mod.rs", 2, false),
(" └── sections.rs",2, true),
];
for (line, depth, _is_last) in &tree {
let t = *depth as f64 / 3.0;
let (r,g,b) = viridis(t * 0.8 + 0.2);
println!(" {}", fg(r,g,b, line));
}
println!();
sub("G3", "Tab-Style Headers", "Section navigation indicators");
print!(" ");
print!("{}", fgbg(0,0,0, 100,180,255, " Summary "));
print!("{}", fgbg(200,200,200, 40,40,50, " LoC "));
print!("{}", fgbg(200,200,200, 40,40,50, " Complexity "));
print!("{}", fgbg(200,200,200, 40,40,50, " Deps "));
print!("{}", fgbg(200,200,200, 40,40,50, " Graph "));
println!();
print!(" ");
print!("{}", fg(100,180,255, "━━━━━━━━━"));
print!("{}", fg(60,60,70, "╸────────────╺────────────╸──────╺───────╸"));
println!();
println!();
sub("G4", "Inline Key-Value with Separators", "Compact horizontal metadata");
print!(" ");
print!("{}", fg(100,180,255, "47"));
print!(" files \x1b[2m│\x1b[0m ");
print!("{}", fg(100,180,255, "312"));
print!(" functions \x1b[2m│\x1b[0m ");
print!("{}", fg(100,180,255, "12,847"));
print!(" LoC \x1b[2m│\x1b[0m ");
print!("complexity μ=");
print!("{}", fg(240,200,60, "8.3"));
println!();
println!();
sub("G5", "Badge / Pill Labels", "Highlighted inline labels");
print!(" ");
print!("{}", fgbg(255,255,255, 180,60,60, " critical "));
print!(" ");
print!("{}", fgbg(0,0,0, 240,200,60, " moderate "));
print!(" ");
print!("{}", fgbg(255,255,255, 60,160,80, " healthy "));
print!(" ");
print!("{}", fgbg(200,200,200, 60,60,80, " neutral "));
print!(" ");
print!("{}", fgbg(255,255,255, 100,100,180, " info "));
println!();
println!();
sub("G6", "Nested Boxes", "Boxes within boxes for grouped data");
println!(" ╭─── Module: render ────────────────────╮");
println!(" │ ╭── Functions ──────╮ ╭── Stats ──╮ │");
println!(" │ │ terminal_width() │ │ LoC: 174 │ │");
println!(" │ │ visible_len() │ │ CC: 3.2 │ │");
println!(" │ │ bar_color() │ │ Deps: 4 │ │");
println!(" │ ╰──────────────────╯ ╰──────────╯ │");
println!(" ╰───────────────────────────────────────╯");
println!();
sub("G7", "Responsive Column Width", "Adapt layout to terminal width (already partially done)");
println!(" \x1b[2mNarrow (<60): single column, truncated labels\x1b[0m");
println!(" \x1b[2mMedium (60-100): standard layout\x1b[0m");
println!(" \x1b[2mWide (>100): side-by-side panels, expanded labels\x1b[0m");
println!();
}
// =====================================================================
// H. TERMINAL FEATURES
// =====================================================================
fn section_terminal_features() {
heading("H", "TERMINAL-LEVEL FEATURES");
sub("H1", "Clickable Hyperlinks (OSC 8)", "Terminal links to files/URLs — click to open");
println!(" \x1b]8;;file:///workspace/src/render.rs\x1b\\src/render.rs:42\x1b]8;;\x1b\\ ← try clicking (supported: iTerm2, WezTerm, Windows Terminal, Kitty, etc.)");
println!(" \x1b]8;;https://example.com\x1b\\https://example.com\x1b]8;;\x1b\\");
println!();
sub("H2", "In-Place Updates (Cursor Movement)", "Overwrite previous output for live-feel");
println!(" \\x1b[nA = move up n lines \\x1b[nB = move down");
println!(" \\x1b[nC = move right n cols \\x1b[nD = move left");
println!(" \\x1b[2K = clear current line \\r = carriage return");
println!(" \x1b[2mUseful for: progress bars, status updates, animation\x1b[0m");
println!();
sub("H3", "Terminal Title (OSC 2)", "Set the terminal window/tab title");
println!(" \\x1b]2;cstat — analyzing project\\x07");
println!(" \x1b[2mSets window title to reflect current operation\x1b[0m");
println!();
sub("H4", "Alternate Screen Buffer", "Switch to full-screen mode and back");
println!(" \\x1b[?1049h = enter alternate screen");
println!(" \\x1b[?1049l = leave alternate screen");
println!(" \x1b[2mUseful for: a full-screen dashboard mode without losing scroll history\x1b[0m");
println!();
sub("H5", "Sixel Graphics", "Actual raster images in terminal (limited support)");
println!(" \x1b[2mSupported: xterm, mlterm, WezTerm, foot, some others\x1b[0m");
println!(" \x1b[2mCould render: actual scatter plots, treemaps, architecture diagrams as images\x1b[0m");
println!();
sub("H6", "Kitty Graphics Protocol", "High-quality image display (Kitty terminal)");
println!(" \x1b[2mSupported: Kitty, WezTerm\x1b[0m");
println!(" \x1b[2mCould render: PNG charts inline in output\x1b[0m");
println!();
sub("H7", "Notification (OSC 9/777)", "Send desktop notification when analysis completes");
println!(" \\x1b]9;Analysis complete\\x07 (Windows Terminal)");
println!(" \\x1b]777;notify;cstat;Done\\x07 (rxvt-unicode)");
println!();
println!();
}
// =====================================================================
// I. DISTRIBUTION VISUALIZATIONS
// =====================================================================
fn section_distribution_viz() {
heading("I", "DISTRIBUTION VISUALIZATIONS");
// I1: Violin plot
sub("I1", "Violin Plot", "Mirrored density curve — shows distribution shape, not just quartiles");
// Simulate a density: peaked in the middle, long right tail
let density = [1,2,3,5,8,12,15,18,15,11,8,6,5,4,3,3,2,2,1,1];
let max_d = 18;
let h = density.len();
println!(" \x1b[2m cyclomatic cognitive\x1b[0m");
let density2 = [1,1,2,4,7,10,14,10,7,5,4,3,2,2,1,1,1,0,0,0];
for row in 0..h {
let d1 = density[row];
let d2 = density2[row];
let w1 = (d1 as f64 / max_d as f64 * 15.0).round() as usize;
let w2 = (d2 as f64 / max_d as f64 * 15.0).round() as usize;
let (r1,g1,b1) = viridis(d1 as f64 / max_d as f64);
let (r2,g2,b2) = magma(d2 as f64 / max_d as f64);
let left_pad = 15 - w1;
print!(" {:>3}\x1b[2m│\x1b[0m", if row == 0 || row == h-1 || row == h/2 { format!("{}", row) } else { String::new() });
print!("{}{}", " ".repeat(left_pad), fg(r1,g1,b1, &"█".repeat(w1)));
print!("\x1b[2m│\x1b[0m");
print!("{}", fg(r1,g1,b1, &"█".repeat(w1)));
print!("{} ", " ".repeat(left_pad));
// second violin
let left_pad2 = 15 - w2;
print!("{}{}", " ".repeat(left_pad2), fg(r2,g2,b2, &"█".repeat(w2)));
print!("\x1b[2m│\x1b[0m");
print!("{}", fg(r2,g2,b2, &"█".repeat(w2)));
println!();
}
println!();
// I2: Ridgeline / joy plot
sub("I2", "Ridgeline / Joy Plot", "Overlapping distributions — compare shapes across groups");
let blocks = ['▁','▂','▃','▄','▅','▆','▇','█'];
let ridges: [(&str, [u8; 20]); 4] = [
("render ", [0,1,2,4,6,7,8,7,5,3,2,1,1,0,0,0,0,0,0,0]),
("deps ", [0,0,1,2,3,5,7,8,7,6,5,4,3,2,1,1,0,0,0,0]),
("complex", [0,0,0,1,1,2,3,4,5,7,8,7,6,4,3,2,1,1,0,0]),
("loc ", [0,0,0,0,0,1,1,2,3,4,5,6,7,8,8,7,5,3,1,0]),
];
for (name, vals) in &ridges {
print!(" {}\x1b[2m│\x1b[0m ", name);
for &v in vals {
if v == 0 {
print!(" ");
} else {
let t = v as f64 / 8.0;
let (r,g,b) = viridis(t);
print!("{}", fg(r,g,b, &blocks[(v as usize - 1).min(7)].to_string()));
}
}
println!();
}
println!(" \x1b[2m └──────────────────────\x1b[0m");
println!();
// I3: Beeswarm plot
sub("I3", "Beeswarm / Jitter Plot", "Individual points jittered to avoid overlap — shows density + outliers");
let swarm_data: [(f64, &[i8]); 1] = [(0.0, &[])]; // placeholder, we'll hardcode the visual
let _ = swarm_data;
// Render a beeswarm: each column is a value bucket, dots stack vertically
println!(" \x1b[2m 5 10 15 20 25 30 35\x1b[0m");
// Row by row, dots placed at various x positions with jitter
let rows: [&str; 5] = [
" ● ● ",
" ● ●● ● ● ",
" ● ●● ●●● ●● ● ● ● ",
" ●● ●●● ●●●● ●●● ●● ●● ● ",
" ●●●● ●●●● ●●●● ●●●● ●●● ●●● ●● ",
];
for (i, row) in rows.iter().enumerate() {
let t = 1.0 - i as f64 / 4.0;
print!(" ");
for ch in row.chars() {
if ch == '●' {
let (r,g,b) = viridis(0.3 + t * 0.5);
print!("{}", fg(r,g,b, "●"));
} else {
print!(" ");
}
}
println!();
}
println!(" \x1b[2m └─────────────────────────────────────\x1b[0m");
println!();
// I4: CDF / Cumulative Distribution
sub("I4", "CDF / Cumulative Distribution Curve", "What % of values fall below threshold X — uses braille for smooth curve");
let cdf_vals = [0.0,0.02,0.05,0.10,0.18,0.28,0.40,0.52,0.63,0.73,0.80,0.86,0.90,0.93,0.95,0.97,0.98,0.99,0.99,1.0];
let cdf_h = 8;
let cdf_w = cdf_vals.len();
for row in (0..cdf_h).rev() {
let threshold = row as f64 / (cdf_h - 1) as f64;
print!(" {:>4.0}%\x1b[2m│\x1b[0m", threshold * 100.0);
for (col, &v) in cdf_vals.iter().enumerate() {
if (v - threshold).abs() < 0.08 {
let (r,g,b) = viridis(v);
print!("{}", fg(r,g,b, "●━"));
} else if v > threshold {
print!(" ");
} else {
print!(" ");
}
}
println!();
}
println!(" \x1b[2m └──────────────────────────────────────\x1b[0m");
println!(" \x1b[2m 0 complexity → max\x1b[0m");
println!();
// I5: Rug plot
sub("I5", "Rug Plot", "Tick marks along axis edge — shows each individual observation");
print!(" \x1b[2m│\x1b[0m");
let rug_points = [2,3,5,5,6,7,7,7,8,10,11,11,12,14,15,18,22,25,28,35];
let rug_max = 40;
let mut rug_line = vec![' '; rug_max + 1];
for &p in &rug_points {
if p <= rug_max { rug_line[p] = '│'; }
}
for (i, &ch) in rug_line.iter().enumerate() {
if ch == '│' {
let t = i as f64 / rug_max as f64;
let (r,g,b) = heat(t);
print!("{}", fg(r,g,b, "│"));
} else {
print!("\x1b[2m╌\x1b[0m");
}
}
println!("\x1b[2m│\x1b[0m");
println!(" \x1b[2mEach tick = one observation. Dense ticks = concentration.\x1b[0m");
println!();
// I6: Q-Q Plot
sub("I6", "Q-Q Plot", "Quantile-quantile — compare distribution to normal. Points on diagonal = normal.");
let qq_h = 10;
let qq_w = 30;
// Points roughly along diagonal with some deviation
let qq_points: [(usize,usize);12] = [(1,0),(3,2),(6,4),(9,6),(11,8),(13,10),(15,13),(18,16),(21,19),(23,22),(26,25),(29,28)];
for row in (0..qq_h).rev() {
print!(" \x1b[2m│\x1b[0m");
for col in 0..qq_w {
// diagonal reference line
let on_diag = (col as f64 / qq_w as f64 - row as f64 / qq_h as f64).abs() < 0.06;
let is_point = qq_points.iter().any(|&(px,py)| {
px == col && (py as f64 / (qq_h as f64) * qq_h as f64).round() as usize == row
});
if is_point {
print!("{}", fg(80,200,120, "●"));
} else if on_diag {
print!("\x1b[2m╱\x1b[0m");
} else {
print!(" ");
}
}
println!();
}
println!(" \x1b[2m└──────────────────────────────\x1b[0m");
println!(" \x1b[2mtheoretical quantiles → (deviation from line = non-normality)\x1b[0m");
println!();
}
// =====================================================================
// J. COMPARISON & RANKING VISUALIZATIONS
// =====================================================================
fn section_comparison_viz() {
heading("J", "COMPARISON & RANKING VISUALIZATIONS");
// J1: Lollipop chart
sub("J1", "Lollipop Chart", "Dot on a stick — cleaner than bars for sparse/ranked data");
let items = [
("parse_expr", 42),
("resolve_imports",31),
("build_graph", 24),
("validate_ast", 18),
("emit_warning", 7),
];
let max_v = 42;
for (name, val) in &items {
let w = (*val as f64 / max_v as f64 * 35.0) as usize;
let t = *val as f64 / max_v as f64;
let (r,g,b) = heat(t);
print!(" {:<20}", name);
print!("{}", fg(r,g,b, &"╌".repeat(w)));
print!("{}", fg(r,g,b, "●"));
println!(" {}", val);
}
println!();
// J2: Dumbbell chart
sub("J2", "Dumbbell Chart", "Two dots connected — shows range or before/after delta");
let pairs = [
("render.rs", 8, 14),
("complexity.rs", 22, 18),
("dist.rs", 15, 28),
("loc.rs", 12, 12),
];
let scale = 35;
let max_val = 30;
println!(" {:<18} \x1b[2m{:>15} v1 v2\x1b[0m", "", "");
for (name, v1, v2) in &pairs {
let p1 = (*v1 as f64 / max_val as f64 * scale as f64) as usize;
let p2 = (*v2 as f64 / max_val as f64 * scale as f64) as usize;
let (lo, hi) = if p1 < p2 { (p1, p2) } else { (p2, p1) };
let improved = v2 < v1;
print!(" {:<18}", name);
for i in 0..=scale {
if i == p1 {
print!("{}", fg(150,150,200, "●"));
} else if i == p2 {
if improved { print!("{}", fg(80,200,120, "●")); }
else { print!("{}", fg(220,60,60, "●")); }
} else if i > lo && i < hi {
print!("─");
} else {
print!("\x1b[2m·\x1b[0m");
}
}
println!(" {:>2}→{}", v1, v2);
}
println!();
// J3: Slope chart
sub("J3", "Slope Chart", "Two columns connected by slope lines — shows rank change");
let slopes = [
("parse_expr", 1, 2),
("build_graph", 2, 1),
("resolve", 3, 5),
("validate", 4, 3),
("emit_warn", 5, 4),
];
let col_gap = 25;
println!(" \x1b[2m v1.0 v2.0\x1b[0m");
// Position items at their rank
let h = 5;
for rank in 1..=h {
let left = slopes.iter().find(|s| s.1 == rank);
let right = slopes.iter().find(|s| s.2 == rank);
let left_name = left.map(|s| s.0).unwrap_or("");
let right_name = right.map(|s| s.0).unwrap_or("");
let going_up = left.map(|s| s.2 < s.1).unwrap_or(false);
let going_down = left.map(|s| s.2 > s.1).unwrap_or(false);
let slope_char = if going_up { "╱" } else if going_down { "╲" } else { "─" };
let (r,g,b) = if going_up { (80,200,120) } else if going_down { (220,60,60) } else { (150,150,150) };
print!(" {:<14}", left_name);
print!("{}", fg(r,g,b, "●"));
print!("{}", fg(r,g,b, &format!("─{}─",slope_char).repeat(3)));
print!("{}", if right.is_some() { fg(100,180,255,"●") } else { " ".to_string() });
println!(" {}", right_name);
}
println!();
// J4: Bump chart
sub("J4", "Bump Chart", "Rank trajectories over time — who moved up/down");
let bump_data: [(&str, [usize; 5]); 4] = [
("render", [1,1,2,3,3]),
("deps", [2,3,3,2,1]),
("complex", [3,2,1,1,2]),
("loc", [4,4,4,4,4]),
];
let colors = [(220,80,80),(80,200,120),(100,180,255),(240,200,60)];
println!(" \x1b[2m t1 t2 t3 t4 t5\x1b[0m");
for rank in 1..=4 {
print!(" #{:<2}", rank);
for t in 0..5 {
let who = bump_data.iter().position(|d| d.1[t] == rank);
if let Some(idx) = who {
let (r,g,b) = colors[idx];
print!(" {}", fg(r,g,b, &format!("{:─<4}", bump_data[idx].0)));
} else {
print!(" ");
}
}
println!();
}
println!();
// J5: Cleveland dot plot
sub("J5", "Cleveland Dot Plot", "Aligned dots on a grid — precise comparison without bar clutter");
let dot_items = [
("parse_expr", 42.0),
("resolve_imports", 31.0),
("build_graph", 24.5),
("validate_ast", 18.2),
("emit_warning", 7.0),
];
let max_v = 45.0;
println!(" \x1b[2m{:>20} 0 10 20 30 40\x1b[0m", "");
println!(" \x1b[2m{:>20} ┼─────────┼─────────┼─────────┼─────────┼\x1b[0m", "");
for (name, val) in &dot_items {
let pos = (*val / max_v * 45.0) as usize;
print!(" {:>20} ", name);
for i in 0..=45 {
if i == pos {
let t = *val / max_v;
let (r,g,b) = heat(t);
print!("{}", fg(r,g,b, "◆"));
} else if i % 10 == 0 {
print!("\x1b[2m┊\x1b[0m");
} else {
print!("\x1b[2m·\x1b[0m");
}
}
println!(" {:.1}", val);
}
println!();
// J6: Diverging bar chart
sub("J6", "Diverging Bar Chart", "Bars extend left/right from center — shows positive/negative change");
let changes = [
("render.rs", 6),
("complexity.rs", -4),
("dist.rs", 13),
("loc.rs", 0),
("deps/mod.rs", -8),
];
let max_abs = 15;
let half_w = 15;
for (name, delta) in &changes {
print!(" {:<16}", name);
let abs_d = (*delta as f64).abs();
let bar_w = (abs_d / max_abs as f64 * half_w as f64) as usize;
if *delta < 0 {
let pad = half_w - bar_w;
let (r,g,b) = (100,180,255);
print!("{}{}", " ".repeat(pad), fg(r,g,b, &"◄".repeat(bar_w)));
print!("\x1b[2m│\x1b[0m");
print!("{}", " ".repeat(half_w));
} else if *delta > 0 {
print!("{}", " ".repeat(half_w));
print!("\x1b[2m│\x1b[0m");
let (r,g,b) = (220,120,60);
print!("{}", fg(r,g,b, &"►".repeat(bar_w)));
print!("{}", " ".repeat(half_w - bar_w));
} else {
print!("{}", " ".repeat(half_w));
print!("\x1b[2m│\x1b[0m");
print!("{}", " ".repeat(half_w));
}
println!(" {:>+3}", delta);
}
println!();
// J7: Radar/Spider chart
sub("J7", "Radar / Spider Chart", "Multivariate profile — one polygon per entity, using braille canvas");
// Simplified: show as a small braille rendering
let metrics_labels = ["CC", "LoC", "Nest", "Deps", "Params"];
let profile = [0.8, 0.5, 0.3, 0.7, 0.4]; // normalized 0-1
// Render as a 5-axis star in braille
let cx = 20_f64;
let cy = 16_f64;
let radius = 14.0_f64;
let n_axes = 5;
let mut canvas = vec![vec![0u8; 22]; 9]; // braille cells
let mut density = vec![vec![0u32; 22]; 9];
let pi = std::f64::consts::PI;
// Draw axes and polygon
for i in 0..n_axes {
let angle = pi / 2.0 + i as f64 * 2.0 * pi / n_axes as f64;
// Axis line
for step in 0..30 {
let t = step as f64 / 29.0;
let px = (cx + angle.cos() * radius * t) as usize;
let py = (cy - angle.sin() * radius * t) as usize; // flip Y
set_braille(&mut canvas, &mut density, px, py);
}
// Polygon vertex
let r = profile[i];
let vx = (cx + angle.cos() * radius * r) as usize;
let vy = (cy - angle.sin() * radius * r) as usize;
set_braille(&mut canvas, &mut density, vx, vy);
// Connect to next vertex
let next = (i + 1) % n_axes;
let next_angle = pi / 2.0 + next as f64 * 2.0 * pi / n_axes as f64;
let next_r = profile[next];
let nvx = cx + next_angle.cos() * radius * next_r;
let nvy = cy - next_angle.sin() * radius * next_r;
for step in 0..20 {
let t = step as f64 / 19.0;
let lx = (vx as f64 + (nvx - vx as f64) * t) as usize;
let ly = (vy as f64 + (nvy - vy as f64) * t) as usize;
set_braille(&mut canvas, &mut density, lx, ly);
}
}
for row in 0..9 {
print!(" ");
for col in 0..22 {
let ch = char::from_u32(0x2800 + canvas[row][col] as u32).unwrap();
if canvas[row][col] == 0 {
print!(" ");
} else if density[row][col] > 2 {
print!("{}", fg(253,231,37, &ch.to_string()));
} else {
print!("{}", fg(80,200,120, &ch.to_string()));
}
}
// Labels at approximate positions
match row {
0 => print!(" {}", metrics_labels[0]),
2 => print!(" {}", metrics_labels[1]),
5 => print!(" {}", metrics_labels[4]),
8 => print!(" \x1b[2m(polygon = module profile)\x1b[0m"),
_ => {}
}
println!();
}
println!();
}
fn set_braille(canvas: &mut [Vec<u8>], density: &mut [Vec<u32>], px: usize, py: usize) {
let cx = px / 2;
let cy = py / 4;
if cx >= canvas[0].len() || cy >= canvas.len() { return; }
let lx = px % 2;
let ly = py % 4;
let bit = match (lx, ly) { (0,0)=>0,(0,1)=>1,(0,2)=>2,(0,3)=>6,(1,0)=>3,(1,1)=>4,(1,2)=>5,(1,3)=>7,_=>0 };
canvas[cy][cx] |= 1 << bit;
density[cy][cx] += 1;
}
// =====================================================================
// K. RELATIONAL / FLOW VISUALIZATIONS
// =====================================================================
fn section_relational_viz() {
heading("K", "RELATIONAL & FLOW VISUALIZATIONS");
// K1: Node-edge graph
sub("K1", "Node-Edge Graph Layout", "2D graph with boxes and connecting lines");
println!(" ╭────────╮ ╭──────────╮");
println!(" │ render │─────────→│ summary │");
println!(" ╰────┬───╯ ╰────┬─────╯");
println!(" │ │");
println!(" ↓ ↓");
println!(" ╭─────────╮ ╭──────────╮");
println!(" │ deps │←───────→│ graph │");
println!(" ╰────┬────╯ ╰──────────╯");
println!(" │");
println!(" ↓");
println!(" ╭──────────╮");
println!(" │ analysis │");
println!(" ╰──────────╯");
println!();
// K2: Sankey / flow diagram
sub("K2", "Sankey / Alluvial Flow", "Width-proportional paths between stages — shows flow volume");
let (r1,g1,b1) = (100,180,255);
let (r2,g2,b2) = (80,200,120);
let (r3,g3,b3) = (240,200,60);
let (r4,g4,b4) = (220,100,100);
println!(" \x1b[2mInput Processing Output\x1b[0m");
println!(" {}━━━━━━━━━━━━━━━{}━━━━━━━━━━━{}",
fg(r1,g1,b1,"parse ████"),fg(r1,g1,b1,"████████"),fg(r1,g1,b1,"████ render"));
println!(" {}━━━━━━━━━━{}",
fg(r2,g2,b2," ████"),fg(r2,g2,b2,"━━━━━━━━━━━━━━████ json"));
println!(" {}━━━━━━━━━━━━━━━{}━━━━━━━━━━━{}",
fg(r3,g3,b3,"walk ██"),fg(r3,g3,b3,"██████"),fg(r3,g3,b3,"██ summary"));
println!(" {}━━━━━━━━━━━━━━━{}",
fg(r4,g4,b4," ██"),fg(r4,g4,b4,"━━━━━━━━━━━━━━██ guide"));
println!(" \x1b[2m(bar width ∝ data volume through each path)\x1b[0m");
println!();
// K3: Chord-style connection list
sub("K3", "Chord / Arc Diagram", "Connections between items on a line — uses arcs above/below");
println!(" \x1b[2m(flat layout, arcs show connections; height ∝ strength)\x1b[0m");
// Top arcs
println!(" {} {}",
fg(100,180,255, " ╭───────────────╮"),
"");
println!(" {} {}",
fg(80,200,120, " ╭────╮"),
fg(220,100,100, " ╭────────╮"));
println!(" {} {}",
fg(240,200,60, "╭─╮"),
"");
print!(" ");
let nodes = ["render","deps","graph","loc","summary","complex"];
for n in &nodes {
print!("{} ", fg(253,231,37, &format!("[{}]", &n[..3])));
}
println!();
// Bottom arcs
println!(" {}",
fg(200,100,200, " ╰──────────────────────╯"));
println!();
// K4: Dependency arrows with indentation
sub("K4", "Layered Dependency View", "Modules in tiers with directional arrows between layers");
println!(" \x1b[2m── Tier 0 (entry) ──────────────────────────\x1b[0m");
print!(" ");
print!("{}", fgbg(200,200,200, 40,60,80, " main "));
println!();
println!(" │ │");
println!(" ↓ ↓");
println!(" \x1b[2m── Tier 1 (orchestration) ──────────────────\x1b[0m");
print!(" ");
print!("{} ", fgbg(200,200,200, 40,80,60, " summary "));
print!("{}", fgbg(200,200,200, 40,80,60, " flow "));
println!();
println!(" │ ╲ │");
println!(" ↓ ╲ ↓");
println!(" \x1b[2m── Tier 2 (analysis) ───────────────────────\x1b[0m");
print!(" ");
print!("{} ", fgbg(200,200,200, 60,40,80, " deps "));
print!("{} ", fgbg(200,200,200, 60,40,80, " complexity "));
print!("{}", fgbg(200,200,200, 60,40,80, " loc "));
println!();
println!();
// K5: Dendrogram
sub("K5", "Dendrogram / Cluster Tree", "Hierarchical clustering — which modules are most similar");
println!(" \x1b[2mdistance 0.0 0.5 1.0\x1b[0m");
println!(" {}", fg(100,180,255, "render ─────────────┐"));
println!(" {} {}", fg(100,180,255, "summary ────────────┤"), fg(80,200,120, ""));
println!(" {} {}",
fg(100,180,255, " ├──────────┐"),
"");
println!(" {}", fg(240,200,60, "deps ──────┐ │ │"));
println!(" {}", fg(240,200,60, "graph ─────┤────────┘ │"));
println!(" {}", fg(240,200,60, " │ │"));
println!(" {}", fg(220,100,100, "complexity ────────────────────┘"));
println!();
// K6: Adjacency list view
sub("K6", "Adjacency List (Compact)", "Text-based graph: each node lists its connections");
let adj = [
("render", vec!["deps","summary","loc"]),
("deps", vec!["graph","render"]),
("summary", vec!["complexity","deps","loc","graph"]),
("complexity", vec![]),
("loc", vec![]),
];
for (node, edges) in &adj {
let edge_str: Vec<String> = edges.iter().map(|e| fg(100,180,255, e)).collect();
if edges.is_empty() {
println!(" {} → \x1b[2m(leaf)\x1b[0m", fg(253,231,37, node));
} else {
println!(" {} → {}", fg(253,231,37, node), edge_str.join(", "));
}
}
println!();
}
// =====================================================================
// L. MATRIX & GRID VISUALIZATIONS
// =====================================================================
fn section_matrix_grid_viz() {
heading("L", "MATRIX & GRID VISUALIZATIONS");
// L1: Calendar heatmap
sub("L1", "Calendar Heatmap", "Grid of days colored by value — weeks as columns, days as rows");
let days = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"];
let mut seed: u64 = 99;
println!(" \x1b[2m W1 W2 W3 W4 W5 W6 W7 W8\x1b[0m");
for d in 0..7 {
print!(" \x1b[2m{}\x1b[0m ", days[d]);
for _w in 0..8 {
seed = seed.wrapping_mul(6364136223846793005).wrapping_add(1);
let v = (seed >> 33) as f64 / u32::MAX as f64;
let (r,g,b) = viridis(v);
print!("{}", bg(r,g,b, " "));
print!(" ");
}
println!();
}
println!(" \x1b[2m(commit activity, complexity changes, etc.)\x1b[0m");
println!();
// L2: Weighted adjacency matrix with blocks
sub("L2", "Weighted Adjacency Matrix", "Color intensity shows connection strength, not just 0/1/2");
let mods = ["rend","deps","summ","comp","loc ","grph"];
let n = mods.len();
print!(" {:>6}", "");
for m in &mods { print!(" {}", m); }
println!();
let mut seed2: u64 = 77;
for i in 0..n {
print!(" {:>5} ", mods[i]);
for j in 0..n {
if i == j {
print!("{}", bg(40,40,40, " ·· "));
print!(" ");
} else {
seed2 = seed2.wrapping_mul(6364136223846793005).wrapping_add(1);
let v = (seed2 >> 33) as f64 / u32::MAX as f64;
let (r,g,b) = magma(v);
let label = format!("{:.1}", v * 10.0);
print!("{}", fgbg(if v > 0.5 {0} else {200}, if v > 0.5 {0} else {200}, if v > 0.5 {0} else {200}, r,g,b, &format!("{:>4}", label)));
print!(" ");
}
}
println!();
}
println!();
// L3: Mosaic / Marimekko chart
sub("L3", "Mosaic / Marimekko Chart", "Variable-width columns — both width and height encode data");
let categories = [("src",50),("tests",25),("bench",15),("docs",10)];
let sub_cats = [(0.6,(80,200,120)),(0.25,(100,180,255)),(0.15,(240,200,60))]; // code/test/doc proportions
let total_w: usize = 60;
println!(" \x1b[2mcolumn width ∝ total LoC, row height ∝ composition\x1b[0m");
for (frac, (r,g,b)) in &sub_cats {
print!(" ");
for (name, pct) in &categories {
let col_w = (*pct as f64 / 100.0 * total_w as f64) as usize;
let fill_h = (*frac * 3.0_f64).round() as usize;
let _ = fill_h;
print!("{}", bg(*r,*g,*b, &" ".repeat(col_w)));
}
println!();
}
print!(" ");
for (name, pct) in &categories {
let col_w = (*pct as f64 / 100.0 * total_w as f64) as usize;
let centered = format!("{:^w$}", name, w=col_w);
print!("\x1b[2m{}\x1b[0m", centered);
}
println!();
println!();
// L4: Heatmap with annotations
sub("L4", "Annotated Heatmap", "Color + text in each cell — value visible on colored background");
let ann_labels = ["CC","Nest","Deps"];
let ann_data = [[8.2,3.1,5.0],[2.4,7.8,1.2],[4.5,2.0,9.1]];
print!(" {:>8}", "");
for l in &ann_labels { print!(" {:>8}", l); }
println!();
for i in 0..3 {
print!(" {:>8}", ann_labels[i]);
for j in 0..3 {
let v = ann_data[i][j];
let t = v / 10.0;
let (r,g,b) = magma(t);
let txt_color = if t > 0.5 { (0,0,0) } else { (220,220,220) };
print!(" {}", fgbg(txt_color.0,txt_color.1,txt_color.2, r,g,b, &format!(" {:>4.1} ", v)));
}
println!();
}
println!();
}
// =====================================================================
// M. PART-TO-WHOLE VISUALIZATIONS
// =====================================================================
fn section_part_to_whole_viz() {
heading("M", "PART-TO-WHOLE VISUALIZATIONS");
// M1: Icicle chart
sub("M1", "Icicle Chart", "Top-down nested rectangles — like a rectangular sunburst");
let (r1,g1,b1) = (80,100,180);
let (r2,g2,b2) = (80,160,120);
let (r3,g3,b3) = (180,160,80);
let (r4,g4,b4) = (180,80,80);
// Level 0: full width
println!(" {}", bg(60,60,80, &format!("{:^60}", "project (12,847 LoC)")));
// Level 1: split
println!(" {}{}{}{}",
bg(r1,g1,b1, &format!("{:^30}", "src/ (8420)")),
bg(r2,g2,b2, &format!("{:^15}", "tests/ (3200)")),
bg(r3,g3,b3, &format!("{:^10}", "bench/")),
bg(r4,g4,b4, &format!("{:^5}", "doc")),
);
// Level 2: src/ split further
let s = lerp((80,100,180),(120,140,220),0.3);
let s2 = lerp((80,100,180),(120,140,220),0.6);
let s3 = lerp((80,100,180),(120,140,220),0.9);
println!(" {}{}{}{}",
bg(s.0,s.1,s.2, &format!("{:^14}", "analysis/")),
bg(s2.0,s2.1,s2.2, &format!("{:^10}", "render/")),
bg(s3.0,s3.1,s3.2, &format!("{:^6}", "cli")),
" ".repeat(30),
);
println!();
// M2: Proportional area (squares)
sub("M2", "Proportional Area Squares", "Square size encodes magnitude — better area perception than bars");
let items = [("parse",42),("resolve",31),("build",24),("validate",18),("emit",7)];
for (name, val) in &items {
let side = ((*val as f64).sqrt() * 1.5) as usize;
let t = *val as f64 / 42.0;
let (r,g,b) = heat(t);
print!(" {:<10}", name);
for _row in 0..1 {
for _ in 0..side { print!("{}", fg(r,g,b, "██")); }
}
println!(" ({})", val);
}
println!(" \x1b[2m(area ∝ value, not just width)\x1b[0m");
println!();
// M3: Nested treemap
sub("M3", "Treemap (Nested)", "Proportional nested rectangles — area ∝ value");
println!(" ┌──────────────────────┬─────────────────┐");
println!(" │ │ │");
println!(" │ {} │ {} │",
fg(100,180,255, "src/analysis"),
fg(80,200,120, "src/render"));
println!(" │ {} │ {} │",
fg(100,180,255, "(4200 LoC)"),
fg(80,200,120, "(2100)"));
println!(" │ │ │");
println!(" ├───────────┬──────────┼────────┬────────┤");
println!(" │ │ │ │ │");
println!(" │ {} │ {} │ {} │ {} │",
fg(240,200,60, "tests"),
fg(220,100,100, "bench"),
fg(200,100,200, "cli"),
fg(150,150,150, "doc"));
println!(" │ {} │ {} │ {} │ {} │",
fg(240,200,60, "(3200)"),
fg(220,100,100, "(890)"),
fg(200,100,200, "(400)"),
fg(150,150,150, "(57)"));
println!(" └───────────┴──────────┴────────┴────────┘");
println!();
// M4: Donut / ring chart (braille)
sub("M4", "Donut / Ring Chart", "Circular proportion display using braille — for 2-4 segments");
let segments: [(f64, (u8,u8,u8)); 3] = [
(0.55, (100,180,255)), // code
(0.30, (80,200,120)), // tests
(0.15, (240,200,60)), // docs
];
let cx = 16.0_f64;
let cy = 16.0_f64;
let outer = 14.0_f64;
let inner = 8.0_f64;
let pi = std::f64::consts::PI;
let mut canvas = vec![vec![0u8; 18]; 9];
let mut colors = vec![vec![(0u8,0u8,0u8); 18]; 9];
let mut angle_start = 0.0_f64;
for (frac, color) in &segments {
let angle_end = angle_start + frac * 2.0 * pi;
// Fill arc
let steps = 100;
for s in 0..steps {
let a = angle_start + (angle_end - angle_start) * s as f64 / steps as f64;
for rd in 0..10 {
let r = inner + (outer - inner) * rd as f64 / 9.0;
let px = (cx + a.cos() * r) as usize;
let py = (cy - a.sin() * r) as usize;
let bcx = px / 2;
let bcy = py / 4;
if bcx < 18 && bcy < 9 {
let lx = px % 2;
let ly = py % 4;
let bit = match (lx, ly) { (0,0)=>0,(0,1)=>1,(0,2)=>2,(0,3)=>6,(1,0)=>3,(1,1)=>4,(1,2)=>5,(1,3)=>7,_=>0 };
canvas[bcy][bcx] |= 1 << bit;
colors[bcy][bcx] = *color;
}
}
}
angle_start = angle_end;
}
for row in 0..9 {
print!(" ");
for col in 0..18 {
let ch = char::from_u32(0x2800 + canvas[row][col] as u32).unwrap();
if canvas[row][col] == 0 {
print!(" ");
} else {
let (r,g,b) = colors[row][col];
print!("{}", fg(r,g,b, &ch.to_string()));
}
}
match row {
2 => print!(" {} 55% code", fg(100,180,255, "██")),
4 => print!(" {} 30% tests", fg(80,200,120, "██")),
6 => print!(" {} 15% docs", fg(240,200,60, "██")),
_ => {}
}
println!();
}
println!();
// M5: Stacked percentage bar
sub("M5", "Stacked 100% Bar", "Horizontal bar always fills to 100% — shows proportions");
let total_w = 50;
let segments_pct = [("code",55,(80,200,120)),("test",30,(100,180,255)),("docs",10,(240,200,60)),("cfg",5,(180,100,200))];
print!(" ");
for (name, pct, (r,g,b)) in &segments_pct {
let w = (*pct as f64 / 100.0 * total_w as f64).round() as usize;
let label = if w > name.len() + 2 { format!("{:^w$}", format!("{} {}%", name, pct), w=w) } else { format!("{:^w$}", "", w=w) };
print!("{}", fgbg(if *pct > 20 {255} else {200},if *pct > 20 {255} else {200},if *pct > 20 {255} else {200}, *r,*g,*b, &label));
}
println!();
println!();
// M6: Parliament / hemicycle (just described, complex to render)
sub("M6", "Waffle Grid (Categorized)", "Grid squares colored by category — each square = 1%");
let grid_cats = [('■',(80,200,120),55),('■',(100,180,255),30),('■',(240,200,60),10),('■',(180,100,200),5)];
print!(" ");
let mut count = 0;
for (ch, (r,g,b), n) in &grid_cats {
for _ in 0..*n {
if count > 0 && count % 25 == 0 { print!("\n "); }
print!("{}", fg(*r,*g,*b, &ch.to_string()));
count += 1;
}
}
println!();
print!(" ");
for (_, (r,g,b), _) in &grid_cats {
print!("{} ", fg(*r,*g,*b, "■■"));
}
println!();
println!(" \x1b[2mcode tests docs cfg\x1b[0m");
println!();
}
// =====================================================================
// N. TEMPORAL & SEQUENTIAL VISUALIZATIONS
// =====================================================================
fn section_temporal_viz() {
heading("N", "TEMPORAL & SEQUENTIAL VISUALIZATIONS");
// N1: Sparkline band (multiple aligned)
sub("N1", "Sparkline Band", "Multiple aligned sparklines for cross-metric comparison");
let blocks = ['▁','▂','▃','▄','▅','▆','▇','█'];
let bands: [(&str, [u8;20], fn(f64)->(u8,u8,u8)); 4] = [
("CC ", [2,3,4,3,5,6,5,4,6,7,8,7,6,5,6,7,6,5,4,3], viridis),
("LoC ", [3,3,4,4,5,5,6,6,7,7,7,7,8,8,8,7,7,6,6,5], magma),
("Deps ", [1,2,2,3,3,4,4,5,5,5,6,6,6,7,7,7,7,8,8,8], inferno),
("Nest ", [5,5,4,4,3,3,3,2,2,2,3,3,4,4,3,3,2,2,1,1], plasma),
];
for (name, vals, pal) in &bands {
print!(" {}", name);
for &v in vals {
let t = v as f64 / 8.0;
let (r,g,b) = pal(t);
print!("{}", fg(r,g,b, &blocks[(v as usize - 1).min(7)].to_string()));
}
println!();
}
println!(" \x1b[2m ← older newer →\x1b[0m");
println!();
// N2: Horizon chart
sub("N2", "Horizon Chart", "Folded bands — encodes magnitude via color layers, saves vertical space");
// Values 0-8, but we fold at 4: values 0-4 use light shade, 4-8 overlay dark
let hz_vals = [1,2,3,4,5,6,7,8,7,6,5,4,3,2,1,0,1,2,4,6,8,6,4,2,0,1,3,5,7,5];
let fold_at = 4;
print!(" layer1: ");
for &v in &hz_vals {
let base = v.min(fold_at);
let t = base as f64 / fold_at as f64;
let (r,g,b) = lerp((30,30,50),(80,140,200), t);
print!("{}", bg(r,g,b, &blocks[(base as usize).min(7).max(1) - 1].to_string()));
}
println!();
print!(" layer2: ");
for &v in &hz_vals {
let over = if v > fold_at { v - fold_at } else { 0 };
let base = v.min(fold_at);
let base_t = base as f64 / fold_at as f64;
let (br,bg_c,bb) = lerp((30,30,50),(80,140,200), base_t);
if over > 0 {
let over_t = over as f64 / fold_at as f64;
let (fr,fgc,fb) = lerp((100,160,220),(220,240,255), over_t);
print!("{}", fgbg(fr,fgc,fb, br,bg_c,bb, &blocks[(over as usize).min(7).max(1) - 1].to_string()));
} else {
print!("{}", bg(br,bg_c,bb, " "));
}
}
println!();
println!(" \x1b[2m(same data: layer1 = base, layer2 = base + overflow folded on top)\x1b[0m");
println!();
// N3: Gantt / timeline chart
sub("N3", "Gantt / Timeline Chart", "Horizontal bars on a time axis — phases, durations, overlaps");
let gantt = [
("parse", 0, 8, (100,180,255)),
("analyze", 5, 15, (80,200,120)),
("deps", 8, 12, (240,200,60)),
("complexity",10, 18, (220,100,100)),
("render", 16, 22, (200,100,200)),
];
let max_t = 24;
let scale = 48;
println!(" \x1b[2m{:>14} 0 5 10 15 20\x1b[0m", "");
println!(" \x1b[2m{:>14} ┼────────┼────────┼────────┼────────┼\x1b[0m", "");
for (name, start, end, (r,g,b)) in &gantt {
print!(" {:>14} ", name);
let s = (*start as f64 / max_t as f64 * scale as f64) as usize;
let e = (*end as f64 / max_t as f64 * scale as f64) as usize;
for i in 0..scale {
if i >= s && i < e {
print!("{}", fg(*r,*g,*b, "█"));
} else {
print!("\x1b[2m·\x1b[0m");
}
}
println!();
}
println!();
// N4: Step chart
sub("N4", "Step Chart", "Discrete level changes — like sparkline but shows exact transitions");
let step_vals: [usize; 15] = [2,2,4,4,4,7,7,3,3,5,5,5,8,8,6];
let max_s = 8;
for row in (1..=max_s).rev() {
print!(" {:>2}\x1b[2m│\x1b[0m", row);
for (i, &v) in step_vals.iter().enumerate() {
if v == row {
let t = v as f64 / max_s as f64;
let (r,g,b) = viridis(t);
// horizontal segment
print!("{}", fg(r,g,b, "──"));
// vertical connector to next if different
} else if i > 0 && step_vals[i-1] == row && v != row {
// vertical going down or up
let going = if v > row { "│ " } else { "│ " };
let t = row as f64 / max_s as f64;
let (r,g,b) = viridis(t);
print!("{}", fg(r,g,b, going));
} else if i > 0 && step_vals[i] != row && step_vals[i-1] != row {
// Check if vertical line passes through this row
let prev = step_vals[i-1];
let cur = step_vals[i];
let (lo, hi) = if prev < cur { (prev, cur) } else { (cur, prev) };
if row > lo && row < hi && i > 0 {
let t = row as f64 / max_s as f64;
let (r,g,b) = viridis(t);
print!("{}", fg(r,g,b, "│ "));
} else {
print!(" ");
}
} else {
print!(" ");
}
}
println!();
}
println!(" \x1b[2m └──────────────────────────────\x1b[0m");
println!();
// N5: Event timeline / marker chart
sub("N5", "Event Timeline / Markers", "Discrete events on a continuous axis");
print!(" \x1b[2m│\x1b[0m");
let events: [(usize, &str, (u8,u8,u8)); 6] = [
(3, "▼", (220,60,60)),
(8, "▼", (240,200,60)),
(12,"▼", (80,200,120)),
(18,"▼", (100,180,255)),
(25,"▼", (220,60,60)),
(33,"▼", (200,100,200)),
];
let tl_w = 40;
let mut tl_line = vec![("─", (80,80,80)); tl_w];
for (pos, marker, color) in &events {
if *pos < tl_w { tl_line[*pos] = (*marker, *color); }
}
for (ch, (r,g,b)) in &tl_line {
print!("{}", fg(*r,*g,*b, ch));
}
println!("\x1b[2m│\x1b[0m");
print!(" ");
for (pos, _, _) in &events {
let label_pos = if *pos > 1 { *pos } else { 1 };
print!("{:>w$}", "│", w=if label_pos > 0 {3} else {1});
}
println!();
println!(" \x1b[2m release bug feature refactor bug deploy\x1b[0m");
println!();
}
// =====================================================================
// O. TEXT-INTEGRATED VISUALIZATIONS
// =====================================================================
fn section_text_integrated_viz() {
heading("O", "TEXT-INTEGRATED VISUALIZATIONS");
// O1: Data bars in table cells
sub("O1", "In-Cell Data Bars", "Bars embedded within table cells — like Excel conditional formatting");
println!(" ╭──────────────────┬────────┬──────────────────────╮");
println!(" │ Function │ Score │ Distribution │");
println!(" ├──────────────────┼────────┼──────────────────────┤");
let table_data = [
("parse_expr", 42, 42),
("resolve_imports", 31, 42),
("build_graph", 24, 42),
("validate_ast", 18, 42),
];
for (name, val, max_v) in &table_data {
let t = *val as f64 / *max_v as f64;
let (r,g,b) = heat(t);
let bar_w = (t * 20.0) as usize;
let bar = fg(r,g,b, &"█".repeat(bar_w));
let pad = " ".repeat(20 - bar_w);
println!(" │ {:<16} │ {:>6} │ {}{} │",
name, fg(r,g,b,&val.to_string()), bar, pad);
}
println!(" ╰──────────────────┴────────┴──────────────────────╯");
println!();
// O2: Heatmap-colored text
sub("O2", "Heatmap-Colored Text", "The text IS the visualization — value encoded in text color");
let funcs = [
("parse_expr", 42), ("resolve_imports",31), ("build_graph",24),
("validate_ast", 18), ("emit_warning", 7), ("new_scope", 12),
("check_types", 28), ("fold_const", 15), ("inline_fn", 9),
];
println!(" \x1b[2mFunction names colored by complexity score:\x1b[0m");
print!(" ");
for (i, (name, val)) in funcs.iter().enumerate() {
let t = *val as f64 / 42.0;
let (r,g,b) = heat(t);
print!("{}", fg(r,g,b, name));
if i < funcs.len() - 1 { print!(" "); }
if (i + 1) % 3 == 0 { print!("\n "); }
}
println!();
println!();
// O3: Inline sparklines in table
sub("O3", "Inline Sparklines in Table Cells", "Trend mini-charts within each row");
let blocks = ['▁','▂','▃','▄','▅','▆','▇','█'];
println!(" ╭──────────────┬───────┬────────────────────┬───────╮");
println!(" │ Module │ CC │ Trend (10 commits) │ Δ │");
println!(" ├──────────────┼───────┼────────────────────┼───────┤");
let sparkdata: [(&str, f64, [u8;10], &str); 4] = [
("render", 8.3, [3,4,4,5,5,6,6,7,7,8], "+2.1↑"),
("deps", 12.1, [8,7,7,6,6,5,5,4,4,3], "-3.2↓"),
("complexity", 6.7, [5,5,5,6,5,5,6,5,5,5], " 0.0→"),
("loc", 4.2, [2,3,4,3,4,5,4,3,4,4], "+0.3↑"),
];
for (name, cc, trend, delta) in &sparkdata {
let cc_t = *cc / 15.0;
let (cr,cg,cb) = heat(cc_t);
print!(" │ {:<12} │ {} │ ", name, fg(cr,cg,cb, &format!("{:>5.1}", cc)));
for &v in trend {
let t = v as f64 / 8.0;
let (r,g,b) = viridis(t);
print!("{}", fg(r,g,b, &blocks[(v as usize - 1).min(7)].to_string()));
}
let delta_color = if delta.contains('↑') { fg(220,60,60,delta) }
else if delta.contains('↓') { fg(80,200,120,delta) }
else { fg(150,150,150,delta) };
println!(" │ {} │", delta_color);
}
println!(" ╰──────────────┴───────┴────────────────────┴───────╯");
println!();
// O4: Conditional row highlighting
sub("O4", "Conditional Row Highlighting", "Entire row background changes based on value/status");
println!(" \x1b[2m Function CC Status\x1b[0m");
let rows = [
("parse_expr", 42, "critical"),
("resolve_imports",31, "warning"),
("build_graph", 24, "warning"),
("validate_ast", 18, "ok"),
("emit_warning", 7, "ok"),
];
for (name, cc, status) in &rows {
let (br,bgg,bb) = match *status {
"critical" => (60,20,20),
"warning" => (50,40,15),
_ => (20,20,20),
};
let (fr,fgg,fb) = match *status {
"critical" => (255,100,100),
"warning" => (240,200,80),
_ => (180,220,180),
};
let line = format!(" {:<22} {:>3} {:<10}", name, cc, status);
println!(" {}", fgbg(fr,fgg,fb, br,bgg,bb, &line));
}
println!();
// O5: Annotation callouts
sub("O5", "Annotation / Callout Lines", "Point at specific data with explanatory text");
let bar_vals = [3,7,5,12,4,6,2,9];
let max_b = 12;
print!(" ");
for &v in &bar_vals {
let t = v as f64 / max_b as f64;
let (r,g,b) = viridis(t);
print!("{}", fg(r,g,b, &format!("{:>3} ", v)));
}
println!();
print!(" ");
for &v in &bar_vals {
let t = v as f64 / max_b as f64;
let h = (t * 6.0) as usize;
let (r,g,b) = viridis(t);
let bks = ['▁','▂','▃','▄','▅','▆','▇','█'];
print!("{}", fg(r,g,b, &format!(" {} ", bks[h.min(7)])));
print!(" ");
}
println!();
// Callout arrow pointing to the outlier (12)
println!(" \x1b[2m ↑\x1b[0m");
println!(" \x1b[2m ╰── {} (z=2.4, outlier)\x1b[0m", fg(253,231,37, "12"));
println!();
// O6: Multi-metric compact row
sub("O6", "Multi-Metric Compact Row", "All metrics for one item in a single dense line");
println!(" \x1b[2mformat: name CC▕gauge▏ nest▕gauge▏ deps▕gauge▏ trend grade\x1b[0m");
let compact = [
("parse_expr", 8.5, 4, 6, [3,4,5,6,7,8], "C"),
("resolve_imports",3.2, 2, 3, [3,3,3,3,3,3], "A"),
("build_graph", 5.1, 3, 8, [2,3,4,5,6,5], "B"),
];
let blocks = ['▁','▂','▃','▄','▅','▆','▇','█'];
for (name, cc, nest, deps, trend, grade) in &compact {
let cc_t = *cc / 10.0;
let nest_t = *nest as f64 / 6.0;
let deps_t = *deps as f64 / 10.0;
let (cr,cg,cb) = heat(cc_t);
let (nr,ng,nb) = heat(nest_t);
let (dr,dg,db) = heat(deps_t);
print!(" {:<16}", name);
// CC gauge
let cc_bar = (cc_t * 5.0) as usize;
print!(" {} {}{}\x1b[2m{}\x1b[0m",
fg(cr,cg,cb, &format!("{:.1}", cc)),
fg(cr,cg,cb, &"█".repeat(cc_bar)),
"\x1b[2m░\x1b[0m".repeat(5-cc_bar),
""
);
// Nest gauge
let n_bar = (nest_t * 4.0) as usize;
print!(" {} {}{}",
fg(nr,ng,nb, &format!("n{}", nest)),
fg(nr,ng,nb, &"█".repeat(n_bar)),
"\x1b[2m░\x1b[0m".repeat(4-n_bar),
);
// Deps
print!(" {} ", fg(dr,dg,db, &format!("d{}", deps)));
// Trend sparkline
for &v in trend {
let t = v as f64 / 8.0;
let (r,g,b) = viridis(t);
print!("{}", fg(r,g,b, &blocks[(v as usize -1).min(7)].to_string()));
}
// Grade badge
let grade_color = match *grade {
"A" => (80,200,120),
"B" => (240,200,60),
_ => (220,60,60),
};
print!(" {}", fgbg(0,0,0, grade_color.0,grade_color.1,grade_color.2, &format!(" {} ", grade)));
println!();
}
println!();
println!("\n{}", "═".repeat(70));
println!(" END OF GLOSSARY");
println!(" A: 8 pixel primitives B: 8 line styles C: 7 color modes");
println!(" D: 9 palettes E: 12 chart elements F: 9 symbol sets");
println!(" G: 7 layout patterns H: 7 terminal features");
println!(" I: 6 distribution viz J: 7 comparison viz K: 6 relational viz");
println!(" L: 4 matrix/grid viz M: 6 part-to-whole N: 5 temporal viz");
println!(" O: 6 text-integrated = {} total entries", 8+8+7+9+12+9+7+7+6+7+6+4+6+5+6);
println!(" Run: rustc demo_glossary.rs -o demo_glossary && ./demo_glossary");
println!("{}\n", "═".repeat(70));
}