git.sophuwu.com > statlog
added graph
sophuwu sophie@sophuwu.com
Mon, 07 Jul 2025 15:51:06 +0200
commit

b85e7e2f05a120255a85326813c345e1096c13b5

parent

9442924c4b751fac072d27c3b79e3aeb6a91f763

4 files changed, 117 insertions(+), 23 deletions(-)

jump to
M cmd/main.gocmd/main.go

@@ -3,6 +3,7 @@

import ( "fmt" "git.sophuwu.com/statlog" + "git.sophuwu.com/statlog/types" "os" "os/signal" )

@@ -26,11 +27,32 @@ <-ch

bl = false }() var s string + var ss string var e error + var fn func(w, h, val int) (string, error) + fn, e = types.Graph("CPU Load", 100) + w, _ := types.TermSize() + fatal(e) for bl { + s = "" hw.Update() - s, e = hw.CPU.LoadBar() + w, _ = types.TermSize() + ss, e = fn(w/2, 4, int(hw.CPU.LoadAvg)) fatal(e) + s += ss + "\n\n" + + // s += "MEM: " + hw.MEM.String() + // s += "\nCPU: " + hw.CPU.MHzAvg.String() + " MHz " + hw.CPU.Temp.String() + "\n\n" + // ss, e = hw.CPU.LoadAvg.Bar("CPU Avg", 0) + // fatal(e) + // s += ss + "\n\n" + // ss, e = hw.MEM.Bar() + // fatal(e) + // s += ss + "\n\nCPU CORES:\n\n" + // ss, e = hw.CPU.LoadBar() + // fatal(e) + // s += ss + "\n" + fmt.Printf("\033[2J\033[1;1H\r%s\n", s) } }
M tmp.gotmp.go

@@ -28,7 +28,7 @@ <-done

<-done } func (hw *HWInfo) String() string { - return fmt.Sprintf("%s | %s\n%s", hw.MEM.String(), hw.CPU.String(), hw.CPU.LoadCoreStr()) + return fmt.Sprintf("%s | %s\n", hw.MEM.String(), hw.CPU.String()) } func (hw *HWInfo) JSON() (string, error) { b, e := json.MarshalIndent(hw, "", " ")
M types/percent.gotypes/percent.go

@@ -49,25 +49,5 @@ *P = Percent(v)

} func (P *Percent) Bar(title string, w int) (s string, err error) { - if w == 0 { - w, _ = TermSize() - } - c := P.Compact() - s = title + " [" - w = w - len(s) - 2 - len(c) - - if w < 10 { - return "", fmt.Errorf("terminal too narrow") - } - - v := int(P.Value() * float64(w) / 100) - i := 0 - for i = 0; i < v; i++ { - s += "|" - } - for ; i < w; i++ { - s += " " - } - s += c + "] " - return s, nil + return Bar(title, w, int(P.Value()), 100, P.Compact()) }
M types/types.gotypes/types.go

@@ -32,3 +32,95 @@ 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 +}