From 2ee0ae7fcb3c8e1acd8b13e4c0878936dd73ceea Mon Sep 17 00:00:00 2001 From: Bradley Cicenas Date: Mon, 6 Mar 2017 08:51:50 +0000 Subject: [PATCH] re-implement expanded view widgets --- cwidgets/expanded/cpu.go | 28 ++++++++++++++++++ cwidgets/expanded/hist.go | 60 +++++++++++++++++++++++++++++++++++++++ cwidgets/expanded/info.go | 30 ++++++++++++++++++++ cwidgets/expanded/main.go | 42 +++++++++++++++++++++++++++ cwidgets/expanded/mem.go | 41 ++++++++++++++++++++++++++ cwidgets/expanded/net.go | 53 ++++++++++++++++++++++++++++++++++ grid.go | 46 ++++++++++++++++-------------- 7 files changed, 278 insertions(+), 22 deletions(-) create mode 100644 cwidgets/expanded/cpu.go create mode 100644 cwidgets/expanded/hist.go create mode 100644 cwidgets/expanded/info.go create mode 100644 cwidgets/expanded/main.go create mode 100644 cwidgets/expanded/mem.go create mode 100644 cwidgets/expanded/net.go diff --git a/cwidgets/expanded/cpu.go b/cwidgets/expanded/cpu.go new file mode 100644 index 0000000..a5c1491 --- /dev/null +++ b/cwidgets/expanded/cpu.go @@ -0,0 +1,28 @@ +package expanded + +import ( + ui "github.com/gizak/termui" +) + +type ExpandedCpu struct { + *ui.LineChart + hist FloatHist +} + +func NewExpandedCpu() *ExpandedCpu { + cpu := &ExpandedCpu{ui.NewLineChart(), NewFloatHist(60)} + cpu.BorderLabel = "CPU" + cpu.Height = 10 + cpu.Width = 50 + cpu.X = 0 + cpu.Y = 4 + cpu.Data = cpu.hist.Data + cpu.DataLabels = cpu.hist.Labels + cpu.AxesColor = ui.ColorDefault + cpu.LineColor = ui.ColorGreen + return cpu +} + +func (w *ExpandedCpu) Update(val int) { + w.hist.Append(float64(val)) +} diff --git a/cwidgets/expanded/hist.go b/cwidgets/expanded/hist.go new file mode 100644 index 0000000..b431f2e --- /dev/null +++ b/cwidgets/expanded/hist.go @@ -0,0 +1,60 @@ +package expanded + +type IntHist struct { + Val int // most current data point + Data []int // historical data points + Labels []string +} + +func NewIntHist(max int) *IntHist { + return &IntHist{ + Data: make([]int, max), + Labels: make([]string, max), + } +} + +func (h *IntHist) Append(val int) { + if len(h.Data) == cap(h.Data) { + h.Data = append(h.Data[:0], h.Data[1:]...) + } + h.Val = val + h.Data = append(h.Data, val) +} + +type DiffHist struct { + *IntHist + lastVal int +} + +func NewDiffHist(max int) *DiffHist { + return &DiffHist{NewIntHist(max), -1} +} + +func (h *DiffHist) Append(val int) { + if h.lastVal >= 0 { // skip append if this is the initial update + diff := val - h.lastVal + h.IntHist.Append(diff) + } + h.lastVal = val +} + +type FloatHist struct { + Val float64 // most current data point + Data []float64 // historical data points + Labels []string +} + +func NewFloatHist(max int) FloatHist { + return FloatHist{ + Data: make([]float64, max), + Labels: make([]string, max), + } +} + +func (h FloatHist) Append(val float64) { + if len(h.Data) == cap(h.Data) { + h.Data = append(h.Data[:0], h.Data[1:]...) + } + h.Val = val + h.Data = append(h.Data, val) +} diff --git a/cwidgets/expanded/info.go b/cwidgets/expanded/info.go new file mode 100644 index 0000000..5c918f1 --- /dev/null +++ b/cwidgets/expanded/info.go @@ -0,0 +1,30 @@ +package expanded + +import ( + ui "github.com/gizak/termui" +) + +type Info struct { + *ui.Table + data map[string]string +} + +func NewInfo(id string) *Info { + p := ui.NewTable() + p.Height = 4 + p.Width = 50 + p.FgColor = ui.ColorWhite + p.Seperator = false + i := &Info{p, make(map[string]string)} + i.Set("ID", id) + return i +} + +func (w *Info) Set(k, v string) { + w.data[k] = v + // rebuild rows + w.Rows = [][]string{} + for k, v := range w.data { + w.Rows = append(w.Rows, []string{k, v}) + } +} diff --git a/cwidgets/expanded/main.go b/cwidgets/expanded/main.go new file mode 100644 index 0000000..0eadbb4 --- /dev/null +++ b/cwidgets/expanded/main.go @@ -0,0 +1,42 @@ +package expanded + +import ( + "github.com/bcicen/ctop/metrics" + ui "github.com/gizak/termui" +) + +type Expanded struct { + Info *Info + Net *ExpandedNet + Cpu *ExpandedCpu + Mem *ExpandedMem + infoMap map[string]string +} + +func NewExpanded(id string) *Expanded { + return &Expanded{ + Info: NewInfo(id), + Net: NewExpandedNet(), + Cpu: NewExpandedCpu(), + Mem: NewExpandedMem(), + } +} + +func (w *Expanded) Buffer() ui.Buffer { + buf := ui.NewBuffer() + buf.Merge(w.Info.Buffer()) + buf.Merge(w.Cpu.Buffer()) + buf.Merge(w.Mem.Buffer()) + buf.Merge(w.Net.Buffer()) + return buf +} + +func (w *Expanded) SetMeta(k, v string) { + w.Info.Set(k, v) +} + +func (w *Expanded) SetMetrics(m metrics.Metrics) { + w.Cpu.Update(m.CPUUtil) + w.Net.Update(m.NetRx, m.NetTx) + w.Mem.Update(int(m.MemUsage), int(m.MemLimit)) +} diff --git a/cwidgets/expanded/mem.go b/cwidgets/expanded/mem.go new file mode 100644 index 0000000..3b2a755 --- /dev/null +++ b/cwidgets/expanded/mem.go @@ -0,0 +1,41 @@ +package expanded + +import ( + "github.com/bcicen/ctop/cwidgets" + ui "github.com/gizak/termui" +) + +type ExpandedMem struct { + *ui.BarChart + hist *IntHist +} + +func NewExpandedMem() *ExpandedMem { + mem := &ExpandedMem{ + ui.NewBarChart(), + NewIntHist(8), + } + mem.BorderLabel = "MEM" + mem.Height = 10 + mem.Width = 50 + mem.BarWidth = 5 + mem.BarGap = 1 + mem.X = 0 + mem.Y = 14 + mem.TextColor = ui.ColorDefault + mem.Data = mem.hist.Data + mem.BarColor = ui.ColorGreen + mem.DataLabels = mem.hist.Labels + mem.NumFmt = cwidgets.ByteFormatInt + return mem +} + +func (w *ExpandedMem) Update(val int, limit int) { + // implement our own scaling for mem graph + if val*4 < limit { + w.SetMax(val * 4) + } else { + w.SetMax(limit) + } + w.hist.Append(val) +} diff --git a/cwidgets/expanded/net.go b/cwidgets/expanded/net.go new file mode 100644 index 0000000..7213e0b --- /dev/null +++ b/cwidgets/expanded/net.go @@ -0,0 +1,53 @@ +package expanded + +import ( + "fmt" + "strings" + + "github.com/bcicen/ctop/cwidgets" + ui "github.com/gizak/termui" +) + +type ExpandedNet struct { + *ui.Sparklines + rxHist *DiffHist + txHist *DiffHist +} + +func NewExpandedNet() *ExpandedNet { + net := &ExpandedNet{ui.NewSparklines(), NewDiffHist(50), NewDiffHist(50)} + net.BorderLabel = "NET" + net.Height = 6 + net.Width = 50 + net.X = 0 + net.Y = 24 + + rx := ui.NewSparkline() + rx.Title = "RX" + rx.Height = 1 + rx.Data = net.rxHist.Data + rx.TitleColor = ui.ColorDefault + rx.LineColor = ui.ColorGreen + + tx := ui.NewSparkline() + tx.Title = "TX" + tx.Height = 1 + tx.Data = net.txHist.Data + tx.TitleColor = ui.ColorDefault + tx.LineColor = ui.ColorYellow + + net.Lines = []ui.Sparkline{rx, tx} + return net +} + +func (w *ExpandedNet) Update(rx int64, tx int64) { + var rate string + + w.rxHist.Append(int(rx)) + rate = strings.ToLower(cwidgets.ByteFormatInt(w.rxHist.Val)) + w.Lines[0].Title = fmt.Sprintf("RX [%s/s]", rate) + + w.txHist.Append(int(tx)) + rate = strings.ToLower(cwidgets.ByteFormatInt(w.txHist.Val)) + w.Lines[1].Title = fmt.Sprintf("TX [%s/s]", rate) +} diff --git a/grid.go b/grid.go index 23c6c88..880f81d 100644 --- a/grid.go +++ b/grid.go @@ -2,6 +2,7 @@ package main import ( "github.com/bcicen/ctop/config" + "github.com/bcicen/ctop/cwidgets/expanded" ui "github.com/gizak/termui" ) @@ -46,31 +47,29 @@ func RedrawRows() { ui.Render(cGrid) } -//func (g *Grid) ExpandView() { -//ui.Clear() -//ui.DefaultEvtStream.ResetHandlers() -//defer ui.DefaultEvtStream.ResetHandlers() +func ExpandView(c *Container) { + ui.Clear() + ui.DefaultEvtStream.ResetHandlers() + defer ui.DefaultEvtStream.ResetHandlers() -//container, _ := g.cSource.Get(g.cursorID) -//// copy current widgets to restore on exit view -//curWidgets := container.widgets -//container.Expand() + expandWidgets := expanded.NewExpanded(c.Id) + c.SetUpdater(expandWidgets) -//ui.Render(container.widgets) -//ui.Handle("/timer/1s", func(ui.Event) { -//ui.Render(container.widgets) -//}) -//ui.Handle("/sys/kbd/", func(ui.Event) { -//ui.StopLoop() -//}) -//ui.Loop() + ui.Render(expandWidgets) + ui.Handle("/timer/1s", func(ui.Event) { + ui.Render(expandWidgets) + }) + ui.Handle("/sys/kbd/", func(ui.Event) { + ui.StopLoop() + }) + ui.Loop() -//container.widgets = curWidgets -//container.widgets.Reset() -//} + c.SetUpdater(c.Widgets) +} func Display() bool { var menu func() + var expand bool cGrid.SetWidth(ui.TermWidth()) ui.DefaultEvtStream.Hook(logEvent) @@ -87,9 +86,8 @@ func Display() bool { cursor.Down() }) ui.Handle("/sys/kbd/", func(ui.Event) { - //c := g.containers[g.cursorIdx()] - //c.Widgets.ToggleExpand() - RedrawRows() + expand = true + ui.StopLoop() }) ui.Handle("/sys/kbd/a", func(ui.Event) { @@ -141,5 +139,9 @@ func Display() bool { menu() return false } + if expand { + ExpandView(cursor.Selected()) + return false + } return true }