概要
Goのコンソール画面にグラフなどを表示させるパッケージtermdash
のWidgetの一つBarChart
の説明です。サンプルにはCPUの使用率をgopsutil
パッケージを使って表示します。
termdash
は以前「Go言語 コンソールモードでコンソール上にグラフ、ボタン、スクロールテキストを表示するtermdashの紹介」として投稿しています。
実行環境
- Windows10
- Go 1.12.5
使用パッケージ
- termdash
- gposutil
BarChartのヘルプ
-
bartchart.New(オプション)
- BarChartのWidgetを生成します
- BarChart Widgetのメソッド
-
ValueCapacity() int
- 画面サイズにフィットする棒グラフの数
- これはオプションの BarGap,BarWidthに依存します
-
Values(値のint型スライス, 最大値, オプション)
- 表示するデータを設定します
- bartchart.Newでのオプションをここでも指定できます
-
ValueCapacity() int
- オプション
-
bartchart.BarColors
- 棒グラフの棒の色(スライス)
-
bartchart.BarGap
- 棒の間隔
-
bartchart.BarWidth
- 棒の幅
-
bartchart.Char
- 棒のところに指定文字を積み重ねて表示
- 出力サイズが一文字分の文字を指定。半角カタカナは可。
-
bartchart.LabelColors
- 棒に下に表示されるそれぞれのラベルの色を指定(スライス)
-
bartchart.Labels
- 棒に下に表示されるそれぞれのラベルを指定(スライス)
-
bartchart.ShowValues
- 棒の値を表示することを指定
-
bartchart.ValueColors
- 棒の値の色を指定(スライス)。 棒の中に表示されるので棒の色とは異なるものにする
-
bartchart.BarColors
サンプル実装
CPUの使用率のサンプル実装です。色や棒の幅などを指定しない例で、幅を指定しないと画面のサイズに合わせて幅を決めます。また、画面をリサイズするとそれに合わせて、棒の幅が変わります。 ALL
は各CPUの平均です。実行したPCは4コア、8スレッドです。
https://github.com/mum4k/termdash/tree/master/widgets/barchart/barchartdemo
を元に改造しました。
cpu.PercentWithContex
がたまにcontext.DeadlineExceeded
を起こすことがあり対処が方法が分からなかったので再実行にしました。
package main
import (
"context"
"fmt"
"time"
"github.com/mum4k/termdash"
"github.com/mum4k/termdash/container"
"github.com/mum4k/termdash/linestyle"
"github.com/mum4k/termdash/terminal/termbox"
"github.com/mum4k/termdash/terminal/terminalapi"
"github.com/mum4k/termdash/widgets/barchart"
"github.com/shirou/gopsutil/cpu"
)
func playBarChart(ctx context.Context, bc *barchart.BarChart, numCPU int, delay time.Duration) {
ticker := time.NewTicker(delay)
values := make([]int, numCPU+1)
defer ticker.Stop()
for {
select {
case <-ticker.C:
cpuPercent, err := cpu.PercentWithContext(ctx, 0, true)
if err != nil {
continue
}
allCPU := 0.0
for ix, c := range cpuPercent {
values[ix+1] = int(c)
allCPU += c
}
values[0] = int(allCPU / float64(numCPU))
if err := bc.Values(values, 100); err != nil {
panic(err)
}
case <-ctx.Done():
return
}
}
}
func main() {
term, err := termbox.New()
if err != nil {
panic(err)
}
defer term.Close()
ctx, cancel := context.WithCancel(context.Background())
var cpuPercent []float64
for {
cpuPercent, err = cpu.PercentWithContext(ctx, 0, true)
if err == context.DeadlineExceeded {
continue
}
if err != nil {
panic(err)
}
break
}
numCPU := len(cpuPercent)
cpuLabel := make([]string, numCPU+1)
cpuLabel[0] = "ALL"
for ix := range cpuPercent {
cpuLabel[ix+1] = fmt.Sprintf("CPU%d", ix)
}
bchart, err := barchart.New(
barchart.ShowValues(),
barchart.Labels(cpuLabel),
)
if err != nil {
panic(err)
}
go playBarChart(ctx, bchart, numCPU, 1*time.Second)
cont, err := container.New(
term,
container.Border(linestyle.Light),
container.BorderTitle("PRESS Q TO QUIT"),
container.PlaceWidget(bchart),
)
if err != nil {
panic(err)
}
quitter := func(k *terminalapi.Keyboard) {
if k.Key == 'q' || k.Key == 'Q' {
cancel()
}
}
if err := termdash.Run(ctx, term, cont,
termdash.KeyboardSubscriber(quitter)); err != nil {
panic(err)
}
}
色指定
色は8色ですから背景の黒を除いて7色になります。または最適な値の色と棒の色の組み合わせは分からないので適当です。ラベルと棒を同じ色にしています。
変更箇所付近だけ記載しました。 //追加
が具体的な変更箇所です。
//追加
var colors = []cell.Color{
cell.ColorRed,
cell.ColorGreen,
cell.ColorYellow,
cell.ColorBlue,
cell.ColorMagenta,
cell.ColorCyan,
cell.ColorWhite,
}
func main() {
//**********************************************
numCPU := len(cpuPercent)
cpuLabel := make([]string, numCPU+1)
barColors := make([]cell.Color, numCPU+1) //追加
valColors := make([]cell.Color, numCPU+1) //追加
labelColors := make([]cell.Color, numCPU+1) //追加
cpuLabel[0] = "ALL"
barColors[0] = colors[0] //追加
valColors[0] = colors[1] //追加
labelColors[0] = barColors[0] //追加
for ix := range cpuPercent {
cpuLabel[ix+1] = fmt.Sprintf("CPU%d", ix)
barColors[ix+1] = colors[(ix+1)%len(colors)] //追加
valColors[ix+1] = colors[(ix+2)%len(colors)] //追加
labelColors[ix+1] = barColors[ix+1] //追加
}
bchart, err := barchart.New(
barchart.ShowValues(),
barchart.Labels(cpuLabel),
barchart.BarColors(barColors), //追加
barchart.ValueColors(valColors), //追加
barchart.LabelColors(labelColors), //追加
)
//**********************************************
}