126
package types
import (
"fmt"
"golang.org/x/term"
)
type MHz int
func (m MHz) String() string {
if m < 0 {
return ""
}
return fmt.Sprintf("%4d MHz", m)
}
type Celsius int
func (c Celsius) String() string {
if c <= -50 {
return ""
}
return fmt.Sprintf("%3d C", c)
}
func TermSize() (w int, h int) {
var e error
w, h, e = term.GetSize(0)
if e != nil {
w = 80
h = 24
}
return
}
func Bar(title string, w, val, max int, vlbl string) (string, error) {
if max <= 0 || val < 0 || val > max {
return "", fmt.Errorf("invalid values: val=%d, max=%d", val, max)
}
if w == 0 {
w, _ = TermSize()
}
s := title + " ["
w = w - len(s) - 2 - len(vlbl)
if w < 10 {
return "", fmt.Errorf("terminal too narrow")
}
val = int(float64(val) * float64(w) / float64(max))
i := 0
for ; i < w && i < val; i++ {
s += "|"
}
for ; i < w; i++ {
s += " "
}
s += vlbl + "] "
return s, nil
}
var gch = []string{" ", "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█"}
func Graph(title string, max int) (func(w, h, val int) (string, error), error) {
var vals []int
if max <= 0 {
return nil, fmt.Errorf("invalid max value: %d", max)
}
maxs := fmt.Sprintf("%d", max)
return func(w, h, val int) (string, error) {
if w == 0 {
w, _ = TermSize()
}
if h == 0 {
h = 2
}
if val < 0 || val > max {
return "", fmt.Errorf("invalid value: %d, max: %d", val, max)
}
vals = append(vals, val)
if len(vals) < w {
ii := make([]int, w-len(vals))
vals = append(ii, vals...)
} else if len(vals) > 2*w {
vals = vals[len(vals)-2*w:]
}
s := fmt.Sprintf("%s\033[%dC%s\033[%dB\033[%dD0\033[%dD", title, w-len(maxs)-len(title), maxs, h+1, 1, w)
s += fmt.Sprintf("%s\033[%dD", title, len(title)+2)
var j, i int
vv := make([]int, 0)
j = len(vals) - w
if j < 0 {
return "", fmt.Errorf("not enough data points: %d, required: %d", len(vals), w)
}
for ; j < len(vals); j++ {
vv = append(vv, vals[j]*h*len(gch)/max)
}
var v int
for i = 0; i < h; i++ {
s += "\033[1A" + func() string {
if i%2 == 0 {
return "\033[1;37m"
}
return "\033[1;97m"
}()
for j, v = range vv {
v -= i * len(gch)
if v < len(gch) {
if v < 0 {
v = 0
}
s += gch[v]
} else if v >= len(gch) {
s += gch[len(gch)-1]
} else {
s += gch[v%len(gch)]
}
}
s += fmt.Sprintf("\033[0m\033[%dD", j+2)
}
s += fmt.Sprintf("\033[%dB\033[0m\n", h+2)
return s, nil
}, nil
}