josie / alder-tools

Graphs: revert renderer-side trace padding (doubled with ui.rs pad())

- The 1-sub-row renderer padding (commit 0eaf5124) stacked with ui.rs
  pad() scale headroom (~1 cell-row) in auto mode -> doubled gap. Reverted
  plot.rs to the full [0, sub_h-1] band
- ui.rs pad() alone keeps the trace clear of the borders in auto mode;
  in fixed mode values at the bounds correctly sit at the box edge
- marker_row back to the caller's [0, rows-1] cell-row (no padding)
- 15 tests, clippy clean; pty-verified 50x100

6ce4ffc7d99cf5b367d001007eb11a911623a900
josie <administrator@josie-c.com> · 2026-09-01T23:14 · browse files at this commit

parents: 52f00c5

diff --git a/src/plot.rs b/src/plot.rs
index 314c81c..8933266 100644
--- a/src/plot.rs
+++ b/src/plot.rs
@@ -158,12 +158,7 @@ pub fn render(
     }
     let rows = area.height as usize;
     let cols = area.width as usize;
-    // Reserve 1 sub-row at the top and bottom so the trace stays visually
-    // clear of the box borders (a dot at sub-row 0 or sub_h-1 would sit
-    // flush against the border and read as touching/overlapping it).
-    // Usable sub-rows: 1..(sub_h-1), mapped over [min,max].
     let sub_h = rows * 4;
-    let usable_h = sub_h.saturating_sub(2).max(1);
     let sub_w = cols * 2;
     let span = max - min;
 
@@ -174,15 +169,15 @@ pub fn render(
     }
     let col_vals = map_to_subcols(&samples, sub_w);
 
-    // Sub-row (0=top=max) for a value, mapped into the usable band
-    // [1, sub_h-1) so the trace stays 1 sub-row clear of both borders.
-    // No hysteresis — the 4-level sub-row quantization is the noise floor
-    // (sub-row jitter maps to the same sub-row and doesn't move the dot).
+    // Sub-row (0=top=max) for a value, mapped over the full [0, sub_h-1]
+    // band. The caller (ui.rs pad()) adds scale headroom in auto mode so
+    // the trace stays clear of the borders; in fixed mode values at the
+    // bounds correctly sit at the box edge. No hysteresis — the 4-level
+    // sub-row quantization is the noise floor (sub-row jitter maps to the
+    // same sub-row and doesn't move the dot).
     let to_sub_row = |v: f64| -> usize {
-        // Map [min,max] → [1, sub_h-2] (usable band, 1 sub-row clear of
-        // each border).
-        let cont = (1.0 - (v - min) / span).clamp(0.0, 1.0) * (usable_h - 1) as f64;
-        1 + cont.round() as usize
+        let cont = (1.0 - (v - min) / span).clamp(0.0, 1.0) * (sub_h - 1) as f64;
+        cont.round() as usize
     };
 
     // Accumulate braille bits per cell. cells[row][col] = u8; 0 = blank.
@@ -227,17 +222,11 @@ pub fn render(
     }
 
     // Marker row: red '┄' on blank cells (first-blank-wins, as before).
-    // Marker row: red '┄' on blank cells. Map the caller's [0, rows-1]
-    // cell-row into the usable band [0, usable_h-1] sub-rows, then convert
-    // to a cell row so the marker stays in the same band as the trace.
-    let marker_cell_row = marker_row.map(|m| {
-        // m is in [0, rows-1] (caller's cell-row index). Rescale into the
-        // usable sub-row band and convert back to a cell row.
-        let sub = (m as f64 / (rows - 1).max(1) as f64) * (usable_h - 1) as f64;
-        let sub = sub.round() as usize;
-        let padded = 1 + sub; // back into full sub_h coordinates
-        (padded / 4).min(rows - 1)
-    });
+    // Marker row: red '┄' on blank cells, in the caller's [0, rows-1]
+    // cell-row (no padding — the caller's scale headroom keeps it clear
+    // of the borders in auto mode; in fixed mode a limit at the bound
+    // correctly sits at the box edge).
+    let marker_cell_row = marker_row.map(|m| (m as usize).min(rows - 1));
 
     let st = Style::default().fg(color);
     let marker_st = Style::default().fg(Color::Red);