added barchart component
This commit is contained in:
parent
e0986b7e31
commit
56fbf0cc0d
128
config.yml
128
config.yml
|
@ -1,65 +1,71 @@
|
||||||
runcharts:
|
runcharts:
|
||||||
- title: SEARCH ENGINE RESPONSE TIME (sec)
|
- title: SEARCH ENGINE RESPONSE TIME (sec)
|
||||||
position:
|
position:
|
||||||
w: 0
|
w: 0
|
||||||
h: 0
|
h: 0
|
||||||
size:
|
size:
|
||||||
w: 50
|
w: 50
|
||||||
h: 14
|
h: 14
|
||||||
precision: 3
|
scale: 3
|
||||||
items:
|
items:
|
||||||
- label: GOOGLE
|
- 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: YAHOO
|
- 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: BING
|
- 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
|
||||||
- title: SEARCH ENGINE RESPONSE TIME 2 (sec)
|
- title: SEARCH ENGINE RESPONSE TIME 2 (sec)
|
||||||
refresh-rate-ms: 5000
|
refresh-rate-ms: 5000
|
||||||
position:
|
position:
|
||||||
w: 0
|
w: 0
|
||||||
h: 14
|
h: 14
|
||||||
size:
|
size:
|
||||||
w: 17
|
w: 17
|
||||||
h: 10
|
h: 10
|
||||||
legend:
|
legend:
|
||||||
enabled: true
|
enabled: true
|
||||||
details: false
|
details: false
|
||||||
items:
|
items:
|
||||||
- label: GOOGLE
|
- 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: YAHOO
|
- 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: BING
|
- 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
|
||||||
- title: MONGO COLLECTIONS COUNT
|
- title: MONGO COLLECTIONS COUNT
|
||||||
precision: 0
|
position:
|
||||||
position:
|
w: 17
|
||||||
w: 17
|
h: 14
|
||||||
h: 14
|
size:
|
||||||
size:
|
w: 17
|
||||||
w: 17
|
h: 10
|
||||||
h: 10
|
scale: 0
|
||||||
items:
|
items:
|
||||||
|
- label: ACTIVE
|
||||||
|
script: 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()"
|
||||||
|
barcharts:
|
||||||
|
- title: ANCHOR CONTEXT EVENTS
|
||||||
- label: ACTIVE
|
- label: ACTIVE
|
||||||
script: mongo --quiet --host=localhost blog --eval "db.getCollection('posts').find({status:'ACTIVE'}).size()"
|
script: mongo --quiet --host=localhost blog --eval "db.getCollection('posts').find({status:'ACTIVE'}).itcount()"
|
||||||
- label: INACTIVE
|
- label: INACTIVE
|
||||||
script: mongo --quiet --host=localhost blog --eval "db.getCollection('posts').find({status:'INACTIVE'}).size()"
|
script: mongo --quiet --host=localhost blog --eval "db.getCollection('posts').find({status:'INACTIVE'}).itcount()"
|
||||||
asciiboxes:
|
asciiboxes:
|
||||||
- title: COUNT
|
- title: COUNT
|
||||||
position:
|
position:
|
||||||
w: 34
|
w: 34
|
||||||
h: 14
|
h: 14
|
||||||
size:
|
size:
|
||||||
w: 16
|
w: 16
|
||||||
h: 4
|
h: 4
|
||||||
script: date +%r
|
script: date +%r
|
||||||
- title: MODE
|
- title: MODE
|
||||||
position:
|
position:
|
||||||
w: 34
|
w: 34
|
||||||
h: 18
|
h: 18
|
||||||
size:
|
size:
|
||||||
w: 16
|
w: 16
|
||||||
h: 6
|
h: 6
|
||||||
script: date +%r
|
script: date +%r
|
||||||
font: 3d
|
font: 3d
|
||||||
|
|
|
@ -14,6 +14,7 @@ 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"`
|
||||||
AsciiBoxes []AsciiBoxConfig `yaml:"asciiboxes,omitempty"`
|
AsciiBoxes []AsciiBoxConfig `yaml:"asciiboxes,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,10 +28,16 @@ type ComponentConfig struct {
|
||||||
type RunChartConfig struct {
|
type RunChartConfig struct {
|
||||||
ComponentConfig `yaml:",inline"`
|
ComponentConfig `yaml:",inline"`
|
||||||
Legend *LegendConfig `yaml:"legend,omitempty"`
|
Legend *LegendConfig `yaml:"legend,omitempty"`
|
||||||
Precision *int `yaml:"precision,omitempty"`
|
Scale *int `yaml:"scale,omitempty"`
|
||||||
Items []data.Item `yaml:"items"`
|
Items []data.Item `yaml:"items"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BarChartConfig struct {
|
||||||
|
ComponentConfig `yaml:",inline"`
|
||||||
|
Scale *int `yaml:"scale,omitempty"`
|
||||||
|
Items []data.Item `yaml:"items"`
|
||||||
|
}
|
||||||
|
|
||||||
type AsciiBoxConfig struct {
|
type AsciiBoxConfig struct {
|
||||||
ComponentConfig `yaml:",inline"`
|
ComponentConfig `yaml:",inline"`
|
||||||
data.Item `yaml:",inline"`
|
data.Item `yaml:",inline"`
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultRefreshRateMs = 1000
|
defaultRefreshRateMs = 1000
|
||||||
defaultPrecision = 1
|
defaultScale = 1
|
||||||
defaultTheme = console.ThemeDark
|
defaultTheme = console.ThemeDark
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -29,9 +29,9 @@ func (c *Config) setDefaultValues() {
|
||||||
r := defaultRefreshRateMs
|
r := defaultRefreshRateMs
|
||||||
chart.RefreshRateMs = &r
|
chart.RefreshRateMs = &r
|
||||||
}
|
}
|
||||||
if chart.Precision == nil {
|
if chart.Scale == nil {
|
||||||
p := defaultPrecision
|
p := defaultScale
|
||||||
chart.Precision = &p
|
chart.Scale = &p
|
||||||
}
|
}
|
||||||
if chart.Legend == nil {
|
if chart.Legend == nil {
|
||||||
chart.Legend = &LegendConfig{true, true}
|
chart.Legend = &LegendConfig{true, true}
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -3,7 +3,7 @@ module github.com/sqshq/sampler
|
||||||
require (
|
require (
|
||||||
github.com/hajimehoshi/go-mp3 v0.1.1
|
github.com/hajimehoshi/go-mp3 v0.1.1
|
||||||
github.com/hajimehoshi/oto v0.1.1
|
github.com/hajimehoshi/oto v0.1.1
|
||||||
github.com/mattn/go-runewidth v0.0.4 // indirect
|
github.com/mattn/go-runewidth v0.0.4
|
||||||
github.com/mbndr/figlet4go v0.0.0-20170909125910-47ded4d17030
|
github.com/mbndr/figlet4go v0.0.0-20170909125910-47ded4d17030
|
||||||
github.com/mitchellh/go-wordwrap v1.0.0 // indirect
|
github.com/mitchellh/go-wordwrap v1.0.0 // indirect
|
||||||
github.com/sqshq/termui v0.0.0-20190125032456-731556c09f2c
|
github.com/sqshq/termui v0.0.0-20190125032456-731556c09f2c
|
||||||
|
|
14
main.go
14
main.go
|
@ -7,6 +7,7 @@ import (
|
||||||
"github.com/sqshq/sampler/event"
|
"github.com/sqshq/sampler/event"
|
||||||
"github.com/sqshq/sampler/widgets"
|
"github.com/sqshq/sampler/widgets"
|
||||||
"github.com/sqshq/sampler/widgets/asciibox"
|
"github.com/sqshq/sampler/widgets/asciibox"
|
||||||
|
"github.com/sqshq/sampler/widgets/barchart"
|
||||||
"github.com/sqshq/sampler/widgets/runchart"
|
"github.com/sqshq/sampler/widgets/runchart"
|
||||||
ui "github.com/sqshq/termui"
|
ui "github.com/sqshq/termui"
|
||||||
"time"
|
"time"
|
||||||
|
@ -25,7 +26,7 @@ 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.Scale, *c.RefreshRateMs, legend)
|
||||||
layout.AddComponent(chart, c.Title, c.Position, c.Size, config.TypeRunChart)
|
layout.AddComponent(chart, c.Title, c.Position, c.Size, config.TypeRunChart)
|
||||||
|
|
||||||
for _, item := range c.Items {
|
for _, item := range c.Items {
|
||||||
|
@ -40,6 +41,17 @@ func main() {
|
||||||
data.NewSampler(box, a.Item, *a.RefreshRateMs)
|
data.NewSampler(box, a.Item, *a.RefreshRateMs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, c := range cfg.BarCharts {
|
||||||
|
|
||||||
|
chart := barchart.NewBarChart(c.Title, *c.Scale)
|
||||||
|
layout.AddComponent(chart, c.Title, c.Position, c.Size, config.TypeBarChart)
|
||||||
|
|
||||||
|
for _, item := range c.Items {
|
||||||
|
chart.AddBar(*item.Label, *item.Color)
|
||||||
|
data.NewSampler(chart, item, *c.RefreshRateMs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
handler := event.Handler{
|
handler := event.Handler{
|
||||||
Layout: layout,
|
Layout: layout,
|
||||||
RenderEvents: time.NewTicker(console.RenderRate).C,
|
RenderEvents: time.NewTicker(console.RenderRate).C,
|
||||||
|
|
|
@ -1,83 +1,109 @@
|
||||||
package barchart
|
package barchart
|
||||||
|
|
||||||
//
|
import (
|
||||||
//import (
|
rw "github.com/mattn/go-runewidth"
|
||||||
// "fmt"
|
"github.com/sqshq/sampler/data"
|
||||||
// "image"
|
ui "github.com/sqshq/termui"
|
||||||
//)
|
"image"
|
||||||
//
|
"strconv"
|
||||||
//type BarChart struct {
|
)
|
||||||
// Block
|
|
||||||
// BarColors []Color
|
const (
|
||||||
// LabelStyles []Style
|
barSymbol rune = '⠿'
|
||||||
// NumStyles []Style // only Fg and Modifier are used
|
barIndent int = 1
|
||||||
// NumFmt func(float64) string
|
)
|
||||||
// Data []float64
|
|
||||||
// Labels []string
|
type BarChart struct {
|
||||||
// BarWidth int
|
ui.Block
|
||||||
// BarGap int
|
bars []Bar
|
||||||
// MaxVal float64
|
scale int
|
||||||
//}
|
maxValue float64
|
||||||
//
|
}
|
||||||
//func NewBarChart() *BarChart {
|
|
||||||
// return &BarChart{
|
type Bar struct {
|
||||||
// Block: *NewBlock(),
|
label string
|
||||||
// BarColors: Theme.BarChart.Bars,
|
color ui.Color
|
||||||
// NumStyles: Theme.BarChart.Nums,
|
value float64
|
||||||
// LabelStyles: Theme.BarChart.Labels,
|
}
|
||||||
// NumFmt: func(n float64) string { return fmt.Sprint(n) },
|
|
||||||
// BarGap: 1,
|
func NewBarChart(title string, scale int) *BarChart {
|
||||||
// BarWidth: 3,
|
block := *ui.NewBlock()
|
||||||
// }
|
block.Title = title
|
||||||
//}
|
return &BarChart{
|
||||||
//
|
Block: block,
|
||||||
//func (self *BarChart) Draw(buf *Buffer) {
|
bars: []Bar{},
|
||||||
// self.Block.Draw(buf)
|
scale: scale,
|
||||||
//
|
maxValue: 0,
|
||||||
// maxVal := self.MaxVal
|
}
|
||||||
// if maxVal == 0 {
|
}
|
||||||
// maxVal, _ = GetMaxFloat64FromSlice(self.Data)
|
|
||||||
// }
|
func (b *BarChart) AddBar(label string, color ui.Color) {
|
||||||
//
|
b.bars = append(b.bars, Bar{label: label, color: color, value: 0})
|
||||||
// barXCoordinate := self.Inner.Min.X
|
}
|
||||||
//
|
|
||||||
// for i, data := range self.Data {
|
func (b *BarChart) ConsumeSample(sample data.Sample) {
|
||||||
// // draw bar
|
|
||||||
// height := int((data / maxVal) * float64(self.Inner.Dy()-1))
|
float, err := strconv.ParseFloat(sample.Value, 64)
|
||||||
// for x := barXCoordinate; x < MinInt(barXCoordinate+self.BarWidth, self.Inner.Max.X); x++ {
|
|
||||||
// for y := self.Inner.Max.Y - 2; y > (self.Inner.Max.Y-2)-height; y-- {
|
if err != nil {
|
||||||
// c := NewCell(' ', NewStyle(ColorClear, SelectColor(self.BarColors, i)))
|
// TODO visual notification + check sample.Error
|
||||||
// buf.SetCell(c, image.Pt(x, y))
|
}
|
||||||
// }
|
|
||||||
// }
|
index := -1
|
||||||
//
|
for i, bar := range b.bars {
|
||||||
// // draw label
|
if bar.label == sample.Label {
|
||||||
// if i < len(self.Labels) {
|
index = i
|
||||||
// labelXCoordinate := barXCoordinate +
|
}
|
||||||
// int((float64(self.BarWidth) / 2)) -
|
}
|
||||||
// int((float64(rw.StringWidth(self.Labels[i])) / 2))
|
|
||||||
// buf.SetString(
|
bar := b.bars[index]
|
||||||
// self.Labels[i],
|
bar.value = float
|
||||||
// SelectStyle(self.LabelStyles, i),
|
b.bars[index] = bar
|
||||||
// image.Pt(labelXCoordinate, self.Inner.Max.Y-1),
|
}
|
||||||
// )
|
|
||||||
// }
|
func (b *BarChart) Draw(buf *ui.Buffer) {
|
||||||
//
|
b.Block.Draw(buf)
|
||||||
// // draw number
|
|
||||||
// numberXCoordinate := barXCoordinate + int((float64(self.BarWidth) / 2))
|
maxVal := b.maxValue
|
||||||
// if numberXCoordinate <= self.Inner.Max.X {
|
|
||||||
// buf.SetString(
|
barXCoordinate := b.Inner.Min.X
|
||||||
// self.NumFmt(data),
|
|
||||||
// NewStyle(
|
for i, data := range b.Data {
|
||||||
// SelectStyle(self.NumStyles, i+1).Fg,
|
// draw bar
|
||||||
// SelectColor(self.BarColors, i),
|
height := int((data / maxVal) * float64(b.Inner.Dy()-1))
|
||||||
// SelectStyle(self.NumStyles, i+1).Modifier,
|
for x := barXCoordinate; x < ui.MinInt(barXCoordinate+b.BarWidth, b.Inner.Max.X); x++ {
|
||||||
// ),
|
for y := b.Inner.Max.Y - 2; y > (b.Inner.Max.Y-2)-height; y-- {
|
||||||
// image.Pt(numberXCoordinate, self.Inner.Max.Y-2),
|
c := ui.NewCell(barSymbol, ui.NewStyle(ui.SelectColor(b.BarColors, i)))
|
||||||
// )
|
buf.SetCell(c, image.Pt(x, y))
|
||||||
// }
|
}
|
||||||
//
|
}
|
||||||
// barXCoordinate += (self.BarWidth + self.BarGap)
|
|
||||||
// }
|
// draw label
|
||||||
//}
|
if i < len(b.Labels) {
|
||||||
//
|
labelXCoordinate := barXCoordinate +
|
||||||
|
int((float64(b.BarWidth) / 2)) -
|
||||||
|
int((float64(rw.StringWidth(b.Labels[i])) / 2))
|
||||||
|
buf.SetString(
|
||||||
|
b.Labels[i],
|
||||||
|
ui.SelectStyle(b.LabelStyles, i),
|
||||||
|
image.Pt(labelXCoordinate, b.Inner.Max.Y-1),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw value
|
||||||
|
numberXCoordinate := barXCoordinate + int((float64(b.BarWidth) / 2))
|
||||||
|
if numberXCoordinate <= b.Inner.Max.X {
|
||||||
|
buf.SetString(
|
||||||
|
b.NumFmt(data),
|
||||||
|
ui.NewStyle(
|
||||||
|
ui.SelectStyle(b.NumStyles, i+1).Fg,
|
||||||
|
ui.SelectColor(b.BarColors, i),
|
||||||
|
ui.SelectStyle(b.NumStyles, i+1).Modifier,
|
||||||
|
),
|
||||||
|
image.Pt(numberXCoordinate, b.Inner.Max.Y-2),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
barXCoordinate += (b.BarWidth + b.BarGap)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -77,13 +77,13 @@ func (c *RunChart) renderAxes(buffer *ui.Buffer) {
|
||||||
for i := 0; i < int(labelsCount); i++ {
|
for i := 0; i < int(labelsCount); i++ {
|
||||||
value := c.grid.valueExtrema.max - (valuePerY * float64(i) * (yAxisLabelsIndent + yAxisLabelsHeight))
|
value := c.grid.valueExtrema.max - (valuePerY * float64(i) * (yAxisLabelsIndent + yAxisLabelsHeight))
|
||||||
buffer.SetString(
|
buffer.SetString(
|
||||||
formatValue(value, c.precision),
|
formatValue(value, c.scale),
|
||||||
ui.NewStyle(ui.ColorWhite),
|
ui.NewStyle(ui.ColorWhite),
|
||||||
image.Pt(c.Inner.Min.X, 1+c.Inner.Min.Y+i*(yAxisLabelsIndent+yAxisLabelsHeight)))
|
image.Pt(c.Inner.Min.X, 1+c.Inner.Min.Y+i*(yAxisLabelsIndent+yAxisLabelsHeight)))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
buffer.SetString(
|
buffer.SetString(
|
||||||
formatValue(c.grid.valueExtrema.max, c.precision),
|
formatValue(c.grid.valueExtrema.max, c.scale),
|
||||||
ui.NewStyle(ui.ColorWhite),
|
ui.NewStyle(ui.ColorWhite),
|
||||||
image.Pt(c.Inner.Min.X, c.Inner.Min.Y+c.Inner.Dy()/2))
|
image.Pt(c.Inner.Min.X, c.Inner.Min.Y+c.Inner.Dy()/2))
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ func (c *RunChart) renderLegend(buffer *ui.Buffer, rectangle image.Rectangle) {
|
||||||
|
|
||||||
rowCount := (c.Dy() - 2*yAxisLegendIndent) / (height + yAxisLegendIndent)
|
rowCount := (c.Dy() - 2*yAxisLegendIndent) / (height + yAxisLegendIndent)
|
||||||
columnCount := int(math.Ceil(float64(len(c.lines)) / float64(rowCount)))
|
columnCount := int(math.Ceil(float64(len(c.lines)) / float64(rowCount)))
|
||||||
columnWidth := getColumnWidth(c.mode, c.lines, c.precision)
|
columnWidth := getColumnWidth(c.mode, c.lines, c.scale)
|
||||||
|
|
||||||
for col := 0; col < columnCount; col++ {
|
for col := 0; col < columnCount; col++ {
|
||||||
for row := 0; row < rowCount; row++ {
|
for row := 0; row < rowCount; row++ {
|
||||||
|
@ -61,7 +61,7 @@ func (c *RunChart) renderLegend(buffer *ui.Buffer, rectangle image.Rectangle) {
|
||||||
|
|
||||||
if c.mode == ModePinpoint {
|
if c.mode == ModePinpoint {
|
||||||
buffer.SetString(fmt.Sprintf("time %s", line.selectionPoint.time.Format("15:04:05.000")), detailsStyle, image.Pt(x, y+1))
|
buffer.SetString(fmt.Sprintf("time %s", line.selectionPoint.time.Format("15:04:05.000")), detailsStyle, image.Pt(x, y+1))
|
||||||
buffer.SetString(fmt.Sprintf("value %s", formatValue(line.selectionPoint.value, c.precision)), detailsStyle, image.Pt(x, y+2))
|
buffer.SetString(fmt.Sprintf("value %s", formatValue(line.selectionPoint.value, c.scale)), detailsStyle, image.Pt(x, y+2))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,10 +70,10 @@ func (c *RunChart) renderLegend(buffer *ui.Buffer, rectangle image.Rectangle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
details := [4]string{
|
details := [4]string{
|
||||||
fmt.Sprintf("cur %s", formatValue(getCurrentValue(line), c.precision)),
|
fmt.Sprintf("cur %s", formatValue(getCurrentValue(line), c.scale)),
|
||||||
fmt.Sprintf("dlt %s", formatValueWithSign(getDiffWithPreviousValue(line), c.precision)),
|
fmt.Sprintf("dlt %s", formatValueWithSign(getDiffWithPreviousValue(line), c.scale)),
|
||||||
fmt.Sprintf("max %s", formatValue(line.extrema.max, c.precision)),
|
fmt.Sprintf("max %s", formatValue(line.extrema.max, c.scale)),
|
||||||
fmt.Sprintf("min %s", formatValue(line.extrema.min, c.precision)),
|
fmt.Sprintf("min %s", formatValue(line.extrema.min, c.scale)),
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, detail := range details {
|
for i, detail := range details {
|
||||||
|
@ -83,13 +83,13 @@ func (c *RunChart) renderLegend(buffer *ui.Buffer, rectangle image.Rectangle) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getColumnWidth(mode Mode, lines []TimeLine, precision int) int {
|
func getColumnWidth(mode Mode, lines []TimeLine, scale int) int {
|
||||||
|
|
||||||
if mode == ModePinpoint {
|
if mode == ModePinpoint {
|
||||||
return len(timeFormat)
|
return len(timeFormat)
|
||||||
}
|
}
|
||||||
|
|
||||||
width := len(formatValue(0, precision))
|
width := len(formatValue(0, scale))
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
if len(line.label) > width {
|
if len(line.label) > width {
|
||||||
width = len(line.label)
|
width = len(line.label)
|
||||||
|
|
|
@ -42,7 +42,7 @@ type RunChart struct {
|
||||||
mutex *sync.Mutex
|
mutex *sync.Mutex
|
||||||
mode Mode
|
mode Mode
|
||||||
selection time.Time
|
selection time.Time
|
||||||
precision int
|
scale int
|
||||||
legend Legend
|
legend Legend
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ type ValueExtrema struct {
|
||||||
min float64
|
min float64
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRunChart(title string, precision int, refreshRateMs int, legend Legend) *RunChart {
|
func NewRunChart(title string, scale int, refreshRateMs int, legend Legend) *RunChart {
|
||||||
block := *ui.NewBlock()
|
block := *ui.NewBlock()
|
||||||
block.Title = title
|
block.Title = title
|
||||||
return &RunChart{
|
return &RunChart{
|
||||||
|
@ -79,7 +79,7 @@ func NewRunChart(title string, precision int, refreshRateMs int, legend Legend)
|
||||||
lines: []TimeLine{},
|
lines: []TimeLine{},
|
||||||
timescale: calculateTimescale(refreshRateMs),
|
timescale: calculateTimescale(refreshRateMs),
|
||||||
mutex: &sync.Mutex{},
|
mutex: &sync.Mutex{},
|
||||||
precision: precision,
|
scale: scale,
|
||||||
mode: ModeDefault,
|
mode: ModeDefault,
|
||||||
legend: legend,
|
legend: legend,
|
||||||
}
|
}
|
||||||
|
@ -285,7 +285,7 @@ func (c *RunChart) getMaxValueLength() int {
|
||||||
|
|
||||||
for _, line := range c.lines {
|
for _, line := range c.lines {
|
||||||
for _, point := range line.points {
|
for _, point := range line.points {
|
||||||
l := len(formatValue(point.value, c.precision))
|
l := len(formatValue(point.value, c.scale))
|
||||||
if l > maxValueLength {
|
if l > maxValueLength {
|
||||||
maxValueLength = l
|
maxValueLength = l
|
||||||
}
|
}
|
||||||
|
@ -327,22 +327,22 @@ func getMidRangeTime(r TimeRange) time.Time {
|
||||||
return r.max.Add(-delta / 2)
|
return r.max.Add(-delta / 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatValue(value float64, precision int) string {
|
func formatValue(value float64, scale int) string {
|
||||||
if math.Abs(value) == math.MaxFloat64 {
|
if math.Abs(value) == math.MaxFloat64 {
|
||||||
return "Inf"
|
return "Inf"
|
||||||
} else {
|
} else {
|
||||||
format := "%." + strconv.Itoa(precision) + "f"
|
format := "%." + strconv.Itoa(scale) + "f"
|
||||||
return fmt.Sprintf(format, value)
|
return fmt.Sprintf(format, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatValueWithSign(value float64, precision int) string {
|
func formatValueWithSign(value float64, scale int) string {
|
||||||
if value == 0 {
|
if value == 0 {
|
||||||
return " 0"
|
return " 0"
|
||||||
} else if value > 0 {
|
} else if value > 0 {
|
||||||
return "+" + formatValue(value, precision)
|
return "+" + formatValue(value, scale)
|
||||||
} else {
|
} else {
|
||||||
return formatValue(value, precision)
|
return formatValue(value, scale)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue