sparkline config and infrastructure added

This commit is contained in:
sqshq 2019-03-24 18:46:39 -04:00
parent d77dd1e524
commit db3888e540
8 changed files with 111 additions and 8 deletions

View File

@ -16,10 +16,10 @@ import (
) )
const ( const (
xAxisGridWidth = xAxisLabelsIndent + xAxisLabelsWidth
xAxisLabelsHeight = 1 xAxisLabelsHeight = 1
xAxisLabelsWidth = 8 xAxisLabelsWidth = 8
xAxisLabelsIndent = 2 xAxisLabelsIndent = 2
xAxisGridWidth = xAxisLabelsIndent + xAxisLabelsWidth
yAxisLabelsHeight = 1 yAxisLabelsHeight = 1
yAxisLabelsIndent = 1 yAxisLabelsIndent = 1
historyReserveMin = 20 historyReserveMin = 20

View File

@ -0,0 +1,61 @@
package sparkline
import (
ui "github.com/gizak/termui/v3"
"github.com/sqshq/sampler/component"
"github.com/sqshq/sampler/config"
"github.com/sqshq/sampler/console"
"github.com/sqshq/sampler/data"
"strconv"
)
type SparkLine struct {
*ui.Block
*data.Consumer
alert *data.Alert
values []float64
palette console.Palette
}
func NewSparkLine(c config.SparkLineConfig, palette console.Palette) *SparkLine {
line := &SparkLine{
Block: component.NewBlock(c.Title, true, palette),
Consumer: data.NewConsumer(),
values: []float64{},
palette: palette,
}
go func() {
for {
select {
case sample := <-line.SampleChannel:
line.consumeSample(sample)
case alert := <-line.AlertChannel:
line.alert = alert
}
}
}()
return line
}
func (s *SparkLine) consumeSample(sample *data.Sample) {
float, err := strconv.ParseFloat(sample.Value, 64)
if err != nil {
s.AlertChannel <- &data.Alert{
Title: "FAILED TO PARSE NUMBER",
Text: err.Error(),
Color: sample.Color,
}
return
}
s.values = append(s.values, float)
// TODO cleanup old ones
}
func (s *SparkLine) Draw(buffer *ui.Buffer) {
s.Block.Draw(buffer)
}

View File

@ -80,6 +80,11 @@ asciiboxes:
position: [[53, 17], [27, 5]] position: [[53, 17], [27, 5]]
value: date +%r value: date +%r
- title: UTC TIME - title: UTC TIME
position: [[53, 22], [27, 6]] position: [[53, 22], [27, 7]]
value: env TZ=UTC date +%r value: env TZ=UTC date +%r
font: 3d font: 3d
sparklines:
- title: CPU usage
position: [[28, 17], [25, 12]]
scale: 0
value: ps -A -o %cpu | awk '{s+=$1} END {print s}'

View File

@ -53,6 +53,12 @@ type GaugeConfig struct {
Items []Item `yaml:",omitempty"` Items []Item `yaml:",omitempty"`
} }
type SparkLineConfig struct {
ComponentConfig `yaml:",inline"`
Scale *int `yaml:"scale,omitempty"`
Item Item `yaml:",inline"`
}
type BarChartConfig struct { type BarChartConfig struct {
ComponentConfig `yaml:",inline"` ComponentConfig `yaml:",inline"`
Scale *int `yaml:"scale,omitempty"` Scale *int `yaml:"scale,omitempty"`

View File

@ -11,11 +11,12 @@ import (
) )
type Config struct { type Config struct {
Theme *console.Theme `yaml:"theme,omitempty"` Theme *console.Theme `yaml:"theme,omitempty"`
RunCharts []RunChartConfig `yaml:"runcharts,omitempty"` RunCharts []RunChartConfig `yaml:"runcharts,omitempty"`
BarCharts []BarChartConfig `yaml:"barcharts,omitempty"` BarCharts []BarChartConfig `yaml:"barcharts,omitempty"`
Gauges []GaugeConfig `yaml:"gauges,omitempty"` Gauges []GaugeConfig `yaml:"gauges,omitempty"`
AsciiBoxes []AsciiBoxConfig `yaml:"asciiboxes,omitempty"` AsciiBoxes []AsciiBoxConfig `yaml:"asciiboxes,omitempty"`
SparkLines []SparkLineConfig `yaml:"sparklines,omitempty"`
} }
func Load() (Config, Options) { func Load() (Config, Options) {
@ -70,6 +71,12 @@ func (c *Config) findComponent(componentType ComponentType, componentTitle strin
return &c.AsciiBoxes[i].ComponentConfig return &c.AsciiBoxes[i].ComponentConfig
} }
} }
case TypeSparkLine:
for i, component := range c.SparkLines {
if component.Title == componentTitle {
return &c.SparkLines[i].ComponentConfig
}
}
} }
panic(fmt.Sprintf( panic(fmt.Sprintf(

View File

@ -43,6 +43,23 @@ func (c *Config) setDefaultValues() {
c.RunCharts[i] = chart c.RunCharts[i] = chart
} }
for i, line := range c.SparkLines {
setDefaultTriggersValues(line.Triggers)
line.ComponentConfig.Type = TypeSparkLine
line.Item.Label = &line.Title
if line.RefreshRateMs == nil {
r := defaultRefreshRateMs
line.RefreshRateMs = &r
}
if line.Scale == nil {
p := defaultScale
line.Scale = &p
}
c.SparkLines[i] = line
}
for i, chart := range c.BarCharts { for i, chart := range c.BarCharts {
setDefaultTriggersValues(chart.Triggers) setDefaultTriggersValues(chart.Triggers)

View File

@ -3,5 +3,5 @@ package console
const ( const (
SymbolSelection rune = '▲' SymbolSelection rune = '▲'
SymbolVerticalBar rune = '▎' SymbolVerticalBar rune = '▎'
SymbolShade rune = '' SymbolShade rune = ''
) )

View File

@ -9,6 +9,7 @@ import (
"github.com/sqshq/sampler/component/gauge" "github.com/sqshq/sampler/component/gauge"
"github.com/sqshq/sampler/component/layout" "github.com/sqshq/sampler/component/layout"
"github.com/sqshq/sampler/component/runchart" "github.com/sqshq/sampler/component/runchart"
"github.com/sqshq/sampler/component/sparkline"
"github.com/sqshq/sampler/config" "github.com/sqshq/sampler/config"
"github.com/sqshq/sampler/console" "github.com/sqshq/sampler/console"
"github.com/sqshq/sampler/data" "github.com/sqshq/sampler/data"
@ -50,6 +51,12 @@ func main() {
starter.start(cpt, cpt.Consumer, c.ComponentConfig, c.Items, c.Triggers) starter.start(cpt, cpt.Consumer, c.ComponentConfig, c.Items, c.Triggers)
} }
for _, c := range cfg.SparkLines {
println(c.Title)
cpt := sparkline.NewSparkLine(c, palette)
starter.start(cpt, cpt.Consumer, c.ComponentConfig, []config.Item{c.Item}, c.Triggers)
}
for _, c := range cfg.AsciiBoxes { for _, c := range cfg.AsciiBoxes {
cpt := asciibox.NewAsciiBox(c, palette) cpt := asciibox.NewAsciiBox(c, palette)
starter.start(cpt, cpt.Consumer, c.ComponentConfig, []config.Item{c.Item}, c.Triggers) starter.start(cpt, cpt.Consumer, c.ComponentConfig, []config.Item{c.Item}, c.Triggers)