Rework the panel onto SI figures, labelled chips and one spacing scale
This commit is contained in:
@@ -57,11 +57,6 @@ func pad(s string, w int, right bool) string {
|
||||
return s + strings.Repeat(" ", gap)
|
||||
}
|
||||
|
||||
func uptime(d time.Duration) string {
|
||||
total := int(d.Seconds())
|
||||
return fmt.Sprintf("%d:%02d:%02d", total/3600, (total/60)%60, total%60)
|
||||
}
|
||||
|
||||
func commas(v uint64) string {
|
||||
s := fmt.Sprintf("%d", v)
|
||||
if len(s) <= 3 {
|
||||
@@ -94,6 +89,37 @@ func humanBytes(b uint64) string {
|
||||
return fmt.Sprintf("%.1f PB", v)
|
||||
}
|
||||
|
||||
// A figure with the letter for its magnitude, so the unit itself can stay a
|
||||
// fixed word on the label and only the letter moves with the value. Below a
|
||||
// thousand there is no letter and none is left dangling, since a trailing space
|
||||
// would push the figure off centre.
|
||||
func scaleSI(v float64) string {
|
||||
for _, mag := range []string{"", "k", "M", "G", "T"} {
|
||||
if v < 1000 {
|
||||
if mag == "" {
|
||||
return fmt.Sprintf("%.2f", v)
|
||||
}
|
||||
return fmt.Sprintf("%.2f %s", v, mag)
|
||||
}
|
||||
v /= 1000
|
||||
}
|
||||
return fmt.Sprintf("%.2f P", v)
|
||||
}
|
||||
|
||||
// The same shape for time, whose magnitudes are sixties and twenty-fours rather
|
||||
// than thousands. The letter changes with the value; the label does not.
|
||||
func scaleTime(d time.Duration) string {
|
||||
switch {
|
||||
case d < time.Minute:
|
||||
return fmt.Sprintf("%.2f s", d.Seconds())
|
||||
case d < time.Hour:
|
||||
return fmt.Sprintf("%.2f m", d.Minutes())
|
||||
case d < 24*time.Hour:
|
||||
return fmt.Sprintf("%.2f h", d.Hours())
|
||||
}
|
||||
return fmt.Sprintf("%.2f d", d.Hours()/24)
|
||||
}
|
||||
|
||||
type colSpec struct {
|
||||
title string
|
||||
width int
|
||||
@@ -216,6 +242,9 @@ func renderBox(title string, headers []string, rights []bool, rows [][]string) s
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// Counted exactly rather than scaled: these are whole frames, and the figure
|
||||
// that matters most is the small one. Scaled, a single lost frame and a
|
||||
// thousand of them both read as 1.00, separated only by a letter.
|
||||
func statusCell(v uint64) string {
|
||||
s := commas(v)
|
||||
if v == 0 {
|
||||
@@ -231,12 +260,12 @@ const (
|
||||
rateYellowFrac = 0.80
|
||||
)
|
||||
|
||||
func rateCell(gb float64, target float64) string {
|
||||
s := fmt.Sprintf("%.2f", gb)
|
||||
func rateCell(bits float64, target float64) string {
|
||||
s := scaleSI(bits)
|
||||
switch {
|
||||
case gb >= target*rateGreenFrac:
|
||||
case bits >= target*rateGreenFrac:
|
||||
return paint(s, cGreen)
|
||||
case gb >= target*rateYellowFrac:
|
||||
case bits >= target*rateYellowFrac:
|
||||
return paint(s, cYellow)
|
||||
default:
|
||||
return paint(s, cRed)
|
||||
|
||||
Reference in New Issue
Block a user