Top wears the skin; the refresh rate reaches every machine; bug bash 4

The process table's columns fit the box they are in, the rate control saves, curves are
timed on the viewer's clock and keep to the stride, the power icon is drawn, and a young
history draws in from the right instead of being stretched.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Mitchell-Johnson
2026-09-21 10:12:45 -07:00
co-authored by Claude Fable 5.1
parent ef3dbdf543
commit 668e716601
13 changed files with 394 additions and 107 deletions
+9
View File
@@ -59,6 +59,15 @@ export function strideMs(windowSec: number, refreshMs: number): number {
return Math.max(refreshMs, Math.round((windowSec * 1000) / HISTORY_POINTS))
}
// Is it time for a curve's next point? `last` is when the current one was started (this
// browser's clock; the caller keeps it). Half a tick of slack, because ticks never land exactly
// on time: without it a tick 5 ms early is "not yet" and every other point is skipped. The
// returned start keeps to the stride's own beat rather than drifting with each late tick.
export function nextPoint(now: number, last: number, stride: number, tickMs: number): { fresh: boolean; start: number } {
if (last === 0 || now - last >= stride - tickMs / 2) return { fresh: true, start: last === 0 || now - last > 2 * stride ? now : last + stride }
return { fresh: false, start: last }
}
export function fmtWindowSec(sec: number): string {
if (sec >= 3600) { const h = sec / 3600; return `${Number.isInteger(h) ? h : h.toFixed(1)} hour${h === 1 ? '' : 's'}` }
if (sec >= 60) { const m = sec / 60; return `${Number.isInteger(m) ? m : m.toFixed(1)} min` }