mirror of
https://github.com/miguelmota/cointop
synced 2024-11-10 13:10:26 +00:00
77f5c752e9
Former-commit-id: 807a38499b5e912a909d18e142ac5ffd27518f47 [formerly 807a38499b5e912a909d18e142ac5ffd27518f47 [formerly 3b23f739d91859165827c1af6a923cf7be19a1d5 [formerly 6f3f3dd824
]]]
Former-commit-id: 36948040aa5bec0dd2c25ec210e02349f5bddf0a
Former-commit-id: 4b1b9d17fc425bc764a46d0fdcd12747cca608f5 [formerly 56d4451c69972aa25ed17119773e6af9085b00c1]
Former-commit-id: 7967040e3a6348128010d3bc0ad213e5eabbf567
227 lines
3.7 KiB
Go
227 lines
3.7 KiB
Go
package table
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/miguelmota/cointop/pkg/table/align"
|
|
)
|
|
|
|
// Table table
|
|
type Table struct {
|
|
cols Cols
|
|
rows Rows
|
|
sort []SortBy
|
|
width int
|
|
HideColumHeaders bool
|
|
}
|
|
|
|
// New new table
|
|
func New() *Table {
|
|
return &Table{}
|
|
}
|
|
|
|
// SetWidth set table width
|
|
func (t *Table) SetWidth(w int) *Table {
|
|
t.width = w
|
|
return t
|
|
}
|
|
|
|
// AddCol add column
|
|
func (t *Table) AddCol(n string) *Col {
|
|
c := &Col{name: n}
|
|
t.cols = append(t.cols, c)
|
|
return c
|
|
}
|
|
|
|
// AddRow add row
|
|
func (t *Table) AddRow(v ...interface{}) *Row {
|
|
r := &Row{table: t, values: v, strValues: make([]string, len(v))}
|
|
t.rows = append(t.rows, r)
|
|
return r
|
|
}
|
|
|
|
// SortAscFn sort ascending function
|
|
func (t *Table) SortAscFn(n string, fn SortFn) *Table {
|
|
i := t.cols.Index(n)
|
|
s := SortBy{index: i, order: SortAsc, sortFn: fn}
|
|
t.sort = append(t.sort, s)
|
|
return t
|
|
}
|
|
|
|
// SortAsc sort ascending
|
|
func (t *Table) SortAsc(n string) *Table {
|
|
return t.SortAscFn(n, nil)
|
|
}
|
|
|
|
// SortDescFn sort descending function
|
|
func (t *Table) SortDescFn(n string, fn SortFn) *Table {
|
|
i := t.cols.Index(n)
|
|
s := SortBy{index: i, order: SortDesc, sortFn: fn}
|
|
t.sort = append(t.sort, s)
|
|
return t
|
|
}
|
|
|
|
// SortDesc sort descending
|
|
func (t *Table) SortDesc(n string) *Table {
|
|
return t.SortDescFn(n, nil)
|
|
}
|
|
|
|
// Sort sort
|
|
func (t *Table) Sort() *Table {
|
|
if len(t.sort) > 0 {
|
|
sort.Sort(t.rows)
|
|
}
|
|
return t
|
|
}
|
|
|
|
func (t *Table) colWidth() int {
|
|
width := 0
|
|
for _, c := range t.cols {
|
|
if c.hide {
|
|
continue
|
|
}
|
|
|
|
width += c.width
|
|
}
|
|
return width
|
|
}
|
|
|
|
func (t *Table) normalizeColWidthPerc() {
|
|
perc := 0
|
|
for _, c := range t.cols {
|
|
if c.hide {
|
|
continue
|
|
}
|
|
|
|
perc += c.minWidthPerc
|
|
}
|
|
|
|
for _, c := range t.cols {
|
|
if c.hide {
|
|
continue
|
|
}
|
|
|
|
c.perc = float32(c.minWidthPerc) / float32(perc)
|
|
}
|
|
}
|
|
|
|
// Format format table
|
|
func (t *Table) Format() *Table {
|
|
for _, c := range t.cols {
|
|
c.width = len(c.name) + 1
|
|
if c.minWidth > c.width {
|
|
c.width = c.minWidth
|
|
}
|
|
}
|
|
|
|
for _, r := range t.rows {
|
|
for j, v := range r.values {
|
|
c := t.cols[j]
|
|
|
|
if c.hide {
|
|
continue
|
|
}
|
|
|
|
if c.formatFn != nil {
|
|
r.strValues[j] = fmt.Sprintf("%s", c.formatFn(v)) + " "
|
|
} else if c.format != "" {
|
|
r.strValues[j] = fmt.Sprintf(c.format, v) + " "
|
|
} else {
|
|
r.strValues[j] = fmt.Sprintf("%v", v) + " "
|
|
}
|
|
|
|
if len(r.strValues[j]) > t.cols[j].width {
|
|
t.cols[j].width = len(r.strValues[j])
|
|
}
|
|
}
|
|
}
|
|
|
|
t.normalizeColWidthPerc()
|
|
|
|
unused := t.width - t.colWidth()
|
|
if unused <= 0 {
|
|
return t
|
|
}
|
|
|
|
for _, c := range t.cols {
|
|
if c.hide {
|
|
continue
|
|
}
|
|
|
|
if c.perc > 0 {
|
|
c.width += int(float32(unused) * c.perc)
|
|
}
|
|
}
|
|
|
|
var i int
|
|
for i = len(t.cols) - 1; i >= 0; i-- {
|
|
if t.cols[i].hide {
|
|
continue
|
|
}
|
|
|
|
break
|
|
}
|
|
t.cols[i].width += t.width - t.colWidth()
|
|
|
|
return t
|
|
}
|
|
|
|
// Fprint write
|
|
func (t *Table) Fprint(w io.Writer) {
|
|
if !t.HideColumHeaders {
|
|
for _, c := range t.cols {
|
|
if c.hide {
|
|
continue
|
|
}
|
|
|
|
var s string
|
|
switch c.align {
|
|
case AlignLeft:
|
|
s = align.AlignLeft(c.name+" ", c.width)
|
|
case AlignRight:
|
|
s = align.AlignRight(c.name+" ", c.width)
|
|
case AlignCenter:
|
|
s = align.AlignCenter(c.name+" ", c.width)
|
|
}
|
|
|
|
fmt.Fprintf(w, "%s", s)
|
|
}
|
|
fmt.Fprintf(w, "\n")
|
|
|
|
for _, c := range t.cols {
|
|
if c.hide {
|
|
continue
|
|
}
|
|
|
|
fmt.Fprintf(w, strings.Repeat("─", c.width))
|
|
}
|
|
fmt.Fprintf(w, "\n")
|
|
}
|
|
|
|
for _, r := range t.rows {
|
|
for i, v := range r.strValues {
|
|
c := t.cols[i]
|
|
|
|
if c.hide {
|
|
continue
|
|
}
|
|
|
|
var s string
|
|
switch c.align {
|
|
case AlignLeft:
|
|
s = align.AlignLeft(v, c.width)
|
|
case AlignRight:
|
|
s = align.AlignRight(v, c.width)
|
|
case AlignCenter:
|
|
s = align.AlignCenter(v, c.width)
|
|
}
|
|
|
|
fmt.Fprintf(w, "%s", s)
|
|
}
|
|
fmt.Fprintf(w, "\n")
|
|
}
|
|
}
|