add kpod stats function
Signed-off-by: Ryan Cole <rcyoalne@gmail.com>
This commit is contained in:
parent
dda5511a2b
commit
ceeed6c32e
92 changed files with 34227 additions and 218 deletions
328
vendor/github.com/buger/goterm/plot.go
generated
vendored
Normal file
328
vendor/github.com/buger/goterm/plot.go
generated
vendored
Normal file
|
@ -0,0 +1,328 @@
|
|||
package goterm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
AXIS_LEFT = iota
|
||||
AXIS_RIGHT
|
||||
)
|
||||
|
||||
const (
|
||||
DRAW_INDEPENDENT = 1 << iota
|
||||
DRAW_RELATIVE
|
||||
)
|
||||
|
||||
type DataTable struct {
|
||||
columns []string
|
||||
|
||||
rows [][]float64
|
||||
}
|
||||
|
||||
func (d *DataTable) AddColumn(name string) {
|
||||
d.columns = append(d.columns, name)
|
||||
}
|
||||
|
||||
func (d *DataTable) AddRow(elms ...float64) {
|
||||
d.rows = append(d.rows, elms)
|
||||
}
|
||||
|
||||
type Chart interface {
|
||||
Draw(data DataTable, flags int) string
|
||||
}
|
||||
|
||||
type LineChart struct {
|
||||
Buf []string
|
||||
chartBuf []string
|
||||
|
||||
data *DataTable
|
||||
|
||||
Width int
|
||||
Height int
|
||||
|
||||
chartHeight int
|
||||
chartWidth int
|
||||
|
||||
paddingX int
|
||||
|
||||
paddingY int
|
||||
|
||||
Flags int
|
||||
}
|
||||
|
||||
func genBuf(size int) []string {
|
||||
buf := make([]string, size)
|
||||
|
||||
for i := 0; i < size; i++ {
|
||||
buf[i] = " "
|
||||
}
|
||||
|
||||
return buf
|
||||
}
|
||||
|
||||
// Format float
|
||||
func ff(num interface{}) string {
|
||||
return fmt.Sprintf("%.1f", num)
|
||||
}
|
||||
|
||||
func NewLineChart(width, height int) *LineChart {
|
||||
chart := new(LineChart)
|
||||
chart.Width = width
|
||||
chart.Height = height
|
||||
chart.Buf = genBuf(width * height)
|
||||
|
||||
// axis lines + axies text
|
||||
chart.paddingY = 2
|
||||
|
||||
return chart
|
||||
}
|
||||
|
||||
func (c *LineChart) DrawAxes(maxX, minX, maxY, minY float64, index int) {
|
||||
side := AXIS_LEFT
|
||||
|
||||
if c.Flags&DRAW_INDEPENDENT != 0 {
|
||||
if index%2 == 0 {
|
||||
side = AXIS_RIGHT
|
||||
}
|
||||
|
||||
c.DrawLine(c.paddingX-1, 1, c.Width-c.paddingX, 1, "-")
|
||||
} else {
|
||||
c.DrawLine(c.paddingX-1, 1, c.Width-1, 1, "-")
|
||||
}
|
||||
|
||||
if side == AXIS_LEFT {
|
||||
c.DrawLine(c.paddingX-1, 1, c.paddingX-1, c.Height-1, "│")
|
||||
} else {
|
||||
c.DrawLine(c.Width-c.paddingX, 1, c.Width-c.paddingX, c.Height-1, "│")
|
||||
}
|
||||
|
||||
left := 0
|
||||
if side == AXIS_RIGHT {
|
||||
left = c.Width - c.paddingX + 1
|
||||
}
|
||||
|
||||
if c.Flags&DRAW_RELATIVE != 0 {
|
||||
c.writeText(ff(minY), left, 1)
|
||||
} else {
|
||||
if minY > 0 {
|
||||
c.writeText("0", left, 1)
|
||||
} else {
|
||||
c.writeText(ff(minY), left, 1)
|
||||
}
|
||||
}
|
||||
|
||||
c.writeText(ff(maxY), left, c.Height-1)
|
||||
|
||||
c.writeText(ff(minX), c.paddingX, 0)
|
||||
|
||||
x_col := c.data.columns[0]
|
||||
c.writeText(c.data.columns[0], c.Width/2-len(x_col)/2, 1)
|
||||
|
||||
if c.Flags&DRAW_INDEPENDENT != 0 || len(c.data.columns) < 3 {
|
||||
col := c.data.columns[index]
|
||||
|
||||
for idx, char := range strings.Split(col, "") {
|
||||
start_from := c.Height/2 + len(col)/2 - idx
|
||||
|
||||
if side == AXIS_LEFT {
|
||||
c.writeText(char, c.paddingX-1, start_from)
|
||||
} else {
|
||||
c.writeText(char, c.Width-c.paddingX, start_from)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if c.Flags&DRAW_INDEPENDENT != 0 {
|
||||
c.writeText(ff(maxX), c.Width-c.paddingX-len(ff(maxX)), 0)
|
||||
} else {
|
||||
c.writeText(ff(maxX), c.Width-len(ff(maxX)), 0)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *LineChart) writeText(text string, x, y int) {
|
||||
coord := y*c.Width + x
|
||||
|
||||
for idx, char := range strings.Split(text, "") {
|
||||
c.Buf[coord+idx] = char
|
||||
}
|
||||
}
|
||||
|
||||
func (c *LineChart) Draw(data *DataTable) (out string) {
|
||||
var scaleY, scaleX float64
|
||||
|
||||
c.data = data
|
||||
|
||||
if c.Flags&DRAW_INDEPENDENT != 0 && len(data.columns) > 3 {
|
||||
fmt.Println("Error: Can't use DRAW_INDEPENDENT for more then 2 graphs")
|
||||
return ""
|
||||
}
|
||||
|
||||
charts := len(data.columns) - 1
|
||||
|
||||
prevPoint := [2]int{-1, -1}
|
||||
|
||||
maxX, minX, maxY, minY := getBoundaryValues(data, -1)
|
||||
|
||||
c.paddingX = int(math.Max(float64(len(ff(minY))), float64(len(ff(maxY))))) + 1
|
||||
|
||||
c.chartHeight = c.Height - c.paddingY
|
||||
|
||||
if c.Flags&DRAW_INDEPENDENT != 0 {
|
||||
c.chartWidth = c.Width - 2*c.paddingX
|
||||
} else {
|
||||
c.chartWidth = c.Width - c.paddingX - 1
|
||||
}
|
||||
|
||||
scaleX = float64(c.chartWidth) / (maxX - minX)
|
||||
|
||||
if c.Flags&DRAW_RELATIVE != 0 || minY < 0 {
|
||||
scaleY = float64(c.chartHeight) / (maxY - minY)
|
||||
} else {
|
||||
scaleY = float64(c.chartHeight) / maxY
|
||||
}
|
||||
|
||||
for i := 1; i < charts+1; i++ {
|
||||
if c.Flags&DRAW_INDEPENDENT != 0 {
|
||||
maxX, minX, maxY, minY = getBoundaryValues(data, i)
|
||||
|
||||
scaleX = float64(c.chartWidth-1) / (maxX - minX)
|
||||
scaleY = float64(c.chartHeight) / maxY
|
||||
|
||||
if c.Flags&DRAW_RELATIVE != 0 || minY < 0 {
|
||||
scaleY = float64(c.chartHeight) / (maxY - minY)
|
||||
}
|
||||
}
|
||||
|
||||
symbol := Color("•", i)
|
||||
|
||||
c_data := getChartData(data, i)
|
||||
|
||||
for _, point := range c_data {
|
||||
x := int((point[0]-minX)*scaleX) + c.paddingX
|
||||
y := int((point[1])*scaleY) + c.paddingY
|
||||
|
||||
if c.Flags&DRAW_RELATIVE != 0 || minY < 0 {
|
||||
y = int((point[1]-minY)*scaleY) + c.paddingY
|
||||
}
|
||||
|
||||
if prevPoint[0] == -1 {
|
||||
prevPoint[0] = x
|
||||
prevPoint[1] = y
|
||||
}
|
||||
|
||||
if prevPoint[0] <= x {
|
||||
c.DrawLine(prevPoint[0], prevPoint[1], x, y, symbol)
|
||||
}
|
||||
|
||||
prevPoint[0] = x
|
||||
prevPoint[1] = y
|
||||
}
|
||||
|
||||
c.DrawAxes(maxX, minX, maxY, minY, i)
|
||||
}
|
||||
|
||||
for row := c.Height - 1; row >= 0; row-- {
|
||||
out += strings.Join(c.Buf[row*c.Width:(row+1)*c.Width], "") + "\n"
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (c *LineChart) DrawLine(x0, y0, x1, y1 int, symbol string) {
|
||||
drawLine(x0, y0, x1, y1, func(x, y int) {
|
||||
coord := y*c.Width + x
|
||||
|
||||
if coord > 0 && coord < len(c.Buf) {
|
||||
c.Buf[coord] = symbol
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func getBoundaryValues(data *DataTable, index int) (maxX, minX, maxY, minY float64) {
|
||||
maxX = data.rows[0][0]
|
||||
minX = data.rows[0][0]
|
||||
maxY = data.rows[0][1]
|
||||
minY = data.rows[0][1]
|
||||
|
||||
for _, r := range data.rows {
|
||||
maxX = math.Max(maxX, r[0])
|
||||
minX = math.Min(minX, r[0])
|
||||
|
||||
for idx, c := range r {
|
||||
if idx > 0 {
|
||||
if index == -1 || index == idx {
|
||||
maxY = math.Max(maxY, c)
|
||||
minY = math.Min(minY, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if maxY > 0 {
|
||||
maxY = maxY * 1.1
|
||||
} else {
|
||||
maxY = maxY * 0.9
|
||||
}
|
||||
|
||||
if minY > 0 {
|
||||
minY = minY * 0.9
|
||||
} else {
|
||||
minY = minY * 1.1
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// DataTable can contain data for multiple graphs, we need to extract only 1
|
||||
func getChartData(data *DataTable, index int) (out [][]float64) {
|
||||
for _, r := range data.rows {
|
||||
out = append(out, []float64{r[0], r[index]})
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Algorithm for drawing line between two points
|
||||
//
|
||||
// http://en.wikipedia.org/wiki/Bresenham's_line_algorithm
|
||||
func drawLine(x0, y0, x1, y1 int, plot func(int, int)) {
|
||||
dx := x1 - x0
|
||||
if dx < 0 {
|
||||
dx = -dx
|
||||
}
|
||||
dy := y1 - y0
|
||||
if dy < 0 {
|
||||
dy = -dy
|
||||
}
|
||||
var sx, sy int
|
||||
if x0 < x1 {
|
||||
sx = 1
|
||||
} else {
|
||||
sx = -1
|
||||
}
|
||||
if y0 < y1 {
|
||||
sy = 1
|
||||
} else {
|
||||
sy = -1
|
||||
}
|
||||
err := dx - dy
|
||||
|
||||
for {
|
||||
plot(x0, y0)
|
||||
if x0 == x1 && y0 == y1 {
|
||||
break
|
||||
}
|
||||
e2 := 2 * err
|
||||
if e2 > -dy {
|
||||
err -= dy
|
||||
x0 += sx
|
||||
}
|
||||
if e2 < dx {
|
||||
err += dx
|
||||
y0 += sy
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue