-
Notifications
You must be signed in to change notification settings - Fork 12
/
sparkline.go
118 lines (90 loc) · 2.4 KB
/
sparkline.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package tvxwidgets
import (
"math"
"sync"
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
)
// Spartline represents a sparkline widgets.
type Sparkline struct {
*tview.Box
data []float64
dataTitle string
dataTitlecolor tcell.Color
lineColor tcell.Color
mu sync.Mutex
}
// NewSparkline returns a new sparkline widget.
func NewSparkline() *Sparkline {
return &Sparkline{
Box: tview.NewBox(),
}
}
// Draw draws this primitive onto the screen.
func (sl *Sparkline) Draw(screen tcell.Screen) {
sl.Box.DrawForSubclass(screen, sl)
x, y, width, height := sl.Box.GetInnerRect()
barHeight := height
// print label
if sl.dataTitle != "" {
tview.Print(screen, sl.dataTitle, x, y, width, tview.AlignLeft, sl.dataTitlecolor)
barHeight--
}
maxVal := getMaxFloat64FromSlice(sl.data)
if maxVal < 0 {
return
}
// print lines
for i := 0; i < len(sl.data) && i+x < x+width; i++ {
data := sl.data[i]
if math.IsNaN(data) {
continue
}
dHeight := int((data / maxVal) * float64(barHeight))
sparkChar := barsRune[len(barsRune)-1]
style := tcell.StyleDefault.Background(sl.GetBackgroundColor()).Foreground(sl.lineColor)
for j := range dHeight {
tview.PrintJoinedSemigraphics(screen, i+x, y-1+height-j, sparkChar, style)
}
if dHeight == 0 {
sparkChar = barsRune[1]
tview.PrintJoinedSemigraphics(screen, i+x, y-1+height, sparkChar, style)
}
}
}
// SetRect sets rect for this primitive.
func (sl *Sparkline) SetRect(x, y, width, height int) {
sl.Box.SetRect(x, y, width, height)
}
// GetRect return primitive current rect.
func (sl *Sparkline) GetRect() (int, int, int, int) {
return sl.Box.GetRect()
}
// HasFocus returns whether or not this primitive has focus.
func (sl *Sparkline) HasFocus() bool {
return sl.Box.HasFocus()
}
// SetData sets sparkline data.
func (sl *Sparkline) SetData(data []float64) {
sl.mu.Lock()
defer sl.mu.Unlock()
sl.data = data
}
// SetDataTitle sets sparkline data title.
func (sl *Sparkline) SetDataTitle(title string) {
sl.mu.Lock()
defer sl.mu.Unlock()
sl.dataTitle = title
}
// SetDataTitleColor sets sparkline data title color.
func (sl *Sparkline) SetDataTitleColor(color tcell.Color) {
sl.mu.Lock()
defer sl.mu.Unlock()
sl.dataTitlecolor = color
}
// SetLineColor sets sparkline line color.
func (sl *Sparkline) SetLineColor(color tcell.Color) {
sl.mu.Lock()
defer sl.mu.Unlock()
sl.lineColor = color
}