Add LineChart and BarChart
This commit is contained in:
parent
8351d8f305
commit
92a301a247
96
bar.go
Normal file
96
bar.go
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
package termui
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type BarChart struct {
|
||||||
|
Block
|
||||||
|
BarColor Attribute
|
||||||
|
TextColor Attribute
|
||||||
|
NumColor Attribute
|
||||||
|
Data []int
|
||||||
|
DataLabels []string
|
||||||
|
BarWidth int
|
||||||
|
BarGap int
|
||||||
|
labels [][]rune
|
||||||
|
dataNum [][]rune
|
||||||
|
numBar int
|
||||||
|
scale float64
|
||||||
|
max int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewBarChart() *BarChart {
|
||||||
|
bc := &BarChart{Block: *NewBlock()}
|
||||||
|
bc.BarColor = ColorCyan
|
||||||
|
bc.NumColor = ColorWhite
|
||||||
|
bc.TextColor = ColorWhite
|
||||||
|
bc.BarGap = 1
|
||||||
|
bc.BarWidth = 3
|
||||||
|
return bc
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bc *BarChart) layout() {
|
||||||
|
bc.numBar = bc.innerWidth / (bc.BarGap + bc.BarWidth)
|
||||||
|
bc.labels = make([][]rune, bc.numBar)
|
||||||
|
bc.dataNum = make([][]rune, len(bc.Data))
|
||||||
|
|
||||||
|
for i := 0; i < bc.numBar && i < len(bc.DataLabels) && i < len(bc.Data); i++ {
|
||||||
|
bc.labels[i] = trimStr2Runes(bc.DataLabels[i], bc.BarWidth)
|
||||||
|
n := bc.Data[i]
|
||||||
|
s := fmt.Sprint(n)
|
||||||
|
bc.dataNum[i] = trimStr2Runes(s, bc.BarWidth)
|
||||||
|
}
|
||||||
|
|
||||||
|
bc.max = bc.Data[0] // what if Data is nil?
|
||||||
|
for i := 0; i < len(bc.Data); i++ {
|
||||||
|
if bc.max < bc.Data[i] {
|
||||||
|
bc.max = bc.Data[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bc.scale = float64(bc.max) / float64(bc.innerHeight-1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bc *BarChart) Buffer() []Point {
|
||||||
|
ps := bc.Block.Buffer()
|
||||||
|
bc.layout()
|
||||||
|
|
||||||
|
for i := 0; i < bc.numBar && i < len(bc.Data) && i < len(bc.DataLabels); i++ {
|
||||||
|
h := int(float64(bc.Data[i]) / bc.scale)
|
||||||
|
oftX := i * (bc.BarWidth + bc.BarGap)
|
||||||
|
// plot bar
|
||||||
|
for j := 0; j < bc.BarWidth; j++ {
|
||||||
|
for k := 0; k < h; k++ {
|
||||||
|
p := Point{}
|
||||||
|
p.Code.Ch = ' '
|
||||||
|
p.Code.Bg = toTmAttr(bc.BarColor)
|
||||||
|
p.X = bc.innerX + i*(bc.BarWidth+bc.BarGap) + j
|
||||||
|
p.Y = bc.innerY + bc.innerHeight - 2 - k
|
||||||
|
ps = append(ps, p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// plot text
|
||||||
|
for j := 0; j < len(bc.labels[i]); j++ {
|
||||||
|
p := Point{}
|
||||||
|
p.Code.Ch = bc.labels[i][j]
|
||||||
|
p.Code.Bg = toTmAttr(bc.BgColor)
|
||||||
|
p.Code.Fg = toTmAttr(bc.TextColor)
|
||||||
|
p.Y = bc.innerY + bc.innerHeight - 1
|
||||||
|
p.X = bc.innerX + oftX + j
|
||||||
|
ps = append(ps, p)
|
||||||
|
}
|
||||||
|
// plot num
|
||||||
|
for j := 0; j < len(bc.dataNum[i]); j++ {
|
||||||
|
p := Point{}
|
||||||
|
p.Code.Ch = bc.dataNum[i][j]
|
||||||
|
p.Code.Fg = toTmAttr(bc.NumColor)
|
||||||
|
p.Code.Bg = toTmAttr(bc.BarColor)
|
||||||
|
if h == 0 {
|
||||||
|
p.Code.Bg = toTmAttr(bc.BgColor)
|
||||||
|
}
|
||||||
|
p.X = bc.innerX + oftX + (bc.BarWidth-len(bc.dataNum[i]))/2 + j
|
||||||
|
p.Y = bc.innerY + bc.innerHeight - 2
|
||||||
|
ps = append(ps, p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ps
|
||||||
|
}
|
279
chart.go
Normal file
279
chart.go
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
package termui
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
import tm "github.com/nsf/termbox-go"
|
||||||
|
|
||||||
|
const VDASH = '┊'
|
||||||
|
const HDASH = '┈'
|
||||||
|
const ORIGIN = '└'
|
||||||
|
|
||||||
|
// only 16 possible combinations, why bother
|
||||||
|
var braillePatterns = map[[2]int]rune{
|
||||||
|
[2]int{0, 0}: '⣀',
|
||||||
|
[2]int{0, 1}: '⡠',
|
||||||
|
[2]int{0, 2}: '⡐',
|
||||||
|
[2]int{0, 3}: '⡈',
|
||||||
|
|
||||||
|
[2]int{1, 0}: '⢄',
|
||||||
|
[2]int{1, 1}: '⠤',
|
||||||
|
[2]int{1, 2}: '⠔',
|
||||||
|
[2]int{1, 3}: '⠌',
|
||||||
|
|
||||||
|
[2]int{2, 0}: '⢂',
|
||||||
|
[2]int{2, 1}: '⠢',
|
||||||
|
[2]int{2, 2}: '⠒',
|
||||||
|
[2]int{2, 3}: '⠊',
|
||||||
|
|
||||||
|
[2]int{3, 0}: '⢁',
|
||||||
|
[2]int{3, 1}: '⠡',
|
||||||
|
[2]int{3, 2}: '⠑',
|
||||||
|
[2]int{3, 3}: '⠉',
|
||||||
|
}
|
||||||
|
|
||||||
|
type LineChart struct {
|
||||||
|
Block
|
||||||
|
Data []float64
|
||||||
|
DataLabels []string
|
||||||
|
Mode string // braille | dot
|
||||||
|
DotStyle rune
|
||||||
|
LineColor Attribute
|
||||||
|
scale float64
|
||||||
|
AxesColor Attribute
|
||||||
|
drawingX int
|
||||||
|
drawingY int
|
||||||
|
axisYHeight int
|
||||||
|
axisXWidth int
|
||||||
|
axisYLebelGap int
|
||||||
|
axisXLebelGap int
|
||||||
|
topValue float64
|
||||||
|
bottomValue float64
|
||||||
|
labelX [][]rune
|
||||||
|
labelY [][]rune
|
||||||
|
labelYSpace int
|
||||||
|
maxY float64
|
||||||
|
minY float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLineChart() *LineChart {
|
||||||
|
lc := &LineChart{Block: *NewBlock()}
|
||||||
|
lc.Mode = "braille"
|
||||||
|
lc.DotStyle = '•'
|
||||||
|
lc.axisXLebelGap = 2
|
||||||
|
lc.axisYLebelGap = 1
|
||||||
|
return lc
|
||||||
|
}
|
||||||
|
|
||||||
|
// one cell contains two data points
|
||||||
|
func (lc *LineChart) renderBraille() []Point {
|
||||||
|
ps := []Point{}
|
||||||
|
getBaseMod := func(d float64) (b, m int) {
|
||||||
|
b = int((d - lc.minY) / lc.scale)
|
||||||
|
m = int(((d-lc.minY)-float64(b)*lc.scale)/0.25 + 0.5)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for i := 0; i+1 < len(lc.Data) && i/2 < lc.axisXWidth; i += 2 {
|
||||||
|
b0, m0 := getBaseMod(lc.Data[i])
|
||||||
|
b1, m1 := getBaseMod(lc.Data[i+1])
|
||||||
|
|
||||||
|
if b0 > b1 {
|
||||||
|
m1 = 0
|
||||||
|
}
|
||||||
|
if b0 < b1 {
|
||||||
|
m1 = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
p := Point{}
|
||||||
|
p.Code.Ch = braillePatterns[[2]int{m0, m1}]
|
||||||
|
p.Code.Bg = toTmAttr(lc.BgColor)
|
||||||
|
p.Code.Fg = toTmAttr(lc.LineColor)
|
||||||
|
p.Y = lc.innerY + lc.innerHeight - 3 - b0
|
||||||
|
p.X = lc.innerX + lc.labelYSpace + 1 + i/2
|
||||||
|
ps = append(ps, p)
|
||||||
|
}
|
||||||
|
return ps
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lc *LineChart) renderDot() []Point {
|
||||||
|
ps := []Point{}
|
||||||
|
for i := 0; i < len(lc.Data) && i < lc.axisXWidth; i++ {
|
||||||
|
p := Point{}
|
||||||
|
p.Code.Ch = lc.DotStyle
|
||||||
|
p.Code.Fg = toTmAttr(lc.LineColor)
|
||||||
|
p.Code.Bg = toTmAttr(lc.BgColor)
|
||||||
|
p.X = lc.innerX + lc.labelYSpace + 1 + i
|
||||||
|
p.Y = lc.innerY + lc.innerHeight - 3 - int((lc.Data[i]-lc.minY)/lc.scale+0.5)
|
||||||
|
ps = append(ps, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ps
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lc *LineChart) calcLabelX() {
|
||||||
|
lc.labelX = [][]rune{}
|
||||||
|
|
||||||
|
for i, l := 0, 0; i < len(lc.DataLabels) && l < lc.axisXWidth; i++ {
|
||||||
|
if lc.Mode == "dot" {
|
||||||
|
if l >= len(lc.DataLabels) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
s := str2runes(lc.DataLabels[l])
|
||||||
|
if l+len(s) <= lc.axisXWidth {
|
||||||
|
lc.labelX = append(lc.labelX, s)
|
||||||
|
}
|
||||||
|
l += (len(s) + lc.axisXLebelGap) // -1 needed
|
||||||
|
} else {
|
||||||
|
if 2*l >= len(lc.DataLabels) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
s := str2runes(lc.DataLabels[2*l])
|
||||||
|
if l+len(s) <= lc.axisXWidth {
|
||||||
|
lc.labelX = append(lc.labelX, s)
|
||||||
|
}
|
||||||
|
l += (len(s) + lc.axisXLebelGap) // -1 needed
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func shortenFloatVal(x float64) string {
|
||||||
|
s := fmt.Sprintf("%.2f", x)
|
||||||
|
if len(s)-3 > 3 {
|
||||||
|
s = fmt.Sprintf("%.2e", x)
|
||||||
|
}
|
||||||
|
|
||||||
|
if x < 0 {
|
||||||
|
s = fmt.Sprintf("%.2f", x)
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lc *LineChart) calcLabelY() {
|
||||||
|
span := lc.topValue - lc.bottomValue
|
||||||
|
lc.scale = span / float64(lc.axisYHeight)
|
||||||
|
|
||||||
|
n := (1 + lc.axisYHeight) / (lc.axisYLebelGap + 1)
|
||||||
|
lc.labelY = make([][]rune, n)
|
||||||
|
maxLen := 0
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
s := str2runes(shortenFloatVal(lc.bottomValue + float64(i)*span/float64(n)))
|
||||||
|
if len(s) > maxLen {
|
||||||
|
maxLen = len(s)
|
||||||
|
}
|
||||||
|
lc.labelY[i] = s
|
||||||
|
}
|
||||||
|
|
||||||
|
lc.labelYSpace = maxLen
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lc *LineChart) calcLayout() {
|
||||||
|
if lc.DataLabels == nil || len(lc.DataLabels) == 0 {
|
||||||
|
lc.DataLabels = make([]string, len(lc.Data))
|
||||||
|
for i := range lc.Data {
|
||||||
|
lc.DataLabels[i] = fmt.Sprint(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lc.minY = lc.Data[0]
|
||||||
|
lc.maxY = lc.Data[0]
|
||||||
|
for _, v := range lc.Data {
|
||||||
|
if v > lc.maxY {
|
||||||
|
lc.maxY = v
|
||||||
|
}
|
||||||
|
if v < lc.minY {
|
||||||
|
lc.minY = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lc.topValue = lc.maxY * 1.2
|
||||||
|
lc.bottomValue = lc.minY * 0.8 //- 0.05*(lc.maxY-lc.minY)
|
||||||
|
if lc.minY < 0 {
|
||||||
|
lc.bottomValue = lc.minY * 1.2
|
||||||
|
}
|
||||||
|
|
||||||
|
lc.axisYHeight = lc.innerHeight - 2
|
||||||
|
lc.calcLabelY()
|
||||||
|
|
||||||
|
lc.axisXWidth = lc.innerWidth - 1 - lc.labelYSpace
|
||||||
|
lc.calcLabelX()
|
||||||
|
|
||||||
|
lc.drawingX = lc.innerX + 1 + lc.labelYSpace
|
||||||
|
lc.drawingY = lc.innerY
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lc *LineChart) plotAxes() []Point {
|
||||||
|
origY := lc.innerY + lc.innerHeight - 2
|
||||||
|
origX := lc.innerX + lc.labelYSpace
|
||||||
|
|
||||||
|
ps := []Point{Point{Code: tm.Cell{Ch: ORIGIN, Bg: toTmAttr(lc.BgColor), Fg: toTmAttr(lc.AxesColor)},
|
||||||
|
X: origX,
|
||||||
|
Y: origY}}
|
||||||
|
|
||||||
|
for x := origX + 1; x < origX+lc.axisXWidth; x++ {
|
||||||
|
p := Point{}
|
||||||
|
p.X = x
|
||||||
|
p.Y = origY
|
||||||
|
p.Code.Bg = toTmAttr(lc.BgColor)
|
||||||
|
p.Code.Fg = toTmAttr(lc.AxesColor)
|
||||||
|
p.Code.Ch = HDASH
|
||||||
|
ps = append(ps, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
for dy := 1; dy <= lc.axisYHeight; dy++ {
|
||||||
|
p := Point{}
|
||||||
|
p.X = origX
|
||||||
|
p.Y = origY - dy
|
||||||
|
p.Code.Bg = toTmAttr(lc.BgColor)
|
||||||
|
p.Code.Fg = toTmAttr(lc.AxesColor)
|
||||||
|
p.Code.Ch = VDASH
|
||||||
|
ps = append(ps, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// x label
|
||||||
|
oft := 0
|
||||||
|
for _, rs := range lc.labelX {
|
||||||
|
if oft+len(rs) > lc.axisXWidth {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
for j, r := range rs {
|
||||||
|
p := Point{}
|
||||||
|
p.Code.Ch = r
|
||||||
|
p.Code.Fg = toTmAttr(lc.AxesColor)
|
||||||
|
p.Code.Bg = toTmAttr(lc.BgColor)
|
||||||
|
p.X = origX + oft + j
|
||||||
|
p.Y = lc.innerY + lc.innerHeight - 1
|
||||||
|
ps = append(ps, p)
|
||||||
|
}
|
||||||
|
oft += len(rs) + lc.axisXLebelGap
|
||||||
|
}
|
||||||
|
|
||||||
|
// y labels
|
||||||
|
for i, rs := range lc.labelY {
|
||||||
|
for j, r := range rs {
|
||||||
|
p := Point{}
|
||||||
|
p.Code.Ch = r
|
||||||
|
p.Code.Fg = toTmAttr(lc.AxesColor)
|
||||||
|
p.Code.Bg = toTmAttr(lc.BgColor)
|
||||||
|
p.X = lc.innerX + j
|
||||||
|
p.Y = origY - i*(lc.axisYLebelGap+1)
|
||||||
|
ps = append(ps, p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ps
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lc *LineChart) Buffer() []Point {
|
||||||
|
ps := lc.Block.Buffer()
|
||||||
|
lc.calcLayout()
|
||||||
|
ps = append(ps, lc.plotAxes()...)
|
||||||
|
|
||||||
|
if lc.Mode == "dot" {
|
||||||
|
ps = append(ps, lc.renderDot()...)
|
||||||
|
} else {
|
||||||
|
ps = append(ps, lc.renderBraille()...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ps
|
||||||
|
}
|
@ -2,6 +2,8 @@ package main
|
|||||||
|
|
||||||
import ui "github.com/gizak/termui"
|
import ui "github.com/gizak/termui"
|
||||||
import tm "github.com/nsf/termbox-go"
|
import tm "github.com/nsf/termbox-go"
|
||||||
|
import "math"
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -11,11 +13,11 @@ func main() {
|
|||||||
}
|
}
|
||||||
defer ui.Close()
|
defer ui.Close()
|
||||||
|
|
||||||
p := ui.NewP(":PRESS q TO QUIT DEMO\nThis is an example of termui package rendering.")
|
p := ui.NewP(":PRESS q TO QUIT DEMO")
|
||||||
p.Height = 4
|
p.Height = 3
|
||||||
p.Width = 59
|
p.Width = 50
|
||||||
p.TextFgColor = ui.ColorWhite
|
p.TextFgColor = ui.ColorWhite
|
||||||
p.Border.Label = "Text"
|
p.Border.Label = "Text Box"
|
||||||
p.Border.FgColor = ui.ColorCyan
|
p.Border.FgColor = ui.ColorCyan
|
||||||
|
|
||||||
strs := []string{"[0] gizak/termui", "[1] editbox.go", "[2] iterrupt.go", "[3] keyboard.go", "[4] output.go", "[5] random_out.go", "[6] dashboard.go", "[7] nsf/termbox-go"}
|
strs := []string{"[0] gizak/termui", "[1] editbox.go", "[2] iterrupt.go", "[3] keyboard.go", "[4] output.go", "[5] random_out.go", "[6] dashboard.go", "[7] nsf/termbox-go"}
|
||||||
@ -29,7 +31,7 @@ func main() {
|
|||||||
|
|
||||||
g := ui.NewGauge()
|
g := ui.NewGauge()
|
||||||
g.Percent = 50
|
g.Percent = 50
|
||||||
g.Width = 52
|
g.Width = 50
|
||||||
g.Height = 3
|
g.Height = 3
|
||||||
g.Y = 11
|
g.Y = 11
|
||||||
g.Border.Label = "Gauge"
|
g.Border.Label = "Gauge"
|
||||||
@ -53,16 +55,84 @@ func main() {
|
|||||||
spark1.LineColor = ui.ColorRed
|
spark1.LineColor = ui.ColorRed
|
||||||
|
|
||||||
sp := ui.NewSparklines(spark, spark1)
|
sp := ui.NewSparklines(spark, spark1)
|
||||||
sp.Width = 20
|
sp.Width = 25
|
||||||
sp.Height = 6
|
sp.Height = 7
|
||||||
sp.Border.Label = "Sparkline"
|
sp.Border.Label = "Sparkline"
|
||||||
sp.Y = 14
|
sp.Y = 4
|
||||||
|
sp.X = 25
|
||||||
|
|
||||||
|
lc := ui.NewLineChart()
|
||||||
|
sinps := (func() []float64 {
|
||||||
|
n := 100
|
||||||
|
ps := make([]float64, n)
|
||||||
|
for i := range ps {
|
||||||
|
ps[i] = 1 + math.Sin(float64(i)/4)
|
||||||
|
}
|
||||||
|
return ps
|
||||||
|
})()
|
||||||
|
|
||||||
|
lc.Border.Label = "Line Chart"
|
||||||
|
lc.Data = sinps
|
||||||
|
lc.Width = 50
|
||||||
|
lc.Height = 11
|
||||||
|
lc.X = 0
|
||||||
|
lc.Y = 14
|
||||||
|
lc.AxesColor = ui.ColorWhite
|
||||||
|
lc.LineColor = ui.ColorRed | ui.AttrBold
|
||||||
|
lc.Mode = "dot"
|
||||||
|
|
||||||
|
bc := ui.NewBarChart()
|
||||||
|
bcdata := []int{3, 2, 5, 3, 9, 5, 3, 2, 5, 8, 3, 2, 4, 5, 3, 2, 5, 7, 5, 3, 2, 6, 7, 4, 6, 3, 6, 7, 8, 3, 6, 4, 5, 3, 2, 4, 6, 4, 8, 5, 9, 4, 3, 6, 5, 3, 6}
|
||||||
|
bclabels := []string{"S0", "S1", "S2", "S3", "S4", "S5"}
|
||||||
|
bc.Border.Label = "Bar Chart"
|
||||||
|
bc.Width = 26
|
||||||
|
bc.Height = 10
|
||||||
|
bc.X = 51
|
||||||
|
bc.Y = 0
|
||||||
|
bc.DataLabels = bclabels
|
||||||
|
bc.BarColor = ui.ColorGreen
|
||||||
|
bc.NumColor = ui.ColorBlack
|
||||||
|
|
||||||
|
lc1 := ui.NewLineChart()
|
||||||
|
lc1.Border.Label = "Line Chart"
|
||||||
|
rndwalk := (func() []float64 {
|
||||||
|
n := 100
|
||||||
|
d := make([]float64, n)
|
||||||
|
for i := 1; i < n; i++ {
|
||||||
|
if i < 20 {
|
||||||
|
d[i] = d[i-1] + 0.01
|
||||||
|
}
|
||||||
|
if i > 20 {
|
||||||
|
d[i] = d[i-1] - 0.05
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return d
|
||||||
|
})()
|
||||||
|
lc1.Data = rndwalk
|
||||||
|
lc1.Width = 26
|
||||||
|
lc1.Height = 11
|
||||||
|
lc1.X = 51
|
||||||
|
lc1.Y = 14
|
||||||
|
lc1.AxesColor = ui.ColorWhite
|
||||||
|
lc1.LineColor = ui.ColorYellow | ui.AttrBold
|
||||||
|
|
||||||
|
p1 := ui.NewP("Hey!\nI am a borderless block!")
|
||||||
|
p1.HasBorder = false
|
||||||
|
p1.Width = 26
|
||||||
|
p1.Height = 2
|
||||||
|
p1.TextFgColor = ui.ColorMagenta
|
||||||
|
p1.X = 52
|
||||||
|
p1.Y = 11
|
||||||
|
|
||||||
draw := func(t int) {
|
draw := func(t int) {
|
||||||
g.Percent = t % 101
|
g.Percent = t % 101
|
||||||
list.Items = strs[t%9:]
|
list.Items = strs[t%9:]
|
||||||
sp.Lines[0].Data = spdata[t%10:]
|
sp.Lines[0].Data = spdata[t%10:]
|
||||||
ui.Render(p, list, g, sp)
|
sp.Lines[1].Data = spdata[t/2%10:]
|
||||||
|
lc.Data = sinps[t/2:]
|
||||||
|
lc1.Data = rndwalk[t:]
|
||||||
|
bc.Data = bcdata[t/2%10:]
|
||||||
|
ui.Render(p, list, g, sp, lc, bc, lc1, p1)
|
||||||
}
|
}
|
||||||
|
|
||||||
evt := make(chan tm.Event)
|
evt := make(chan tm.Event)
|
||||||
|
Loading…
Reference in New Issue
Block a user