package termui import "math" type Sparkline struct { Data []int Height int Title string TitleColor Attribute LineColor Attribute displayHeight int scale float32 max int } type Sparklines struct { Block Lines []Sparkline displayLines int displayWidth int } var sparks = []rune{'▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'} func (s *Sparklines) Add(sl Sparkline) { s.Lines = append(s.Lines, sl) } func NewSparklines(ss ...Sparkline) *Sparklines { s := &Sparklines{Block: *NewBlock(), Lines: ss} return s } func (sl *Sparklines) update() { for i, v := range sl.Lines { if v.Title == "" { sl.Lines[i].displayHeight = v.Height } else { sl.Lines[i].displayHeight = v.Height + 1 } } sl.displayWidth = sl.innerWidth // get how many lines gotta display h := 0 for _, v := range sl.Lines { if h+v.displayHeight <= sl.innerHeight { sl.displayLines++ } else { break } h += v.displayHeight } for i := 0; i < sl.displayLines; i++ { data := sl.Lines[i].Data max := math.MinInt32 for _, v := range data { if max < v { max = v } } sl.Lines[i].max = max sl.Lines[i].scale = float32(8*sl.Lines[i].Height) / float32(max) } } func (sl *Sparklines) Buffer() []Point { ps := sl.Block.Buffer() sl.update() oftY := 0 for i := 0; i < sl.displayLines; i++ { l := sl.Lines[i] data := l.Data if len(data) > sl.innerWidth { data = data[:sl.innerWidth] } if l.Title != "" { rs := trimStr2Runes(l.Title, sl.innerWidth) for oftX, v := range rs { p := Point{} p.Code.Ch = v p.Code.Fg = toTmAttr(l.TitleColor) p.Code.Bg = toTmAttr(sl.BgColor) p.X = oftX p.Y = oftY ps = append(ps, p) } } for j, v := range data { h := int(float32(v) * l.scale) barCnt := h / 8 barMod := h % 8 for jj := 0; jj < barCnt; jj++ { p := Point{} p.X = sl.innerX + j p.Y = sl.innerY + oftY + l.Height - jj p.Code.Ch = sparks[7] p.Code.Fg = toTmAttr(l.LineColor) p.Code.Bg = toTmAttr(sl.BgColor) ps = append(ps, p) } if barMod != 0 { p := Point{} p.X = sl.innerX + j p.Y = sl.innerY + oftY + l.Height - barCnt p.Code.Ch = sparks[barMod-1] p.Code.Fg = toTmAttr(l.LineColor) p.Code.Bg = toTmAttr(sl.BgColor) ps = append(ps, p) } } oftY += l.displayHeight } return ps }