implemented components size/position save in yaml, defaults for optional settings
This commit is contained in:
parent
94c7d5011e
commit
687e6f098e
98
config.yml
98
config.yml
|
@ -1,78 +1,48 @@
|
||||||
theme: dark
|
theme: dark
|
||||||
runcharts:
|
runcharts:
|
||||||
- title: SEARCH ENGINE RESPONSE TIME (sec)
|
- title: SEARCH ENGINE RESPONSE TIME (sec)
|
||||||
items:
|
precision: 3
|
||||||
- label: GOOGLE
|
position:
|
||||||
script: curl -o /dev/null -s -w '%{time_total}' https://www.google.com/
|
w: 0
|
||||||
- label: YAHOO
|
h: 0
|
||||||
script: curl -o /dev/null -s -w '%{time_total}' https://search.yahoo.com/
|
size:
|
||||||
- label: BING
|
w: 30
|
||||||
script: curl -o /dev/null -s -w '%{time_total}' https://www.bing.com/
|
h: 20
|
||||||
refresh-rate-ms: 200
|
|
||||||
decimal-places: 3
|
|
||||||
alert:
|
|
||||||
value:
|
|
||||||
more-than: 0.231
|
|
||||||
less-than: 0.123
|
|
||||||
equal: 0.144
|
|
||||||
indicator:
|
|
||||||
terminal: true
|
|
||||||
beep: true
|
|
||||||
legend:
|
legend:
|
||||||
enabled: true
|
enabled: true
|
||||||
details: true
|
details: true
|
||||||
position:
|
|
||||||
x: 0
|
|
||||||
y: 0
|
|
||||||
size:
|
|
||||||
x: 30
|
|
||||||
y: 15
|
|
||||||
- title: SEARCH ENGINE RESPONSE TIME 2 (sec)
|
|
||||||
items:
|
items:
|
||||||
- label: GOOGLE
|
- script: curl -o /dev/null -s -w '%{time_total}' https://www.google.com/
|
||||||
script: curl -o /dev/null -s -w '%{time_total}' https://www.google.com/
|
label: GOOGLE
|
||||||
- label: YAHOO
|
- script: curl -o /dev/null -s -w '%{time_total}' https://search.yahoo.com/
|
||||||
script: curl -o /dev/null -s -w '%{time_total}' https://search.yahoo.com/
|
label: YAHOO
|
||||||
- label: BING
|
- script: curl -o /dev/null -s -w '%{time_total}' https://www.bing.com/
|
||||||
script: curl -o /dev/null -s -w '%{time_total}' https://www.bing.com/
|
label: BING
|
||||||
|
- title: SEARCH ENGINE RESPONSE TIME 2 (sec)
|
||||||
refresh-rate-ms: 5000
|
refresh-rate-ms: 5000
|
||||||
decimal-places: 3
|
position:
|
||||||
alert:
|
w: 0
|
||||||
value:
|
h: 20
|
||||||
more-than: 0.231
|
size:
|
||||||
less-than: 0.123
|
w: 15
|
||||||
equal: 0.144
|
h: 10
|
||||||
indicator:
|
|
||||||
terminal: true
|
|
||||||
beep: true
|
|
||||||
legend:
|
legend:
|
||||||
enabled: true
|
enabled: true
|
||||||
details: false
|
details: false
|
||||||
position:
|
|
||||||
x: 0
|
|
||||||
y: 15
|
|
||||||
size:
|
|
||||||
x: 15
|
|
||||||
y: 15
|
|
||||||
- title: MONGO COLLECTIONS COUNT
|
|
||||||
items:
|
items:
|
||||||
- label: POSTS
|
- script: curl -o /dev/null -s -w '%{time_total}' https://www.google.com/
|
||||||
script: mongo --quiet --host=localhost blog --eval "db.getCollection('post').find({}).size()"
|
label: GOOGLE
|
||||||
|
- script: curl -o /dev/null -s -w '%{time_total}' https://search.yahoo.com/
|
||||||
|
label: YAHOO
|
||||||
|
- script: curl -o /dev/null -s -w '%{time_total}' https://www.bing.com/
|
||||||
|
label: BING
|
||||||
|
- title: MONGO COLLECTIONS COUNT
|
||||||
position:
|
position:
|
||||||
x: 15
|
w: 15
|
||||||
y: 15
|
h: 20
|
||||||
size:
|
size:
|
||||||
x: 15
|
w: 15
|
||||||
y: 15
|
h: 10
|
||||||
barcharts:
|
items:
|
||||||
none
|
- script: mongo --quiet --host=localhost blog --eval "db.getCollection('post').find({}).size()"
|
||||||
sparklines:
|
label: POSTS
|
||||||
none
|
|
||||||
gauges:
|
|
||||||
none
|
|
||||||
lists:
|
|
||||||
none
|
|
||||||
textboxes:
|
|
||||||
none
|
|
||||||
asciiboxes:
|
|
||||||
none
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"github.com/sqshq/sampler/console"
|
"github.com/sqshq/sampler/console"
|
||||||
"github.com/sqshq/sampler/data"
|
"github.com/sqshq/sampler/data"
|
||||||
. "github.com/sqshq/sampler/widgets"
|
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
@ -11,18 +11,22 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Theme console.Theme `yaml:"theme"`
|
Theme *console.Theme `yaml:"theme,omitempty"`
|
||||||
RunCharts []RunChartConfig `yaml:"runcharts"`
|
RunCharts []RunChartConfig `yaml:"runcharts,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ComponentConfig struct {
|
||||||
|
Title string `yaml:"title"`
|
||||||
|
RefreshRateMs *int `yaml:"refresh-rate-ms,omitempty"`
|
||||||
|
Precision *int `yaml:"precision,omitempty"`
|
||||||
|
Position Position `yaml:"position"`
|
||||||
|
Size Size `yaml:"size"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RunChartConfig struct {
|
type RunChartConfig struct {
|
||||||
Title string `yaml:"title"`
|
ComponentConfig `yaml:",inline"`
|
||||||
|
Legend *LegendConfig `yaml:"legend,omitempty"`
|
||||||
Items []data.Item `yaml:"items"`
|
Items []data.Item `yaml:"items"`
|
||||||
Position Position `yaml:"position"`
|
|
||||||
Size Size `yaml:"size"`
|
|
||||||
RefreshRateMs int `yaml:"refresh-rate-ms"`
|
|
||||||
Precision int `yaml:"decimal-places"`
|
|
||||||
Legend LegendConfig `yaml:"legend"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type LegendConfig struct {
|
type LegendConfig struct {
|
||||||
|
@ -30,6 +34,30 @@ type LegendConfig struct {
|
||||||
Details bool `yaml:"details"`
|
Details bool `yaml:"details"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Position struct {
|
||||||
|
X int `yaml:"w"`
|
||||||
|
Y int `yaml:"h"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Size struct {
|
||||||
|
X int `yaml:"w"`
|
||||||
|
Y int `yaml:"h"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ComponentType rune
|
||||||
|
|
||||||
|
const (
|
||||||
|
TypeRunChart ComponentType = 0
|
||||||
|
TypeBarChart ComponentType = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
type ComponentSettings struct {
|
||||||
|
Type ComponentType
|
||||||
|
Title string
|
||||||
|
Size Size
|
||||||
|
Position Position
|
||||||
|
}
|
||||||
|
|
||||||
func Load() *Config {
|
func Load() *Config {
|
||||||
|
|
||||||
if len(os.Args) < 2 {
|
if len(os.Args) < 2 {
|
||||||
|
@ -39,13 +67,36 @@ func Load() *Config {
|
||||||
|
|
||||||
cfg := readFile(os.Args[1])
|
cfg := readFile(os.Args[1])
|
||||||
cfg.validate()
|
cfg.validate()
|
||||||
cfg.setDefaultValues()
|
cfg.setDefaults()
|
||||||
cfg.setDefaultColors()
|
|
||||||
cfg.setDefaultLayout()
|
|
||||||
|
|
||||||
return cfg
|
return cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Update(settings []ComponentSettings) {
|
||||||
|
cfg := readFile(os.Args[1])
|
||||||
|
for _, s := range settings {
|
||||||
|
componentConfig := cfg.findComponent(s.Type, s.Title)
|
||||||
|
componentConfig.Size = s.Size
|
||||||
|
componentConfig.Position = s.Position
|
||||||
|
}
|
||||||
|
saveFile(cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) findComponent(componentType ComponentType, componentTitle string) *ComponentConfig {
|
||||||
|
|
||||||
|
switch componentType {
|
||||||
|
case TypeRunChart:
|
||||||
|
for i, component := range c.RunCharts {
|
||||||
|
if component.Title == componentTitle {
|
||||||
|
return &c.RunCharts[i].ComponentConfig
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panic(fmt.Sprintf(
|
||||||
|
"Can't find component type %v with title %v", componentType, componentTitle))
|
||||||
|
}
|
||||||
|
|
||||||
func readFile(location string) *Config {
|
func readFile(location string) *Config {
|
||||||
|
|
||||||
yamlFile, err := ioutil.ReadFile(location)
|
yamlFile, err := ioutil.ReadFile(location)
|
||||||
|
@ -62,3 +113,15 @@ func readFile(location string) *Config {
|
||||||
|
|
||||||
return cfg
|
return cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func saveFile(config *Config) {
|
||||||
|
file, err := yaml.Marshal(config)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Can't marshal config file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ioutil.WriteFile("config.yml", file, 0644)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Can't save config file: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -10,35 +10,48 @@ const (
|
||||||
defaultTheme = console.ThemeDark
|
defaultTheme = console.ThemeDark
|
||||||
)
|
)
|
||||||
|
|
||||||
func (self *Config) setDefaultValues() {
|
func (c *Config) setDefaults() {
|
||||||
|
c.setDefaultValues()
|
||||||
if len(self.Theme) == 0 {
|
c.setDefaultColors()
|
||||||
self.Theme = defaultTheme
|
c.setDefaultLayout()
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, chart := range self.RunCharts {
|
func (c *Config) setDefaultValues() {
|
||||||
if chart.RefreshRateMs == 0 {
|
|
||||||
chart.RefreshRateMs = defaultRefreshRateMs
|
if c.Theme == nil {
|
||||||
|
t := defaultTheme
|
||||||
|
c.Theme = &t
|
||||||
}
|
}
|
||||||
if chart.Precision == 0 {
|
|
||||||
chart.Precision = defaultPrecision
|
for i, chart := range c.RunCharts {
|
||||||
|
if chart.RefreshRateMs == nil {
|
||||||
|
r := defaultRefreshRateMs
|
||||||
|
chart.RefreshRateMs = &r
|
||||||
}
|
}
|
||||||
self.RunCharts[i] = chart
|
if chart.Precision == nil {
|
||||||
|
p := defaultPrecision
|
||||||
|
chart.Precision = &p
|
||||||
|
}
|
||||||
|
if chart.Legend == nil {
|
||||||
|
chart.Legend = &LegendConfig{true, true}
|
||||||
|
c.RunCharts[i] = chart
|
||||||
|
}
|
||||||
|
c.RunCharts[i] = chart
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config *Config) setDefaultLayout() {
|
func (c *Config) setDefaultLayout() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config *Config) setDefaultColors() {
|
func (c *Config) setDefaultColors() {
|
||||||
|
|
||||||
palette := console.GetPalette(config.Theme)
|
palette := console.GetPalette(*c.Theme)
|
||||||
|
|
||||||
for i, chart := range config.RunCharts {
|
for i, chart := range c.RunCharts {
|
||||||
for j, item := range chart.Items {
|
for j, item := range chart.Items {
|
||||||
if item.Color == 0 {
|
if item.Color == nil {
|
||||||
item.Color = palette.Colors[i+j] // TODO handle out of range case
|
item.Color = &palette.Colors[i+j] // TODO handle out of range case
|
||||||
chart.Items[j] = item
|
chart.Items[j] = item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,6 @@ package config
|
||||||
- title uniquness and mandatory within a single type of widget
|
- title uniquness and mandatory within a single type of widget
|
||||||
- label uniqueness and mandatory (if > 1 data bullets)
|
- label uniqueness and mandatory (if > 1 data bullets)
|
||||||
*/
|
*/
|
||||||
func (self *Config) validate() {
|
func (c *Config) validate() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,12 @@ import (
|
||||||
type Item struct {
|
type Item struct {
|
||||||
Script string `yaml:"script"`
|
Script string `yaml:"script"`
|
||||||
Label string `yaml:"label"`
|
Label string `yaml:"label"`
|
||||||
Color ui.Color `yaml:"color"`
|
Color *ui.Color `yaml:"color,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Item) nextValue() (value string, err error) {
|
func (i *Item) nextValue() (value string, err error) {
|
||||||
|
|
||||||
output, err := exec.Command("sh", "-c", self.Script).Output()
|
output, err := exec.Command("sh", "-c", i.Script).Output()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
|
|
@ -11,10 +11,12 @@ type Sampler struct {
|
||||||
|
|
||||||
func NewSampler(consumer Consumer, item Item, rateMs int) Sampler {
|
func NewSampler(consumer Consumer, item Item, rateMs int) Sampler {
|
||||||
|
|
||||||
|
ticker := time.NewTicker(time.Duration(rateMs * int(time.Millisecond)))
|
||||||
sampler := Sampler{consumer, item}
|
sampler := Sampler{consumer, item}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for t := time.Tick(time.Duration(rateMs * int(time.Millisecond))); ; <-t {
|
sampler.sample()
|
||||||
|
for ; true; <-ticker.C {
|
||||||
sampler.sample()
|
sampler.sample()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package event
|
package event
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/sqshq/sampler/config"
|
||||||
"github.com/sqshq/sampler/console"
|
"github.com/sqshq/sampler/console"
|
||||||
"github.com/sqshq/sampler/widgets"
|
"github.com/sqshq/sampler/widgets"
|
||||||
ui "github.com/sqshq/termui"
|
ui "github.com/sqshq/termui"
|
||||||
|
@ -13,28 +14,38 @@ type Handler struct {
|
||||||
ConsoleEvents <-chan ui.Event
|
ConsoleEvents <-chan ui.Event
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Handler) HandleEvents() {
|
func (h *Handler) HandleEvents() {
|
||||||
|
|
||||||
pause := false
|
pause := false
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-self.RenderEvents:
|
case <-h.RenderEvents:
|
||||||
if !pause {
|
if !pause {
|
||||||
ui.Render(self.Layout)
|
ui.Render(h.Layout)
|
||||||
}
|
}
|
||||||
case e := <-self.ConsoleEvents:
|
case e := <-h.ConsoleEvents:
|
||||||
switch e.ID {
|
switch e.ID {
|
||||||
case console.KeyQuit, console.KeyExit:
|
case console.KeyQuit, console.KeyExit:
|
||||||
|
h.handleExit()
|
||||||
return
|
return
|
||||||
case console.KeyPause:
|
case console.KeyPause:
|
||||||
pause = !pause
|
pause = !pause
|
||||||
case console.SignalResize:
|
case console.SignalResize:
|
||||||
payload := e.Payload.(ui.Resize)
|
payload := e.Payload.(ui.Resize)
|
||||||
self.Layout.ChangeDimensions(payload.Width, payload.Height)
|
h.Layout.ChangeDimensions(payload.Width, payload.Height)
|
||||||
default:
|
default:
|
||||||
self.Layout.HandleConsoleEvent(e.ID)
|
h.Layout.HandleConsoleEvent(e.ID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Handler) handleExit() {
|
||||||
|
var settings []config.ComponentSettings
|
||||||
|
for _, c := range h.Layout.Components {
|
||||||
|
settings = append(settings,
|
||||||
|
config.ComponentSettings{Type: c.Type, Title: c.Title, Size: c.Size, Position: c.Position})
|
||||||
|
}
|
||||||
|
config.Update(settings)
|
||||||
|
}
|
||||||
|
|
8
main.go
8
main.go
|
@ -24,12 +24,12 @@ func main() {
|
||||||
for _, c := range cfg.RunCharts {
|
for _, c := range cfg.RunCharts {
|
||||||
|
|
||||||
legend := runchart.Legend{Enabled: c.Legend.Enabled, Details: c.Legend.Details}
|
legend := runchart.Legend{Enabled: c.Legend.Enabled, Details: c.Legend.Details}
|
||||||
chart := runchart.NewRunChart(c.Title, c.Precision, c.RefreshRateMs, legend)
|
chart := runchart.NewRunChart(c.Title, *c.Precision, *c.RefreshRateMs, legend)
|
||||||
layout.AddComponent(chart, c.Title, c.Position, c.Size, widgets.TypeRunChart)
|
layout.AddComponent(chart, c.Title, c.Position, c.Size, config.TypeRunChart)
|
||||||
|
|
||||||
for _, item := range c.Items {
|
for _, item := range c.Items {
|
||||||
chart.AddLine(item.Label, item.Color)
|
chart.AddLine(item.Label, *item.Color)
|
||||||
data.NewSampler(chart, item, c.RefreshRateMs)
|
data.NewSampler(chart, item, *c.RefreshRateMs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,32 +1,16 @@
|
||||||
package widgets
|
package widgets
|
||||||
|
|
||||||
import (
|
import (
|
||||||
. "github.com/sqshq/termui"
|
"github.com/sqshq/sampler/config"
|
||||||
|
ui "github.com/sqshq/termui"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Component struct {
|
type Component struct {
|
||||||
Drawable Drawable
|
Drawable ui.Drawable
|
||||||
Title string
|
Title string
|
||||||
Position Position
|
Position config.Position
|
||||||
Size Size
|
Size config.Size
|
||||||
Type ComponentType
|
Type config.ComponentType
|
||||||
}
|
|
||||||
|
|
||||||
type ComponentType rune
|
|
||||||
|
|
||||||
const (
|
|
||||||
TypeRunChart ComponentType = 0
|
|
||||||
TypeBarChart ComponentType = 1
|
|
||||||
)
|
|
||||||
|
|
||||||
type Position struct {
|
|
||||||
X int `yaml:"x"`
|
|
||||||
Y int `yaml:"y"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Size struct {
|
|
||||||
X int `yaml:"x"`
|
|
||||||
Y int `yaml:"y"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Component) Move(x, y int) {
|
func (c *Component) Move(x, y int) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package widgets
|
package widgets
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/sqshq/sampler/config"
|
||||||
"github.com/sqshq/sampler/console"
|
"github.com/sqshq/sampler/console"
|
||||||
"github.com/sqshq/sampler/widgets/runchart"
|
"github.com/sqshq/sampler/widgets/runchart"
|
||||||
ui "github.com/sqshq/termui"
|
ui "github.com/sqshq/termui"
|
||||||
|
@ -8,7 +9,7 @@ import (
|
||||||
|
|
||||||
type Layout struct {
|
type Layout struct {
|
||||||
ui.Block
|
ui.Block
|
||||||
components []Component
|
Components []Component
|
||||||
menu *Menu
|
menu *Menu
|
||||||
mode Mode
|
mode Mode
|
||||||
selection int
|
selection int
|
||||||
|
@ -37,22 +38,22 @@ func NewLayout(width, height int, menu *Menu) *Layout {
|
||||||
|
|
||||||
return &Layout{
|
return &Layout{
|
||||||
Block: block,
|
Block: block,
|
||||||
components: make([]Component, 0),
|
Components: make([]Component, 0),
|
||||||
menu: menu,
|
menu: menu,
|
||||||
mode: ModeDefault,
|
mode: ModeDefault,
|
||||||
selection: 0,
|
selection: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Layout) AddComponent(drawable ui.Drawable, title string, position Position, size Size, Type ComponentType) {
|
func (l *Layout) AddComponent(drawable ui.Drawable, title string, position config.Position, size config.Size, Type config.ComponentType) {
|
||||||
l.components = append(l.components, Component{drawable, title, position, size, Type})
|
l.Components = append(l.Components, Component{drawable, title, position, size, Type})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Layout) GetComponents(Type ComponentType) []ui.Drawable {
|
func (l *Layout) GetComponents(Type config.ComponentType) []ui.Drawable {
|
||||||
|
|
||||||
var components []ui.Drawable
|
var components []ui.Drawable
|
||||||
|
|
||||||
for _, component := range l.components {
|
for _, component := range l.Components {
|
||||||
if component.Type == Type {
|
if component.Type == Type {
|
||||||
components = append(components, component.Drawable)
|
components = append(components, component.Drawable)
|
||||||
}
|
}
|
||||||
|
@ -133,7 +134,7 @@ func (l *Layout) HandleConsoleEvent(e string) {
|
||||||
chart := l.getSelectedComponent().Drawable.(*runchart.RunChart)
|
chart := l.getSelectedComponent().Drawable.(*runchart.RunChart)
|
||||||
chart.MoveSelection(1)
|
chart.MoveSelection(1)
|
||||||
case ModeComponentSelect:
|
case ModeComponentSelect:
|
||||||
if l.selection < len(l.components)-1 {
|
if l.selection < len(l.Components)-1 {
|
||||||
l.selection++
|
l.selection++
|
||||||
}
|
}
|
||||||
l.menu.highlight(l.getComponent(l.selection))
|
l.menu.highlight(l.getComponent(l.selection))
|
||||||
|
@ -167,7 +168,7 @@ func (l *Layout) HandleConsoleEvent(e string) {
|
||||||
l.selection = 0
|
l.selection = 0
|
||||||
l.menu.highlight(l.getComponent(l.selection))
|
l.menu.highlight(l.getComponent(l.selection))
|
||||||
case ModeComponentSelect:
|
case ModeComponentSelect:
|
||||||
if l.selection < len(l.components)-1 {
|
if l.selection < len(l.Components)-1 {
|
||||||
l.selection++
|
l.selection++
|
||||||
}
|
}
|
||||||
l.menu.highlight(l.getComponent(l.selection))
|
l.menu.highlight(l.getComponent(l.selection))
|
||||||
|
@ -187,11 +188,11 @@ func (l *Layout) ChangeDimensions(width, height int) {
|
||||||
|
|
||||||
// TODO func to get prev/next component navigating left/right/top/bottom
|
// TODO func to get prev/next component navigating left/right/top/bottom
|
||||||
func (l *Layout) getComponent(i int) Component {
|
func (l *Layout) getComponent(i int) Component {
|
||||||
return l.components[i]
|
return l.Components[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Layout) getSelectedComponent() *Component {
|
func (l *Layout) getSelectedComponent() *Component {
|
||||||
return &l.components[l.selection]
|
return &l.Components[l.selection]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Layout) Draw(buffer *ui.Buffer) {
|
func (l *Layout) Draw(buffer *ui.Buffer) {
|
||||||
|
@ -199,7 +200,7 @@ func (l *Layout) Draw(buffer *ui.Buffer) {
|
||||||
columnWidth := float64(l.GetRect().Dx()) / columnsCount
|
columnWidth := float64(l.GetRect().Dx()) / columnsCount
|
||||||
rowHeight := float64(l.GetRect().Dy()) / rowsCount
|
rowHeight := float64(l.GetRect().Dy()) / rowsCount
|
||||||
|
|
||||||
for _, component := range l.components {
|
for _, component := range l.Components {
|
||||||
|
|
||||||
x1 := float64(component.Position.X) * columnWidth
|
x1 := float64(component.Position.X) * columnWidth
|
||||||
y1 := float64(component.Position.Y) * rowHeight
|
y1 := float64(component.Position.Y) * rowHeight
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package widgets
|
package widgets
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/sqshq/sampler/config"
|
||||||
"github.com/sqshq/sampler/console"
|
"github.com/sqshq/sampler/console"
|
||||||
ui "github.com/sqshq/termui"
|
ui "github.com/sqshq/termui"
|
||||||
"image"
|
"image"
|
||||||
|
@ -191,7 +192,7 @@ func (m *Menu) renderOptions(buffer *ui.Buffer) {
|
||||||
style = highlightedStyle
|
style = highlightedStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
if option != MenuOptionPinpoint || m.component.Type == TypeRunChart {
|
if option != MenuOptionPinpoint || m.component.Type == config.TypeRunChart {
|
||||||
offset += 2
|
offset += 2
|
||||||
point := getMiddlePoint(m.Block, string(option), offset-5)
|
point := getMiddlePoint(m.Block, string(option), offset-5)
|
||||||
if point.In(m.GetRect()) {
|
if point.In(m.GetRect()) {
|
||||||
|
|
|
@ -328,9 +328,13 @@ func getMidRangeTime(r TimeRange) time.Time {
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatValue(value float64, precision int) string {
|
func formatValue(value float64, precision int) string {
|
||||||
|
if math.Abs(value) == math.MaxFloat64 {
|
||||||
|
return "Inf"
|
||||||
|
} else {
|
||||||
format := "%." + strconv.Itoa(precision) + "f"
|
format := "%." + strconv.Itoa(precision) + "f"
|
||||||
return fmt.Sprintf(format, value)
|
return fmt.Sprintf(format, value)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// time duration between grid lines
|
// time duration between grid lines
|
||||||
func calculateTimescale(refreshRateMs int) time.Duration {
|
func calculateTimescale(refreshRateMs int) time.Duration {
|
||||||
|
|
Loading…
Reference in New Issue