added gauge component type

This commit is contained in:
sqshq 2019-02-25 23:36:23 -05:00
parent a40cc50f3f
commit 7b22a083a4
17 changed files with 313 additions and 116 deletions

View File

@ -1,7 +1,7 @@
package asciibox
import (
fl "github.com/sqshq/figlet4go"
fl "github.com/mbndr/figlet4go"
"github.com/sqshq/sampler/asset"
"github.com/sqshq/sampler/data"
ui "github.com/sqshq/termui"
@ -24,6 +24,8 @@ const (
AsciiFont3D AsciiFont = "3d"
)
const asciiFontExtension = ".flf"
func NewAsciiBox(title string, font AsciiFont, color ui.Color) *AsciiBox {
block := *ui.NewBlock()
@ -32,7 +34,7 @@ func NewAsciiBox(title string, font AsciiFont, color ui.Color) *AsciiBox {
options := fl.NewRenderOptions()
options.FontName = string(font)
fontStr, err := asset.Asset(options.FontName + ".flf")
fontStr, err := asset.Asset(options.FontName + asciiFontExtension)
if err != nil {
panic("Can't load the font: " + err.Error())
}

View File

@ -12,8 +12,7 @@ import (
)
const (
barSymbol rune = '⠿'
barIndent int = 1
barIndent int = 1
)
type BarChart struct {
@ -106,7 +105,7 @@ func (b *BarChart) Draw(buf *ui.Buffer) {
maxYCoordinate := b.Inner.Max.Y - height
for x := barXCoordinate; x < ui.MinInt(barXCoordinate+barWidth, b.Inner.Max.X-barIndent); x++ {
for y := b.Inner.Max.Y - 2; y >= maxYCoordinate; y-- {
c := ui.NewCell(barSymbol, ui.NewStyle(bar.color))
c := ui.NewCell(console.SymbolShade, ui.NewStyle(bar.color))
buf.SetCell(c, image.Pt(x, y))
}
}

View File

@ -5,6 +5,10 @@ import (
ui "github.com/sqshq/termui"
)
const (
minDimension = 3
)
type Component struct {
Type config.ComponentType
Drawable ui.Drawable
@ -27,11 +31,11 @@ func (c *Component) Resize(x, y int) {
}
func (c *Component) normalize() {
if c.Size.X < 0 {
c.Size.X = 0
if c.Size.X < minDimension {
c.Size.X = minDimension
}
if c.Size.Y < 0 {
c.Size.Y = 0
if c.Size.Y < minDimension {
c.Size.Y = minDimension
}
if c.Position.X < 0 {
c.Position.X = 0

103
component/gauge/gauge.go Normal file
View File

@ -0,0 +1,103 @@
package gauge
import (
"fmt"
"github.com/sqshq/sampler/console"
"github.com/sqshq/sampler/data"
ui "github.com/sqshq/termui"
"image"
"math"
"strconv"
)
const (
MinValueLabel = "min"
MaxValueLabel = "max"
CurValueLabel = "cur"
)
type Gauge struct {
ui.Block
minValue float64
maxValue float64
curValue float64
scale int
color ui.Color
}
func NewGauge(title string, scale int, color ui.Color) *Gauge {
block := *ui.NewBlock()
block.Title = title
return &Gauge{
Block: block,
scale: scale,
color: color,
}
}
func (g *Gauge) ConsumeSample(sample data.Sample) {
float, err := strconv.ParseFloat(sample.Value, 64)
if err != nil {
// TODO visual notification + check sample.Error
}
switch sample.Label {
case MinValueLabel:
g.minValue = float
break
case MaxValueLabel:
g.maxValue = float
break
case CurValueLabel:
g.curValue = float
break
}
}
func (g *Gauge) Draw(buf *ui.Buffer) {
g.Block.Draw(buf)
percent := 0.0
if g.curValue != 0 {
percent = (100 * g.curValue) / (g.maxValue - g.minValue)
}
label := fmt.Sprintf("%v%% (%v)", formatValue(percent, g.scale), g.curValue)
// plot bar
barWidth := int((percent / 100) * float64(g.Inner.Dx()))
if barWidth == 0 {
barWidth = 1
} else if barWidth > g.Dx()-2 {
barWidth = g.Dx() - 2
}
buf.Fill(
ui.NewCell(console.SymbolVerticalBar, ui.NewStyle(g.color)),
image.Rect(g.Inner.Min.X+1, g.Inner.Min.Y, g.Inner.Min.X+barWidth, g.Inner.Max.Y),
)
// plot label
labelXCoordinate := g.Inner.Min.X + (g.Inner.Dx() / 2) - int(float64(len(label))/2)
labelYCoordinate := g.Inner.Min.Y + ((g.Inner.Dy() - 1) / 2)
if labelYCoordinate < g.Inner.Max.Y {
for i, char := range label {
style := ui.NewStyle(console.ColorWhite)
if labelXCoordinate+i+1 <= g.Inner.Min.X+barWidth {
style = ui.NewStyle(console.ColorWhite, ui.ColorClear)
}
buf.SetCell(ui.NewCell(char, style), image.Pt(labelXCoordinate+i, labelYCoordinate))
}
}
}
// TODO extract to utils
func formatValue(value float64, scale int) string {
if math.Abs(value) == math.MaxFloat64 {
return "Inf"
} else {
format := "%." + strconv.Itoa(scale) + "f"
return fmt.Sprintf(format, value)
}
}

View File

@ -29,8 +29,8 @@ const (
)
const (
columnsCount = 60
rowsCount = 40
columnsCount = 80
rowsCount = 60
statusbarHeight = 1
)

View File

@ -33,6 +33,10 @@ const (
MenuOptionResume MenuOption = "RESUME"
)
const (
minimalMenuHeight = 8
)
func NewMenu() *Menu {
block := *ui.NewBlock()
block.Border = true
@ -99,7 +103,12 @@ func (m *Menu) Draw(buffer *ui.Buffer) {
m.updateDimensions()
buffer.Fill(ui.NewCell(' ', ui.NewStyle(ui.ColorBlack)), m.GetRect())
m.drawInnerBorder(buffer)
if m.Dy() > minimalMenuHeight {
m.drawInnerBorder(buffer)
}
m.Block.Draw(buffer)
switch m.mode {
case MenuModeHighlight:
@ -109,15 +118,25 @@ func (m *Menu) Draw(buffer *ui.Buffer) {
case MenuModeOptionSelect:
m.renderOptions(buffer)
}
m.Block.Draw(buffer)
}
func (m *Menu) renderHighlight(buffer *ui.Buffer) {
arrowsText := "Use arrows for selection"
optionsText := "<ENTER> to view options"
resumeText := "<ESC> to resume"
if m.Dy() <= minimalMenuHeight {
buffer.SetString(
optionsText,
ui.NewStyle(console.ColorDarkGrey),
getMiddlePoint(m.Block, optionsText, -1),
)
return
}
m.printAllDirectionsArrowSign(buffer, -2)
arrowsText := "Use arrows for selection"
arrowsTextPoint := getMiddlePoint(m.Block, arrowsText, 2)
if arrowsTextPoint.Y+1 < m.Inner.Max.Y {
buffer.SetString(
@ -127,7 +146,6 @@ func (m *Menu) renderHighlight(buffer *ui.Buffer) {
)
}
optionsText := "<ENTER> to view options"
optionsTextPoint := getMiddlePoint(m.Block, optionsText, 3)
if optionsTextPoint.Y+1 < m.Inner.Max.Y {
buffer.SetString(
@ -137,7 +155,6 @@ func (m *Menu) renderHighlight(buffer *ui.Buffer) {
)
}
resumeText := "<ESC> to resume"
resumeTextPoint := getMiddlePoint(m.Block, resumeText, 4)
if resumeTextPoint.Y+1 < m.Inner.Max.Y {
buffer.SetString(
@ -150,17 +167,15 @@ func (m *Menu) renderHighlight(buffer *ui.Buffer) {
func (m *Menu) renderMoveAndResize(buffer *ui.Buffer) {
m.printAllDirectionsArrowSign(buffer, -2)
saveText := "<ENTER> to save changes"
saveTextPoint := getMiddlePoint(m.Block, saveText, 4)
if saveTextPoint.In(m.Rectangle) {
buffer.SetString(
saveText,
ui.NewStyle(console.ColorDarkGrey),
saveTextPoint,
)
if m.Dy() <= minimalMenuHeight {
buffer.SetString(saveText, ui.NewStyle(console.ColorDarkGrey), getMiddlePoint(m.Block, saveText, -1))
return
}
m.printAllDirectionsArrowSign(buffer, -1)
buffer.SetString(saveText, ui.NewStyle(console.ColorDarkGrey), getMiddlePoint(m.Block, saveText, 3))
}
func (m *Menu) printAllDirectionsArrowSign(buffer *ui.Buffer, y int) {
@ -184,7 +199,7 @@ func (m *Menu) renderOptions(buffer *ui.Buffer) {
// TODO extract styles to console.Palette
highlightedStyle := ui.NewStyle(console.ColorOlive, console.ColorBlack, ui.ModifierReverse)
regularStyle := ui.NewStyle(console.ColorWhite)
regularStyle := ui.NewStyle(console.ColorWhite, console.ColorBlack)
offset := 1
for _, option := range m.options {
@ -197,9 +212,10 @@ func (m *Menu) renderOptions(buffer *ui.Buffer) {
if option != MenuOptionPinpoint || m.component.Type == config.TypeRunChart {
offset += 2
point := getMiddlePoint(m.Block, string(option), offset-5)
if point.In(m.GetRect()) {
buffer.SetString(string(option), style, point)
}
buffer.SetString(string(option), style, point)
//if point.In(m.GetRect()) {
// buffer.SetString(string(option), style, point)
//}
}
}
}

View File

@ -9,11 +9,11 @@ runcharts:
scale: 3
items:
- label: GOOGLE
script: curl -o /dev/null -s -w '%{time_total}' https://www.google.com
value: curl -o /dev/null -s -w '%{time_total}' https://www.google.com
- label: YAHOO
script: curl -o /dev/null -s -w '%{time_total}' https://search.yahoo.com
value: curl -o /dev/null -s -w '%{time_total}' https://search.yahoo.com
- label: BING
script: curl -o /dev/null -s -w '%{time_total}' https://www.bing.com
value: curl -o /dev/null -s -w '%{time_total}' https://www.bing.com
- title: SEARCH ENGINE RESPONSE TIME 2 (sec)
refresh-rate-ms: 5000
position:
@ -27,11 +27,11 @@ runcharts:
details: false
items:
- label: GOOGLE
script: curl -o /dev/null -s -w '%{time_total}' https://www.google.com
value: curl -o /dev/null -s -w '%{time_total}' https://www.google.com
- label: YAHOO
script: curl -o /dev/null -s -w '%{time_total}' https://search.yahoo.com
value: curl -o /dev/null -s -w '%{time_total}' https://search.yahoo.com
- label: BING
script: curl -o /dev/null -s -w '%{time_total}' https://www.bing.com
value: curl -o /dev/null -s -w '%{time_total}' https://www.bing.com
- title: MONGO COLLECTIONS COUNT
position:
w: 21
@ -42,9 +42,9 @@ runcharts:
scale: 0
items:
- label: ACTIVE
script: mongo --quiet --host=localhost blog --eval "db.getCollection('posts').find({status:'ACTIVE'}).itcount()"
value: mongo --quiet --host=localhost blog --eval "db.getCollection('posts').find({status:'ACTIVE'}).itcount()"
- label: INACTIVE
script: mongo --quiet --host=localhost blog --eval "db.getCollection('posts').find({status:'INACTIVE'}).itcount()"
value: mongo --quiet --host=localhost blog --eval "db.getCollection('posts').find({status:'INACTIVE'}).itcount()"
barcharts:
- title: EVENTS BY STATUS
refresh-rate-ms: 1000
@ -57,15 +57,28 @@ barcharts:
scale: 0
items:
- label: NEW
script: mongo --quiet --host=localhost blog --eval "db.getCollection('posts').find({status:'ACTIVE'}).itcount()"
value: mongo --quiet --host=localhost blog --eval "db.getCollection('posts').find({status:'ACTIVE'}).itcount()"
- label: TRIGGERED
script: mongo --quiet --host=localhost blog --eval "db.getCollection('posts').find({status:'INACTIVE'}).itcount()"
value: mongo --quiet --host=localhost blog --eval "db.getCollection('posts').find({status:'INACTIVE'}).itcount()"
- label: IN_PROCESS
script: echo 0
- label: FINISHED
script: mongo --quiet --host=localhost blog --eval "db.getCollection('posts').find({status:'ACTIVE'}).itcount()"
value: echo 0
- label: FAILED
script: mongo --quiet --host=localhost blog --eval "db.getCollection('posts').find({status:'INACTIVE'}).itcount()"
value: mongo --quiet --host=localhost blog --eval "db.getCollection('posts').find({status:'ACTIVE'}).itcount()"
- label: FINISHED
value: mongo --quiet --host=localhost blog --eval "db.getCollection('posts').find({status:'INACTIVE'}).itcount()"
gauges:
- title: YEAR PROGRESS
position:
w: 21
h: 33
size:
w: 20
h: 3
values:
cur: echo 245
max: echo 365
min: echo 0
items: []
asciiboxes:
- title: LOCAL TIME
position:
@ -74,7 +87,7 @@ asciiboxes:
size:
w: 20
h: 6
script: date +%r
value: date +%r
- title: UTC TIME
position:
w: 40
@ -82,5 +95,5 @@ asciiboxes:
size:
w: 20
h: 7
script: env TZ=UTC date +%r
value: env TZ=UTC date +%r
font: 3d

73
config/component.go Normal file
View File

@ -0,0 +1,73 @@
package config
import (
"github.com/sqshq/sampler/component/asciibox"
"github.com/sqshq/sampler/data"
ui "github.com/sqshq/termui"
)
type ComponentConfig struct {
Title string `yaml:"title"`
RefreshRateMs *int `yaml:"refresh-rate-ms,omitempty"`
Position Position `yaml:"position"`
Size Size `yaml:"size"`
}
type GaugeConfig struct {
ComponentConfig `yaml:",inline"`
Scale *int `yaml:"scale,omitempty"`
Color *ui.Color `yaml:"color,omitempty"`
Values map[string]string `yaml:"values"`
Items []data.Item
}
type BarChartConfig struct {
ComponentConfig `yaml:",inline"`
Scale *int `yaml:"scale,omitempty"`
Items []data.Item `yaml:"items"`
}
type AsciiBoxConfig struct {
ComponentConfig `yaml:",inline"`
data.Item `yaml:",inline"`
Font *asciibox.AsciiFont `yaml:"font,omitempty"`
}
type RunChartConfig struct {
ComponentConfig `yaml:",inline"`
Legend *LegendConfig `yaml:"legend,omitempty"`
Scale *int `yaml:"scale,omitempty"`
Items []data.Item `yaml:"items"`
}
type LegendConfig struct {
Enabled bool `yaml:"enabled"`
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
TypeTextBox ComponentType = 2
TypeAsciiBox ComponentType = 3
TypeGauge ComponentType = 4
)
type ComponentSettings struct {
Type ComponentType
Title string
Size Size
Position Position
}

View File

@ -2,9 +2,7 @@ package config
import (
"fmt"
"github.com/sqshq/sampler/component/asciibox"
"github.com/sqshq/sampler/console"
"github.com/sqshq/sampler/data"
"gopkg.in/yaml.v2"
"io/ioutil"
"log"
@ -15,6 +13,7 @@ type Config struct {
Theme *console.Theme `yaml:"theme,omitempty"`
RunCharts []RunChartConfig `yaml:"runcharts,omitempty"`
BarCharts []BarChartConfig `yaml:"barcharts,omitempty"`
Gauges []GaugeConfig `yaml:"gauges,omitempty"`
AsciiBoxes []AsciiBoxConfig `yaml:"asciiboxes,omitempty"`
}
@ -23,63 +22,6 @@ type Flags struct {
Variables map[string]string
}
type ComponentConfig struct {
Title string `yaml:"title"`
RefreshRateMs *int `yaml:"refresh-rate-ms,omitempty"`
Position Position `yaml:"position"`
Size Size `yaml:"size"`
}
type RunChartConfig struct {
ComponentConfig `yaml:",inline"`
Legend *LegendConfig `yaml:"legend,omitempty"`
Scale *int `yaml:"scale,omitempty"`
Items []data.Item `yaml:"items"`
}
type BarChartConfig struct {
ComponentConfig `yaml:",inline"`
Scale *int `yaml:"scale,omitempty"`
Items []data.Item `yaml:"items"`
}
type AsciiBoxConfig struct {
ComponentConfig `yaml:",inline"`
data.Item `yaml:",inline"`
Font *asciibox.AsciiFont `yaml:"font,omitempty"`
}
type LegendConfig struct {
Enabled bool `yaml:"enabled"`
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
TypeTextBox ComponentType = 2
TypeAsciiBox ComponentType = 3
)
type ComponentSettings struct {
Type ComponentType
Title string
Size Size
Position Position
}
func Load() (Config, Flags) {
if len(os.Args) < 2 {
@ -121,6 +63,12 @@ func (c *Config) findComponent(componentType ComponentType, componentTitle strin
return &c.BarCharts[i].ComponentConfig
}
}
case TypeGauge:
for i, component := range c.Gauges {
if component.Title == componentTitle {
return &c.Gauges[i].ComponentConfig
}
}
case TypeAsciiBox:
for i, component := range c.AsciiBoxes {
if component.Title == componentTitle {

View File

@ -3,6 +3,7 @@ package config
import (
"github.com/sqshq/sampler/component/asciibox"
"github.com/sqshq/sampler/console"
"github.com/sqshq/sampler/data"
)
const (
@ -52,6 +53,24 @@ func (c *Config) setDefaultValues() {
c.BarCharts[i] = chart
}
for i, g := range c.Gauges {
if g.RefreshRateMs == nil {
r := defaultRefreshRateMs
g.RefreshRateMs = &r
}
if g.Scale == nil {
p := defaultScale
g.Scale = &p
}
var items []data.Item
for label, script := range g.Values {
l := label
items = append(items, data.Item{Label: &l, Script: script})
}
g.Items = items
c.Gauges[i] = g
}
for i, box := range c.AsciiBoxes {
if box.RefreshRateMs == nil {
r := defaultRefreshRateMs
@ -99,4 +118,11 @@ func (c *Config) setDefaultColors() {
}
}
}
for i, g := range c.Gauges {
if g.Color == nil {
g.Color = &palette.Colors[i%colorsCount]
c.Gauges[i] = g
}
}
}

View File

@ -28,7 +28,7 @@ const (
)
const (
MenuColorBackground ui.Color = 236
MenuColorBackground ui.Color = 234
MenuColorText ui.Color = 255
)

View File

@ -1,5 +1,7 @@
package console
const (
SymbolSelection rune = '▲'
SymbolSelection rune = '▲'
SymbolVerticalBar rune = '⢸'
SymbolShade rune = '⣿'
)

View File

@ -8,7 +8,7 @@ import (
type Item struct {
Label *string `yaml:"label,omitempty"`
Script string `yaml:"script"`
Script string `yaml:"value"`
Color *ui.Color `yaml:"color,omitempty"`
}

2
go.mod
View File

@ -4,8 +4,8 @@ require (
github.com/hajimehoshi/go-mp3 v0.1.1
github.com/hajimehoshi/oto v0.1.1
github.com/mattn/go-runewidth v0.0.4
github.com/mbndr/figlet4go v0.0.0-20190224160619-d6cef5b186ea
github.com/mitchellh/go-wordwrap v1.0.0 // indirect
github.com/sqshq/figlet4go v0.0.0-20190224060604-5ce91d55ba00
github.com/sqshq/termui v0.0.0-20190125032456-731556c09f2c
gopkg.in/yaml.v2 v2.2.2
)

4
go.sum
View File

@ -11,13 +11,13 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mbndr/figlet4go v0.0.0-20190224160619-d6cef5b186ea h1:mQncVDBpKkAecPcH2IMGpKUQYhwowlafQbfkz2QFqkc=
github.com/mbndr/figlet4go v0.0.0-20190224160619-d6cef5b186ea/go.mod h1:QzTGLGoOqLHUBK8/EZ0v4Fa4CdyXmdyRwCHcl0YbeO4=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d h1:x3S6kxmy49zXVVyhcnrFqxvNVCBPb2KZ9hV2RBdS840=
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
github.com/sqshq/figlet4go v0.0.0-20190224060604-5ce91d55ba00 h1:HDXBCtVmmsZ0uMTd7CduTASlVECbRZhyAc0m3C+Dbjk=
github.com/sqshq/figlet4go v0.0.0-20190224060604-5ce91d55ba00/go.mod h1:8MTXZj469VoimW9vWH9LcL9Q3k1SRa+dgZdni8ZZw0o=
github.com/sqshq/termui v0.0.0-20190125032456-731556c09f2c h1:BBEmIcD4UhAHDVWi3PVuA5TxVTZxcjmYzmdvhWkPfvE=
github.com/sqshq/termui v0.0.0-20190125032456-731556c09f2c/go.mod h1:puWaguPLLYPPKabYPVhZ8sDNe0nKSMiKWRfLVaaX8Zs=
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045/go.mod h1:cYlCBUl1MsqxdiKgmc4uh7TxZfWSFLOGSRR090WDxt8=

21
main.go
View File

@ -4,6 +4,7 @@ import (
"github.com/sqshq/sampler/component"
"github.com/sqshq/sampler/component/asciibox"
"github.com/sqshq/sampler/component/barchart"
"github.com/sqshq/sampler/component/gauge"
"github.com/sqshq/sampler/component/runchart"
"github.com/sqshq/sampler/config"
"github.com/sqshq/sampler/console"
@ -40,14 +41,24 @@ func main() {
data.NewSampler(box, a.Item, *a.RefreshRateMs)
}
for _, c := range cfg.BarCharts {
for _, b := range cfg.BarCharts {
chart := barchart.NewBarChart(c.Title, *c.Scale)
layout.AddComponent(config.TypeBarChart, chart, c.Title, c.Position, c.Size, *c.RefreshRateMs)
chart := barchart.NewBarChart(b.Title, *b.Scale)
layout.AddComponent(config.TypeBarChart, chart, b.Title, b.Position, b.Size, *b.RefreshRateMs)
for _, item := range c.Items {
for _, item := range b.Items {
chart.AddBar(*item.Label, *item.Color)
data.NewSampler(chart, item, *c.RefreshRateMs)
data.NewSampler(chart, item, *b.RefreshRateMs)
}
}
for _, gc := range cfg.Gauges {
g := gauge.NewGauge(gc.Title, *gc.Scale, *gc.Color)
layout.AddComponent(config.TypeGauge, g, gc.Title, gc.Position, gc.Size, *gc.RefreshRateMs)
for _, item := range gc.Items {
data.NewSampler(g, item, *gc.RefreshRateMs)
}
}

Binary file not shown.