bitbucket.org/ai69/amoy@v0.2.3/render.go (about) 1 package amoy 2 3 import ( 4 "math" 5 "strings" 6 7 tw "github.com/olekukonko/tablewriter" 8 ) 9 10 // RenderTableString renders the rows as table and returns as string for console. 11 func RenderTableString(header []string, rows [][]string) string { 12 s := strings.Builder{} 13 table := tw.NewWriter(&s) 14 table.SetHeader(header) 15 table.SetHeaderAlignment(tw.ALIGN_LEFT) 16 table.SetHeaderLine(false) 17 table.SetTablePadding("\t") 18 table.SetAlignment(tw.ALIGN_LEFT) 19 table.SetAutoWrapText(false) 20 table.SetAutoFormatHeaders(true) 21 table.SetBorders(tw.Border{Left: true, Top: false, Right: true, Bottom: false}) 22 table.SetCenterSeparator(EmptyStr) 23 table.SetColumnSeparator(EmptyStr) 24 table.SetRowSeparator(EmptyStr) 25 26 for _, r := range rows { 27 table.Append(r) 28 } 29 30 table.Render() 31 return s.String() 32 } 33 34 var ( 35 sparkLineLevels = []rune("▁▂▃▄▅▆▇█") 36 blocks = []rune(`░▏▎▍▌▋▊▉█`) 37 ) 38 39 // RenderSparkline generates a sparkline string like ▅▆▂▂▅▇▂▂▃▆▆▆▅▃ from a slice of float64. 40 func RenderSparkline(nums []float64) string { 41 n := len(nums) 42 if n == 0 { 43 return "" 44 } 45 min := math.Inf(1) 46 max := math.Inf(-1) 47 for _, y := range nums { 48 if y < min { 49 min = y 50 } 51 if y > max { 52 max = y 53 } 54 } 55 if max == min { 56 return strings.Repeat(string(sparkLineLevels[0]), n) 57 } 58 var ( 59 line = make([]rune, n) 60 ratio = (float64(len(sparkLineLevels)) - 1) / (max - min) 61 ) 62 for i := range nums { 63 j := int(math.Floor(ratio * (nums[i] - min))) 64 line[i] = sparkLineLevels[j] 65 } 66 return string(line) 67 } 68 69 // RenderPartialBlock generates a partial block string like █▍░░ from a float64 between 0 and 1. 70 func RenderPartialBlock(num float64, length int) string { 71 // length must be positive 72 if length < 1 { 73 length = 1 74 } 75 // num must be between 0 and 1 76 if num < 0 { 77 num = 0 78 } else if num > 1 { 79 num = 1 80 } 81 82 // total number of blocks, i.e. each rune contains 8 blocks 83 total := length * 8 84 prog := int(math.Round(num * float64(total))) 85 86 var sb strings.Builder 87 // full blocks 88 if n := prog / 8; n > 0 { 89 sb.WriteString(strings.Repeat(string(blocks[8]), n)) 90 } 91 // partial block 92 if n := prog % 8; n > 0 { 93 sb.WriteRune(blocks[n]) 94 } 95 // empty blocks 96 if n := (total - prog) / 8; n > 0 { 97 sb.WriteString(strings.Repeat(string(blocks[0]), n)) 98 } 99 return sb.String() 100 }