2021-03-30 15:17:14 +07:00
|
|
|
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.
|
2021-03-30 15:45:34 +07:00
|
|
|
// Note: %.0f gives us a float with 0 decimals and 0 padding for 2 numbers less than 10.
|
2021-03-30 15:17:14 +07:00
|
|
|
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 {
|
2021-06-09 10:30:54 +07:00
|
|
|
width = "170"
|
2021-03-30 15:17:14 +07:00
|
|
|
}
|
|
|
|
if len(percentage) == 3 {
|
2021-06-09 10:30:54 +07:00
|
|
|
width = "310"
|
2021-03-30 15:17:14 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
return Pill{
|
2021-06-09 10:30:54 +07:00
|
|
|
Percentage: percentage + "%",
|
2021-03-30 15:17:14 +07:00
|
|
|
Colour: colour,
|
|
|
|
Width: width,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-09 10:30:54 +07:00
|
|
|
func UnknownPill() Pill {
|
|
|
|
return Pill{
|
|
|
|
Percentage: "N/A",
|
|
|
|
Colour: "#353535",
|
|
|
|
Width: "220",
|
2021-03-30 15:17:14 +07:00
|
|
|
}
|
2021-06-09 10:30:54 +07:00
|
|
|
}
|
2021-03-30 15:17:14 +07:00
|
|
|
|
2021-06-09 10:30:54 +07:00
|
|
|
var pillTemplate = template.Must(tmpl.Parse(pill))
|
|
|
|
|
|
|
|
// Execute runs the pill template with the data and writes the result to the writer given.
|
|
|
|
func (p Pill) Execute(w io.Writer) error {
|
|
|
|
return tmpl.Execute(w, p)
|
2021-03-30 15:17:14 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
func clamp(n, min, max float64) float64 {
|
|
|
|
switch {
|
|
|
|
case n > max:
|
|
|
|
return max
|
|
|
|
case n < min:
|
|
|
|
return min
|
|
|
|
default:
|
|
|
|
return n
|
|
|
|
}
|
|
|
|
}
|