package pill import ( // Used for embedding pill. _ "embed" "fmt" "io" "math" "text/template" ) var ( //go:embed pill.svg pill string tmpl = template.New("svgTemplate") ) const ( modifier = 0.2 max = 190 blue = 55 ) // Pill is used to execute the pill.svg template. // Width is dependent on whether the percentage is 2 digits or 3 digits. type Pill struct { Percentage string Colour string Width string } // NewPill creates creates a Pill, automatically calculating the colour, width, and formatting the percentage. // Note: %02.0f gives us a float with 0 decimals and 0 padding for 2 numbers less than 10. func NewPill(percentDecimal float64) Pill { square := math.Pow(percentDecimal, 2) red := modifier + clamp(2-2*square, 0, 1)*(1-modifier) green := modifier + clamp(2*square, 0, 1)*(1-modifier) percentage := fmt.Sprintf("%.0f", percentDecimal*100) colour := fmt.Sprintf("rgb(%.0f, %.0f, %d)", red*max, green*max, blue) width := "250" if len(percentage) == 1 { percentage = " " + percentage width = "220" } if len(percentage) == 3 { width = "300" } return Pill{ Percentage: percentage, Colour: colour, Width: width, } } // Execute runs the pill template with the data and writes the result to the writer given. func (p Pill) Execute(w io.Writer) error { var err error tmpl, err = tmpl.Parse(pill) if err != nil { return err } err = tmpl.Execute(w, p) return err } func clamp(n, min, max float64) float64 { switch { case n > max: return max case n < min: return min default: return n } }