mirror of
https://github.com/mum4k/termdash.git
synced 2025-05-04 22:18:07 +08:00
Refactoring y.Details off the object.
This commit is contained in:
parent
9b3edb42b9
commit
feb406ec11
@ -88,19 +88,30 @@ func RequiredWidth(minVal, maxVal float64) int {
|
||||
}) + axisWidth
|
||||
}
|
||||
|
||||
// Details retrieves details about the Y axis required to draw it on a canvas
|
||||
// of the provided area.
|
||||
// The argument reqXHeight is the height required for the X axis and its labels.
|
||||
func (y *Y) Details(cvsAr image.Rectangle, reqXHeight int, mode YScaleMode) (*YDetails, error) {
|
||||
// YProperties are the properties of the Y axis.
|
||||
type YProperties struct {
|
||||
// Min is the minimum value on the axis.
|
||||
Min float64
|
||||
// Max is the maximum value on the axis.
|
||||
Max float64
|
||||
// ReqXHeight is the height required for the X axis and its labels.
|
||||
ReqXHeight int
|
||||
// ScaleMode determines how the Y axis scales.
|
||||
ScaleMode YScaleMode
|
||||
}
|
||||
|
||||
// NewYDetails retrieves details about the Y axis required to draw it on a
|
||||
// canvas of the provided area.
|
||||
func NewYDetails(cvsAr image.Rectangle, yp *YProperties) (*YDetails, error) {
|
||||
cvsWidth := cvsAr.Dx()
|
||||
cvsHeight := cvsAr.Dy()
|
||||
maxWidth := cvsWidth - 1 // Reserve one column for the line chart itself.
|
||||
if req := RequiredWidth(y.min.Value, y.max.Value); maxWidth < req {
|
||||
if req := RequiredWidth(yp.Min, yp.Max); maxWidth < req {
|
||||
return nil, fmt.Errorf("the available maxWidth %d is smaller than the reported required width %d", maxWidth, req)
|
||||
}
|
||||
|
||||
graphHeight := cvsHeight - reqXHeight
|
||||
scale, err := NewYScale(y.min.Value, y.max.Value, graphHeight, nonZeroDecimals, mode)
|
||||
graphHeight := cvsHeight - yp.ReqXHeight
|
||||
scale, err := NewYScale(yp.Min, yp.Max, graphHeight, nonZeroDecimals, yp.ScaleMode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -29,11 +29,7 @@ type updateY struct {
|
||||
func TestY(t *testing.T) {
|
||||
tests := []struct {
|
||||
desc string
|
||||
minVal float64
|
||||
maxVal float64
|
||||
update *updateY
|
||||
reqXHeight int
|
||||
mode YScaleMode
|
||||
yp *YProperties
|
||||
cvsAr image.Rectangle
|
||||
wantWidth int
|
||||
want *YDetails
|
||||
@ -41,38 +37,46 @@ func TestY(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
desc: "fails on canvas too small",
|
||||
minVal: 0,
|
||||
maxVal: 3,
|
||||
yp: &YProperties{
|
||||
Min: 0,
|
||||
Max: 3,
|
||||
ReqXHeight: 2,
|
||||
},
|
||||
cvsAr: image.Rect(0, 0, 3, 2),
|
||||
reqXHeight: 2,
|
||||
wantWidth: 2,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
desc: "fails on cvsWidth less than required width",
|
||||
minVal: 0,
|
||||
maxVal: 3,
|
||||
yp: &YProperties{
|
||||
Min: 0,
|
||||
Max: 3,
|
||||
ReqXHeight: 2,
|
||||
},
|
||||
cvsAr: image.Rect(0, 0, 2, 4),
|
||||
reqXHeight: 2,
|
||||
wantWidth: 2,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
desc: "fails when max is less than min",
|
||||
minVal: 0,
|
||||
maxVal: -1,
|
||||
yp: &YProperties{
|
||||
Min: 0,
|
||||
Max: -1,
|
||||
ReqXHeight: 2,
|
||||
},
|
||||
cvsAr: image.Rect(0, 0, 4, 4),
|
||||
reqXHeight: 2,
|
||||
wantWidth: 3,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
desc: "cvsWidth equals required width",
|
||||
minVal: 0,
|
||||
maxVal: 3,
|
||||
yp: &YProperties{
|
||||
Min: 0,
|
||||
Max: 3,
|
||||
ReqXHeight: 2,
|
||||
},
|
||||
cvsAr: image.Rect(0, 0, 3, 4),
|
||||
wantWidth: 2,
|
||||
reqXHeight: 2,
|
||||
want: &YDetails{
|
||||
Width: 2,
|
||||
Start: image.Point{1, 0},
|
||||
@ -86,11 +90,13 @@ func TestY(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "success for anchored scale",
|
||||
minVal: 1,
|
||||
maxVal: 3,
|
||||
mode: YScaleModeAnchored,
|
||||
yp: &YProperties{
|
||||
Min: 1,
|
||||
Max: 3,
|
||||
ReqXHeight: 2,
|
||||
ScaleMode: YScaleModeAnchored,
|
||||
},
|
||||
cvsAr: image.Rect(0, 0, 3, 4),
|
||||
reqXHeight: 2,
|
||||
wantWidth: 2,
|
||||
want: &YDetails{
|
||||
Width: 2,
|
||||
@ -105,11 +111,13 @@ func TestY(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "accommodates X scale that needs more height",
|
||||
minVal: 1,
|
||||
maxVal: 3,
|
||||
mode: YScaleModeAnchored,
|
||||
yp: &YProperties{
|
||||
Min: 1,
|
||||
Max: 3,
|
||||
ReqXHeight: 4,
|
||||
ScaleMode: YScaleModeAnchored,
|
||||
},
|
||||
cvsAr: image.Rect(0, 0, 3, 6),
|
||||
reqXHeight: 4,
|
||||
wantWidth: 2,
|
||||
want: &YDetails{
|
||||
Width: 2,
|
||||
@ -124,11 +132,13 @@ func TestY(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "success for adaptive scale",
|
||||
minVal: 1,
|
||||
maxVal: 6,
|
||||
mode: YScaleModeAdaptive,
|
||||
yp: &YProperties{
|
||||
Min: 1,
|
||||
Max: 6,
|
||||
ReqXHeight: 2,
|
||||
ScaleMode: YScaleModeAdaptive,
|
||||
},
|
||||
cvsAr: image.Rect(0, 0, 3, 4),
|
||||
reqXHeight: 2,
|
||||
wantWidth: 2,
|
||||
want: &YDetails{
|
||||
Width: 2,
|
||||
@ -143,10 +153,12 @@ func TestY(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "cvsWidth just accommodates the longest label",
|
||||
minVal: 0,
|
||||
maxVal: 3,
|
||||
yp: &YProperties{
|
||||
Min: 0,
|
||||
Max: 3,
|
||||
ReqXHeight: 2,
|
||||
},
|
||||
cvsAr: image.Rect(0, 0, 6, 4),
|
||||
reqXHeight: 2,
|
||||
wantWidth: 2,
|
||||
want: &YDetails{
|
||||
Width: 5,
|
||||
@ -161,10 +173,12 @@ func TestY(t *testing.T) {
|
||||
},
|
||||
{
|
||||
desc: "cvsWidth is more than we need",
|
||||
minVal: 0,
|
||||
maxVal: 3,
|
||||
yp: &YProperties{
|
||||
Min: 0,
|
||||
Max: 3,
|
||||
ReqXHeight: 2,
|
||||
},
|
||||
cvsAr: image.Rect(0, 0, 7, 4),
|
||||
reqXHeight: 2,
|
||||
wantWidth: 2,
|
||||
want: &YDetails{
|
||||
Width: 5,
|
||||
@ -181,17 +195,12 @@ func TestY(t *testing.T) {
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
y := NewY(tc.minVal, tc.maxVal)
|
||||
if tc.update != nil {
|
||||
y.Update(tc.update.minVal, tc.update.maxVal)
|
||||
}
|
||||
|
||||
gotWidth := RequiredWidth(tc.minVal, tc.maxVal)
|
||||
gotWidth := RequiredWidth(tc.yp.Min, tc.yp.Max)
|
||||
if gotWidth != tc.wantWidth {
|
||||
t.Errorf("RequiredWidth => got %v, want %v", gotWidth, tc.wantWidth)
|
||||
}
|
||||
|
||||
got, err := y.Details(tc.cvsAr, tc.reqXHeight, tc.mode)
|
||||
got, err := NewYDetails(tc.cvsAr, tc.yp)
|
||||
if (err != nil) != tc.wantErr {
|
||||
t.Errorf("Details => unexpected error: %v, wantErr: %v", err, tc.wantErr)
|
||||
}
|
||||
|
@ -212,7 +212,13 @@ func (lc *LineChart) Draw(cvs *canvas.Canvas) error {
|
||||
}
|
||||
|
||||
reqXHeight := axes.RequiredHeight(lc.maxPoints(), lc.xLabels, lc.opts.xLabelOrientation)
|
||||
yd, err := lc.yAxis.Details(cvs.Area(), reqXHeight, lc.opts.yAxisMode)
|
||||
yp := &axes.YProperties{
|
||||
Min: lc.yMin,
|
||||
Max: lc.yMax,
|
||||
ReqXHeight: reqXHeight,
|
||||
ScaleMode: lc.opts.yAxisMode,
|
||||
}
|
||||
yd, err := axes.NewYDetails(cvs.Area(), yp)
|
||||
if err != nil {
|
||||
return fmt.Errorf("lc.yAxis.Details => %v", err)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user