feat(tui): overhaul latency sparkline scaling, color, and layout
CI / test (pull_request) Successful in 2m39s
CI / lint (pull_request) Failing after 56s
CI / vulncheck (pull_request) Successful in 51s

Replace misleading relative-only sparkline with dual-channel design:
bar height uses relative scaling (shows stability and anomalies),
color+brightness uses absolute thresholds (shows fast vs slow).

- Add brightness gradient within color bands (dim→bright as latency
  increases toward the next threshold)
- Pass row background through sparkline rendering so zebra stripes
  and selection highlights carry through ANSI sequences
- Cap sparkline width to 60 (matches maxHistoryLen) and column
  width to 62 to eliminate trailing dead space
- Quiet group sparkline: subtle dots for healthy, bold red for down
- Add braille subpixel canvas (ported from meridian) for future
  multi-row graph use
This commit is contained in:
2026-06-04 19:32:02 -04:00
parent 00fa381a7c
commit 986681ef8a
8 changed files with 349 additions and 35 deletions
+16 -3
View File
@@ -86,6 +86,9 @@ func (m Model) computeLayout() tableLayout {
if sparkW < 15 {
sparkW = 15
}
if sparkW > 62 {
sparkW = 62
}
widths[1] = nameW
widths[6] = sparkW
@@ -110,6 +113,9 @@ func (m Model) viewSitesTab() string {
if sparkWidth < 8 {
sparkWidth = 8
}
if sparkWidth > 60 {
sparkWidth = 60
}
var groupRows map[int]bool
return m.renderTable(
@@ -120,6 +126,13 @@ func (m Model) viewSitesTab() string {
var rows [][]string
for i := start; i < end; i++ {
site := m.sites[i]
rowIdx := i - start
var rowBg lipgloss.Color
if i == m.cursor {
rowBg = m.theme.SelectedBg
} else if rowIdx%2 == 1 {
rowBg = m.theme.ZebraBg
}
if site.Type == "group" {
groupRows[i-start] = true
@@ -131,7 +144,7 @@ func (m Model) viewSitesTab() string {
fmtStatus(site.Status, site.Paused, m.isMonitorInMaintenance(site.ID)),
subtleStyle.Render("—"),
m.groupUptime(site.ID),
m.groupSparkline(site.ID, sparkWidth),
m.groupSparkline(site.ID, sparkWidth, rowBg),
subtleStyle.Render("-"),
subtleStyle.Render("—"),
})
@@ -166,9 +179,9 @@ func (m Model) viewSitesTab() string {
hist, _ := m.engine.GetHistory(site.ID)
var spark string
if site.Type == "push" {
spark = heartbeatSparkline(hist.Statuses, sparkWidth)
spark = heartbeatSparkline(hist.Statuses, sparkWidth, rowBg)
} else {
spark = latencySparkline(hist.Latencies, hist.Statuses, sparkWidth)
spark = latencySparkline(hist.Latencies, hist.Statuses, sparkWidth, rowBg)
}
rows = append(rows, []string{