mirror of
https://github.com/mum4k/termdash.git
synced 2025-04-30 13:48:54 +08:00
Add formatted values creation if the scale has a value formatter asigned
Signed-off-by: Xabier Larrakoetxea <slok69@gmail.com>
This commit is contained in:
parent
7157a07457
commit
135edd42fa
@ -72,6 +72,8 @@ type YProperties struct {
|
|||||||
ReqXHeight int
|
ReqXHeight int
|
||||||
// ScaleMode determines how the Y axis scales.
|
// ScaleMode determines how the Y axis scales.
|
||||||
ScaleMode YScaleMode
|
ScaleMode YScaleMode
|
||||||
|
// ValueFormatter is the formatter used to format numeric values to string representation.
|
||||||
|
ValueFormatter valueFormatter
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewYDetails retrieves details about the Y axis required to draw it on a
|
// NewYDetails retrieves details about the Y axis required to draw it on a
|
||||||
@ -85,7 +87,7 @@ func NewYDetails(cvsAr image.Rectangle, yp *YProperties) (*YDetails, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
graphHeight := cvsHeight - yp.ReqXHeight
|
graphHeight := cvsHeight - yp.ReqXHeight
|
||||||
scale, err := NewYScale(yp.Min, yp.Max, graphHeight, nonZeroDecimals, yp.ScaleMode)
|
scale, err := NewYScale(yp.Min, yp.Max, graphHeight, nonZeroDecimals, yp.ScaleMode, yp.ValueFormatter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,10 @@ import (
|
|||||||
"github.com/kylelemons/godebug/pretty"
|
"github.com/kylelemons/godebug/pretty"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
testValueFormatter = func(float64) string { return "test" }
|
||||||
|
)
|
||||||
|
|
||||||
type updateY struct {
|
type updateY struct {
|
||||||
minVal float64
|
minVal float64
|
||||||
maxVal float64
|
maxVal float64
|
||||||
@ -82,7 +86,7 @@ func TestY(t *testing.T) {
|
|||||||
Width: 2,
|
Width: 2,
|
||||||
Start: image.Point{1, 0},
|
Start: image.Point{1, 0},
|
||||||
End: image.Point{1, 2},
|
End: image.Point{1, 2},
|
||||||
Scale: mustNewYScale(0, 3, 2, nonZeroDecimals, YScaleModeAnchored),
|
Scale: mustNewYScale(0, 3, 2, nonZeroDecimals, YScaleModeAnchored, nil),
|
||||||
Labels: []*Label{
|
Labels: []*Label{
|
||||||
{NewValue(0, nonZeroDecimals), image.Point{0, 1}},
|
{NewValue(0, nonZeroDecimals), image.Point{0, 1}},
|
||||||
{NewValue(1.72, nonZeroDecimals), image.Point{0, 0}},
|
{NewValue(1.72, nonZeroDecimals), image.Point{0, 0}},
|
||||||
@ -103,7 +107,7 @@ func TestY(t *testing.T) {
|
|||||||
Width: 2,
|
Width: 2,
|
||||||
Start: image.Point{1, 0},
|
Start: image.Point{1, 0},
|
||||||
End: image.Point{1, 2},
|
End: image.Point{1, 2},
|
||||||
Scale: mustNewYScale(0, 3, 2, nonZeroDecimals, YScaleModeAnchored),
|
Scale: mustNewYScale(0, 3, 2, nonZeroDecimals, YScaleModeAnchored, nil),
|
||||||
Labels: []*Label{
|
Labels: []*Label{
|
||||||
{NewValue(0, nonZeroDecimals), image.Point{0, 1}},
|
{NewValue(0, nonZeroDecimals), image.Point{0, 1}},
|
||||||
{NewValue(1.72, nonZeroDecimals), image.Point{0, 0}},
|
{NewValue(1.72, nonZeroDecimals), image.Point{0, 0}},
|
||||||
@ -124,7 +128,7 @@ func TestY(t *testing.T) {
|
|||||||
Width: 2,
|
Width: 2,
|
||||||
Start: image.Point{1, 0},
|
Start: image.Point{1, 0},
|
||||||
End: image.Point{1, 2},
|
End: image.Point{1, 2},
|
||||||
Scale: mustNewYScale(0, 3, 2, nonZeroDecimals, YScaleModeAnchored),
|
Scale: mustNewYScale(0, 3, 2, nonZeroDecimals, YScaleModeAnchored, nil),
|
||||||
Labels: []*Label{
|
Labels: []*Label{
|
||||||
{NewValue(0, nonZeroDecimals), image.Point{0, 1}},
|
{NewValue(0, nonZeroDecimals), image.Point{0, 1}},
|
||||||
{NewValue(1.72, nonZeroDecimals), image.Point{0, 0}},
|
{NewValue(1.72, nonZeroDecimals), image.Point{0, 0}},
|
||||||
@ -145,7 +149,7 @@ func TestY(t *testing.T) {
|
|||||||
Width: 2,
|
Width: 2,
|
||||||
Start: image.Point{1, 0},
|
Start: image.Point{1, 0},
|
||||||
End: image.Point{1, 2},
|
End: image.Point{1, 2},
|
||||||
Scale: mustNewYScale(1, 6, 2, nonZeroDecimals, YScaleModeAdaptive),
|
Scale: mustNewYScale(1, 6, 2, nonZeroDecimals, YScaleModeAdaptive, nil),
|
||||||
Labels: []*Label{
|
Labels: []*Label{
|
||||||
{NewValue(1, nonZeroDecimals), image.Point{0, 1}},
|
{NewValue(1, nonZeroDecimals), image.Point{0, 1}},
|
||||||
{NewValue(3.88, nonZeroDecimals), image.Point{0, 0}},
|
{NewValue(3.88, nonZeroDecimals), image.Point{0, 0}},
|
||||||
@ -165,7 +169,7 @@ func TestY(t *testing.T) {
|
|||||||
Width: 5,
|
Width: 5,
|
||||||
Start: image.Point{4, 0},
|
Start: image.Point{4, 0},
|
||||||
End: image.Point{4, 2},
|
End: image.Point{4, 2},
|
||||||
Scale: mustNewYScale(0, 3, 2, nonZeroDecimals, YScaleModeAnchored),
|
Scale: mustNewYScale(0, 3, 2, nonZeroDecimals, YScaleModeAnchored, nil),
|
||||||
Labels: []*Label{
|
Labels: []*Label{
|
||||||
{NewValue(0, nonZeroDecimals), image.Point{3, 1}},
|
{NewValue(0, nonZeroDecimals), image.Point{3, 1}},
|
||||||
{NewValue(1.72, nonZeroDecimals), image.Point{0, 0}},
|
{NewValue(1.72, nonZeroDecimals), image.Point{0, 0}},
|
||||||
@ -185,13 +189,35 @@ func TestY(t *testing.T) {
|
|||||||
Width: 5,
|
Width: 5,
|
||||||
Start: image.Point{4, 0},
|
Start: image.Point{4, 0},
|
||||||
End: image.Point{4, 2},
|
End: image.Point{4, 2},
|
||||||
Scale: mustNewYScale(0, 3, 2, nonZeroDecimals, YScaleModeAnchored),
|
Scale: mustNewYScale(0, 3, 2, nonZeroDecimals, YScaleModeAnchored, nil),
|
||||||
Labels: []*Label{
|
Labels: []*Label{
|
||||||
{NewValue(0, nonZeroDecimals), image.Point{3, 1}},
|
{NewValue(0, nonZeroDecimals), image.Point{3, 1}},
|
||||||
{NewValue(1.72, nonZeroDecimals), image.Point{0, 0}},
|
{NewValue(1.72, nonZeroDecimals), image.Point{0, 0}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
desc: "success for formatted labels scale",
|
||||||
|
yp: &YProperties{
|
||||||
|
Min: 1,
|
||||||
|
Max: 3,
|
||||||
|
ReqXHeight: 2,
|
||||||
|
ScaleMode: YScaleModeAnchored,
|
||||||
|
ValueFormatter: testValueFormatter,
|
||||||
|
},
|
||||||
|
cvsAr: image.Rect(0, 0, 3, 4),
|
||||||
|
wantWidth: 2,
|
||||||
|
want: &YDetails{
|
||||||
|
Width: 2,
|
||||||
|
Start: image.Point{1, 0},
|
||||||
|
End: image.Point{1, 2},
|
||||||
|
Scale: mustNewYScale(0, 3, 2, nonZeroDecimals, YScaleModeAnchored, testValueFormatter),
|
||||||
|
Labels: []*Label{
|
||||||
|
{NewFormattedValue(0, nonZeroDecimals, testValueFormatter), image.Point{0, 1}},
|
||||||
|
{NewFormattedValue(1.72, nonZeroDecimals, testValueFormatter), image.Point{0, 0}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range tests {
|
for _, tc := range tests {
|
||||||
|
@ -129,7 +129,7 @@ func TestYLabels(t *testing.T) {
|
|||||||
|
|
||||||
for _, tc := range tests {
|
for _, tc := range tests {
|
||||||
t.Run(tc.desc, func(t *testing.T) {
|
t.Run(tc.desc, func(t *testing.T) {
|
||||||
scale, err := NewYScale(tc.min, tc.max, tc.graphHeight, nonZeroDecimals, YScaleModeAnchored)
|
scale, err := NewYScale(tc.min, tc.max, tc.graphHeight, nonZeroDecimals, YScaleModeAnchored, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("NewYScale => unexpected error: %v", err)
|
t.Fatalf("NewYScale => unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,10 @@ type YScale struct {
|
|||||||
GraphHeight int
|
GraphHeight int
|
||||||
// brailleHeight is the height of the braille canvas based on the GraphHeight.
|
// brailleHeight is the height of the braille canvas based on the GraphHeight.
|
||||||
brailleHeight int
|
brailleHeight int
|
||||||
|
|
||||||
|
// valueFormatter is the value formatter used for the labels
|
||||||
|
// represented by the values on the scale.
|
||||||
|
valueFormatter valueFormatter
|
||||||
}
|
}
|
||||||
|
|
||||||
// String implements fmt.Stringer.
|
// String implements fmt.Stringer.
|
||||||
@ -78,7 +82,7 @@ func (ys *YScale) String() string {
|
|||||||
// calculated scale, see NewValue for details.
|
// calculated scale, see NewValue for details.
|
||||||
// Max must be greater or equal to min. The graphHeight must be a positive
|
// Max must be greater or equal to min. The graphHeight must be a positive
|
||||||
// number.
|
// number.
|
||||||
func NewYScale(min, max float64, graphHeight, nonZeroDecimals int, mode YScaleMode) (*YScale, error) {
|
func NewYScale(min, max float64, graphHeight, nonZeroDecimals int, mode YScaleMode, valueFormatter valueFormatter) (*YScale, error) {
|
||||||
if max < min {
|
if max < min {
|
||||||
return nil, fmt.Errorf("max(%v) cannot be less than min(%v)", max, min)
|
return nil, fmt.Errorf("max(%v) cannot be less than min(%v)", max, min)
|
||||||
}
|
}
|
||||||
@ -114,11 +118,12 @@ func NewYScale(min, max float64, graphHeight, nonZeroDecimals int, mode YScaleMo
|
|||||||
diff := max - min
|
diff := max - min
|
||||||
step := NewValue(diff/float64(usablePixels), nonZeroDecimals)
|
step := NewValue(diff/float64(usablePixels), nonZeroDecimals)
|
||||||
return &YScale{
|
return &YScale{
|
||||||
Min: NewValue(min, nonZeroDecimals),
|
Min: yScaleNewValue(min, nonZeroDecimals, valueFormatter),
|
||||||
Max: NewValue(max, nonZeroDecimals),
|
Max: yScaleNewValue(max, nonZeroDecimals, valueFormatter),
|
||||||
Step: step,
|
Step: step,
|
||||||
GraphHeight: graphHeight,
|
GraphHeight: graphHeight,
|
||||||
brailleHeight: brailleHeight,
|
brailleHeight: brailleHeight,
|
||||||
|
valueFormatter: valueFormatter,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,7 +193,18 @@ func (ys *YScale) CellLabel(y int) (*Value, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return NewValue(v, ys.Min.NonZeroDecimals), nil
|
return yScaleNewValue(v, ys.Min.NonZeroDecimals, ys.valueFormatter), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// yScaleNewValue is a helper method to get new values for the y scale
|
||||||
|
// that selects the correct value factory method depending on the passed
|
||||||
|
// arguments.
|
||||||
|
func yScaleNewValue(value float64, nonZeroDecimals int, valueFormatter valueFormatter) *Value {
|
||||||
|
if valueFormatter != nil {
|
||||||
|
return NewFormattedValue(value, nonZeroDecimals, valueFormatter)
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewValue(value, nonZeroDecimals)
|
||||||
}
|
}
|
||||||
|
|
||||||
// XScale is the scale of the X axis.
|
// XScale is the scale of the X axis.
|
||||||
|
@ -22,8 +22,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// mustNewYScale returns a new YScale or panics.
|
// mustNewYScale returns a new YScale or panics.
|
||||||
func mustNewYScale(min, max float64, graphHeight, nonZeroDecimals int, mode YScaleMode) *YScale {
|
func mustNewYScale(min, max float64, graphHeight, nonZeroDecimals int, mode YScaleMode, formatter valueFormatter) *YScale {
|
||||||
s, err := NewYScale(min, max, graphHeight, nonZeroDecimals, mode)
|
s, err := NewYScale(min, max, graphHeight, nonZeroDecimals, mode, formatter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -766,7 +766,7 @@ func TestYScale(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
scale, err := NewYScale(test.min, test.max, test.graphHeight, test.nonZeroDecimals, test.mode)
|
scale, err := NewYScale(test.min, test.max, test.graphHeight, test.nonZeroDecimals, test.mode, nil)
|
||||||
if (err != nil) != test.wantErr {
|
if (err != nil) != test.wantErr {
|
||||||
t.Errorf("NewYScale => unexpected error: %v, wantErr: %v", err, test.wantErr)
|
t.Errorf("NewYScale => unexpected error: %v, wantErr: %v", err, test.wantErr)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user