github.com/wtfutil/wtf@v0.43.0/view/bargraph.go (about)

     1  package view
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"strings"
     7  
     8  	"github.com/rivo/tview"
     9  	"github.com/wtfutil/wtf/cfg"
    10  	"github.com/wtfutil/wtf/wtf"
    11  )
    12  
    13  // BarGraph defines the data required to make a bar graph
    14  type BarGraph struct {
    15  	maxStars int
    16  	starChar string
    17  
    18  	*Base
    19  	*KeyboardWidget
    20  
    21  	View *tview.TextView
    22  }
    23  
    24  // Bar defines a single row in the bar graph
    25  type Bar struct {
    26  	Label      string
    27  	Percent    int
    28  	ValueLabel string
    29  	LabelColor string
    30  }
    31  
    32  // NewBarGraph creates and returns an instance of BarGraph
    33  func NewBarGraph(tviewApp *tview.Application, redrawChan chan bool, _ string, commonSettings *cfg.Common) BarGraph {
    34  	widget := BarGraph{
    35  		Base:           NewBase(tviewApp, redrawChan, nil, commonSettings),
    36  		KeyboardWidget: NewKeyboardWidget(commonSettings),
    37  
    38  		maxStars: commonSettings.Config.UInt("graphStars", 20),
    39  		starChar: commonSettings.Config.UString("graphIcon", "|"),
    40  	}
    41  
    42  	widget.View = widget.createView(widget.bordered)
    43  
    44  	return widget
    45  }
    46  
    47  /* -------------------- Exported Functions -------------------- */
    48  
    49  // BuildBars will build a string of * to represent your data of [time][value]
    50  // time should be passed as a int64
    51  func (widget *BarGraph) BuildBars(data []Bar) {
    52  	widget.View.SetText(BuildStars(data, widget.maxStars, widget.starChar))
    53  	widget.Base.RedrawChan <- true
    54  }
    55  
    56  // BuildStars build the string to display
    57  func BuildStars(data []Bar, maxStars int, starChar string) string {
    58  	var buffer bytes.Buffer
    59  
    60  	// the number of characters in the longest label
    61  	var longestLabel int
    62  
    63  	//just getting min and max values
    64  	for _, bar := range data {
    65  		if len(bar.Label) > longestLabel {
    66  			longestLabel = len(bar.Label)
    67  		}
    68  	}
    69  
    70  	// each number = how many stars?
    71  	var starRatio = float64(maxStars) / 100
    72  
    73  	//build the stars
    74  	for _, bar := range data {
    75  		//how many stars for this one?
    76  		var starCount = int(float64(bar.Percent) * starRatio)
    77  
    78  		label := bar.ValueLabel
    79  		if label == "" {
    80  			label = fmt.Sprint(bar.Percent)
    81  		}
    82  
    83  		labelColor := bar.LabelColor
    84  		if labelColor == "" {
    85  			labelColor = "default"
    86  		}
    87  
    88  		//write the line
    89  		_, err := buffer.WriteString(
    90  			fmt.Sprintf(
    91  				"%s%s[[%s]%s[default]%s] %s\n",
    92  				bar.Label,
    93  				strings.Repeat(" ", longestLabel-len(bar.Label)),
    94  				labelColor,
    95  				strings.Repeat(starChar, starCount),
    96  				strings.Repeat(" ", maxStars-starCount),
    97  				label,
    98  			),
    99  		)
   100  		if err != nil {
   101  			return ""
   102  		}
   103  	}
   104  
   105  	return buffer.String()
   106  }
   107  
   108  func (widget *BarGraph) TextView() *tview.TextView {
   109  	return widget.View
   110  }
   111  
   112  /* -------------------- Unexported Functions -------------------- */
   113  
   114  func (widget *BarGraph) createView(bordered bool) *tview.TextView {
   115  	view := tview.NewTextView()
   116  
   117  	view.SetBackgroundColor(wtf.ColorFor(widget.commonSettings.Colors.WidgetTheme.Background))
   118  	view.SetBorder(bordered)
   119  	view.SetBorderColor(wtf.ColorFor(widget.BorderColor()))
   120  	view.SetDynamicColors(true)
   121  	view.SetTitle(widget.ContextualTitle(widget.CommonSettings().Title))
   122  	view.SetTitleColor(wtf.ColorFor(widget.commonSettings.Colors.TextTheme.Title))
   123  	view.SetWrap(false)
   124  
   125  	return view
   126  }