mirror of
https://github.com/mum4k/termdash.git
synced 2025-04-28 13:48:51 +08:00
Add round and suffix based value formatter for the Y-axis label representation
Signed-off-by: Xabier Larrakoetxea <slok69@gmail.com>
This commit is contained in:
parent
38f40428a1
commit
a5c7363f43
@ -20,6 +20,7 @@ package linechart
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -42,33 +43,34 @@ func durationSingleUnitPrettyFormat(d time.Duration, decimals int) string {
|
||||
return fmt.Sprintf(dFmt, d.Nanoseconds())
|
||||
// Microseconds.
|
||||
case d.Seconds()*1000*1000 < 1000:
|
||||
dFmt := prefix + decimalFormat(decimals, "µs")
|
||||
dFmt := prefix + suffixDecimalFormat(decimals, "µs")
|
||||
return fmt.Sprintf(dFmt, d.Seconds()*1000*1000)
|
||||
// Milliseconds.
|
||||
case d.Seconds()*1000 < 1000:
|
||||
dFmt := prefix + decimalFormat(decimals, "ms")
|
||||
dFmt := prefix + suffixDecimalFormat(decimals, "ms")
|
||||
return fmt.Sprintf(dFmt, d.Seconds()*1000)
|
||||
// Seconds.
|
||||
case d.Seconds() < 60:
|
||||
dFmt := prefix + decimalFormat(decimals, "s")
|
||||
dFmt := prefix + suffixDecimalFormat(decimals, "s")
|
||||
return fmt.Sprintf(dFmt, d.Seconds())
|
||||
// Minutes.
|
||||
case d.Minutes() < 60:
|
||||
dFmt := prefix + decimalFormat(decimals, "m")
|
||||
dFmt := prefix + suffixDecimalFormat(decimals, "m")
|
||||
return fmt.Sprintf(dFmt, d.Minutes())
|
||||
// Hours.
|
||||
case d.Hours() < 24:
|
||||
dFmt := prefix + decimalFormat(decimals, "h")
|
||||
dFmt := prefix + suffixDecimalFormat(decimals, "h")
|
||||
return fmt.Sprintf(dFmt, d.Hours())
|
||||
// Days.
|
||||
default:
|
||||
dFmt := prefix + decimalFormat(decimals, "d")
|
||||
dFmt := prefix + suffixDecimalFormat(decimals, "d")
|
||||
return fmt.Sprintf(dFmt, d.Hours()/24)
|
||||
}
|
||||
}
|
||||
|
||||
func decimalFormat(decimals int, unit string) string {
|
||||
return fmt.Sprintf("%%.%df%s", decimals, unit)
|
||||
func suffixDecimalFormat(decimals int, suffix string) string {
|
||||
suffix = strings.ReplaceAll(suffix, "%", "%%") // safe `%` character for fmt.
|
||||
return fmt.Sprintf("%%.%df%s", decimals, suffix)
|
||||
}
|
||||
|
||||
// ValueFormatterSingleUnitDuration is a factory to create a custom duration
|
||||
@ -103,3 +105,42 @@ func ValueFormatterSingleUnitSeconds(seconds float64) string {
|
||||
f := ValueFormatterSingleUnitDuration(time.Second, 0)
|
||||
return f(seconds)
|
||||
}
|
||||
|
||||
// ValueFormatterRound is a formatter that will receive a float64
|
||||
// value and will round to the nearest value without decimals.
|
||||
func ValueFormatterRound(value float64) string {
|
||||
f := ValueFormatterRoundWithSuffix("")
|
||||
return f(value)
|
||||
}
|
||||
|
||||
// ValueFormatterRoundWithSuffix is a factory that returns a formatter
|
||||
// that will receive a float64 value and will round to the nearest value
|
||||
// without decimals adding a suffix to the final value string representation.
|
||||
func ValueFormatterRoundWithSuffix(suffix string) ValueFormatter {
|
||||
return valueFormatterSuffixWithTransformer(0, suffix, math.Round)
|
||||
}
|
||||
|
||||
// ValueFormatterSuffix is a factory that returns a formatter
|
||||
// that will receive a float64 value and return a string representation with
|
||||
// the desired number of decimal truncated and a suffix.
|
||||
func ValueFormatterSuffix(decimals int, suffix string) ValueFormatter {
|
||||
return valueFormatterSuffixWithTransformer(decimals, suffix, nil)
|
||||
}
|
||||
|
||||
// valueFormatterSuffixWithTransformer is a factory that returns a formatter
|
||||
// that will apply a tranform function to the received value before
|
||||
// returning the decimal with suffix representation.
|
||||
func valueFormatterSuffixWithTransformer(decimals int, suffix string, transformFunc func(float64) float64) ValueFormatter {
|
||||
dFmt := suffixDecimalFormat(decimals, suffix)
|
||||
return func(value float64) string {
|
||||
if math.IsNaN(value) {
|
||||
return ""
|
||||
}
|
||||
|
||||
if transformFunc != nil {
|
||||
value = transformFunc(value)
|
||||
}
|
||||
|
||||
return fmt.Sprintf(dFmt, value)
|
||||
}
|
||||
}
|
||||
|
@ -143,6 +143,90 @@ func TestFormatters(t *testing.T) {
|
||||
formatter: ValueFormatterSingleUnitDuration(time.Nanosecond, 8),
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
desc: "Round formatter handles NaN values",
|
||||
value: math.NaN(),
|
||||
formatter: ValueFormatterRound,
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
desc: "Round formatter handles 0 values",
|
||||
value: 0,
|
||||
formatter: ValueFormatterRound,
|
||||
want: "0",
|
||||
},
|
||||
{
|
||||
desc: "Round formatter handles > x.5 values",
|
||||
value: 96.7,
|
||||
formatter: ValueFormatterRound,
|
||||
want: "97",
|
||||
},
|
||||
{
|
||||
desc: "Round formatter handles < x.5 values",
|
||||
value: 1621.2,
|
||||
formatter: ValueFormatterRound,
|
||||
want: "1621",
|
||||
},
|
||||
{
|
||||
desc: "Round formatter handles x.5 values",
|
||||
value: 6.5,
|
||||
formatter: ValueFormatterRound,
|
||||
want: "7",
|
||||
},
|
||||
{
|
||||
desc: "Round formatter handles minus > x.5 values",
|
||||
value: -96.7,
|
||||
formatter: ValueFormatterRound,
|
||||
want: "-97",
|
||||
},
|
||||
{
|
||||
desc: "Round formatter handles minus < x.5 values",
|
||||
value: -1621.2,
|
||||
formatter: ValueFormatterRound,
|
||||
want: "-1621",
|
||||
},
|
||||
{
|
||||
desc: "Round formatter handles minus x.5 values",
|
||||
value: -6.5,
|
||||
formatter: ValueFormatterRound,
|
||||
want: "-7",
|
||||
},
|
||||
{
|
||||
desc: "Round formatter handles values with suffix",
|
||||
value: 96.7,
|
||||
formatter: ValueFormatterRoundWithSuffix("km"),
|
||||
want: "97km",
|
||||
},
|
||||
{
|
||||
desc: "Suffix formatter handles values with decimals",
|
||||
value: 11234567890.71234567890,
|
||||
formatter: ValueFormatterSuffix(4, " reqps"),
|
||||
want: "11234567890.7123 reqps",
|
||||
},
|
||||
{
|
||||
desc: "Suffix formatter handles NaN values",
|
||||
value: math.NaN(),
|
||||
formatter: ValueFormatterSuffix(2, "test"),
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
desc: "Suffix formatter handles 0 values",
|
||||
value: 0,
|
||||
formatter: ValueFormatterSuffix(2, "test"),
|
||||
want: "0.00test",
|
||||
},
|
||||
{
|
||||
desc: "Suffix formatters handles correctly percent suffix",
|
||||
value: 96.78,
|
||||
formatter: ValueFormatterSuffix(2, "%"),
|
||||
want: "96.78%",
|
||||
},
|
||||
{
|
||||
desc: "Round formatter handles values with percent suffix",
|
||||
value: 96.7,
|
||||
formatter: ValueFormatterRoundWithSuffix("%"),
|
||||
want: "97%",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
|
Loading…
x
Reference in New Issue
Block a user