1
0
mirror of https://github.com/mum4k/termdash.git synced 2025-04-30 13:48:54 +08:00

LineChart defaults to 0 mix and max when these are NaN

Signed-off-by: Xabier Larrakoetxea <slok69@gmail.com>
This commit is contained in:
Xabier Larrakoetxea 2019-04-17 13:42:05 +02:00
parent 9b25e35172
commit b54694ed12
No known key found for this signature in database
GPG Key ID: FDAD7FD8275E1B32
2 changed files with 136 additions and 50 deletions

View File

@ -57,7 +57,7 @@ func newSeriesValues(values []float64) *seriesValues {
v := make([]float64, len(values)) v := make([]float64, len(values))
copy(v, values) copy(v, values)
min, max := numbers.MinMax(v) min, max := minMax(v)
return &seriesValues{ return &seriesValues{
values: v, values: v,
min: min, min: min,
@ -176,8 +176,9 @@ func (lc *LineChart) yMinMax() (float64, float64) {
maximums = append(maximums, lc.opts.yAxisCustomScale.max) maximums = append(maximums, lc.opts.yAxisCustomScale.max)
} }
min, _ := numbers.MinMax(minimums) min, _ := minMax(minimums)
_, max := numbers.MinMax(maximums) _, max := minMax(maximums)
return min, max return min, max
} }
@ -530,3 +531,22 @@ func (lc *LineChart) maxXValue() int {
} }
return maxLen - 1 return maxLen - 1
} }
const (
defMin = 0
defMax = 0
)
// minMax is a wrapper around numbers.MinMax that controls
// the output if the values are NaN and sets defaults if it's
// the case.
func minMax(values []float64) (x, y float64) {
min, max := numbers.MinMax(values)
if math.IsNaN(min) {
min = defMin
}
if math.IsNaN(max) {
max = defMax
}
return min, max
}

View File

@ -960,53 +960,6 @@ func TestLineChartDraws(t *testing.T) {
return ft return ft
}, },
}, },
{
desc: "more values than capacity, X rescales with NaN values ignored",
canvas: image.Rect(0, 0, 11, 10),
writes: func(lc *LineChart) error {
return lc.Series("first", []float64{0, 1, 2, 3, 4, 5, 6, 7, math.NaN(), math.NaN(), math.NaN(), math.NaN(), 12, 13, 14, 15, 16, 17, 18, 19})
},
wantCapacity: 12,
want: func(size image.Point) *faketerm.Terminal {
ft := faketerm.MustNew(size)
c := testcanvas.MustNew(ft.Area())
// Y and X axis.
lines := []draw.HVLine{
{Start: image.Point{4, 0}, End: image.Point{4, 8}},
{Start: image.Point{4, 8}, End: image.Point{10, 8}},
}
testdraw.MustHVLines(c, lines)
// Value labels.
testdraw.MustText(c, "0", image.Point{3, 7})
testdraw.MustText(c, "9.92", image.Point{0, 3})
testdraw.MustText(c, "0", image.Point{5, 9})
testdraw.MustText(c, "14", image.Point{9, 9})
// Braille line.
graphAr := image.Rect(5, 0, 11, 8)
bc := testbraille.MustNew(graphAr)
testdraw.MustBrailleLine(bc, image.Point{0, 31}, image.Point{1, 29})
testdraw.MustBrailleLine(bc, image.Point{1, 29}, image.Point{1, 28})
testdraw.MustBrailleLine(bc, image.Point{1, 28}, image.Point{2, 26})
testdraw.MustBrailleLine(bc, image.Point{2, 26}, image.Point{2, 25})
testdraw.MustBrailleLine(bc, image.Point{2, 25}, image.Point{3, 23})
testdraw.MustBrailleLine(bc, image.Point{3, 23}, image.Point{3, 21})
testdraw.MustBrailleLine(bc, image.Point{3, 21}, image.Point{4, 20})
testdraw.MustBrailleLine(bc, image.Point{7, 12}, image.Point{8, 10})
testdraw.MustBrailleLine(bc, image.Point{8, 10}, image.Point{8, 8})
testdraw.MustBrailleLine(bc, image.Point{8, 8}, image.Point{9, 7})
testdraw.MustBrailleLine(bc, image.Point{9, 7}, image.Point{9, 5})
testdraw.MustBrailleLine(bc, image.Point{9, 5}, image.Point{10, 4})
testdraw.MustBrailleLine(bc, image.Point{10, 4}, image.Point{10, 2})
testdraw.MustBrailleLine(bc, image.Point{10, 2}, image.Point{11, 0})
testbraille.MustCopyTo(bc, c)
testcanvas.MustApply(c, ft)
return ft
},
},
{ {
desc: "more values than capacity, X unscaled", desc: "more values than capacity, X unscaled",
opts: []Option{ opts: []Option{
@ -1570,6 +1523,119 @@ func TestLineChartDraws(t *testing.T) {
testdraw.MustBrailleLine(bc, image.Point{0, 31}, image.Point{26, 0}) testdraw.MustBrailleLine(bc, image.Point{0, 31}, image.Point{26, 0})
testbraille.MustCopyTo(bc, c) testbraille.MustCopyTo(bc, c)
testcanvas.MustApply(c, ft)
return ft
},
},
{
desc: "all NaN values",
canvas: image.Rect(0, 0, 20, 10),
writes: func(lc *LineChart) error {
return lc.Series("first", []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN()})
},
wantCapacity: 36,
want: func(size image.Point) *faketerm.Terminal {
ft := faketerm.MustNew(size)
c := testcanvas.MustNew(ft.Area())
// Y and X axis.
lines := []draw.HVLine{
{Start: image.Point{1, 0}, End: image.Point{1, 8}},
{Start: image.Point{1, 8}, End: image.Point{19, 8}},
}
testdraw.MustHVLines(c, lines)
// Value labels.
testdraw.MustText(c, "0", image.Point{0, 7})
testdraw.MustText(c, "0", image.Point{2, 9})
testdraw.MustText(c, "1", image.Point{6, 9})
testdraw.MustText(c, "2", image.Point{10, 9})
testdraw.MustText(c, "3", image.Point{14, 9})
testdraw.MustText(c, "4", image.Point{18, 9})
testcanvas.MustApply(c, ft)
return ft
},
},
{
desc: "first and last NaN values",
canvas: image.Rect(0, 0, 28, 10),
writes: func(lc *LineChart) error {
return lc.Series("first", []float64{math.NaN(), math.NaN(), 100, 150, math.NaN()})
},
wantCapacity: 44,
want: func(size image.Point) *faketerm.Terminal {
ft := faketerm.MustNew(size)
c := testcanvas.MustNew(ft.Area())
// Y and X axis.
lines := []draw.HVLine{
{Start: image.Point{5, 0}, End: image.Point{5, 8}},
{Start: image.Point{5, 8}, End: image.Point{27, 8}},
}
testdraw.MustHVLines(c, lines)
// Value labels.
testdraw.MustText(c, "0", image.Point{4, 7})
testdraw.MustText(c, "77.44", image.Point{0, 3})
testdraw.MustText(c, "0", image.Point{6, 9})
testdraw.MustText(c, "1", image.Point{11, 9})
testdraw.MustText(c, "2", image.Point{16, 9})
testdraw.MustText(c, "3", image.Point{22, 9})
testdraw.MustText(c, "4", image.Point{27, 9})
graphAr := image.Rect(6, 0, 25, 8)
bc := testbraille.MustNew(graphAr)
testdraw.MustBrailleLine(bc, image.Point{21, 10}, image.Point{32, 0})
testbraille.MustCopyTo(bc, c)
testcanvas.MustApply(c, ft)
return ft
},
},
{
desc: "more values than capacity, X rescales with NaN values ignored",
canvas: image.Rect(0, 0, 11, 10),
writes: func(lc *LineChart) error {
return lc.Series("first", []float64{0, 1, 2, 3, 4, 5, 6, 7, math.NaN(), math.NaN(), math.NaN(), math.NaN(), 12, 13, 14, 15, 16, 17, 18, 19})
},
wantCapacity: 12,
want: func(size image.Point) *faketerm.Terminal {
ft := faketerm.MustNew(size)
c := testcanvas.MustNew(ft.Area())
// Y and X axis.
lines := []draw.HVLine{
{Start: image.Point{4, 0}, End: image.Point{4, 8}},
{Start: image.Point{4, 8}, End: image.Point{10, 8}},
}
testdraw.MustHVLines(c, lines)
// Value labels.
testdraw.MustText(c, "0", image.Point{3, 7})
testdraw.MustText(c, "9.92", image.Point{0, 3})
testdraw.MustText(c, "0", image.Point{5, 9})
testdraw.MustText(c, "14", image.Point{9, 9})
// Braille line.
graphAr := image.Rect(5, 0, 11, 8)
bc := testbraille.MustNew(graphAr)
testdraw.MustBrailleLine(bc, image.Point{0, 31}, image.Point{1, 29})
testdraw.MustBrailleLine(bc, image.Point{1, 29}, image.Point{1, 28})
testdraw.MustBrailleLine(bc, image.Point{1, 28}, image.Point{2, 26})
testdraw.MustBrailleLine(bc, image.Point{2, 26}, image.Point{2, 25})
testdraw.MustBrailleLine(bc, image.Point{2, 25}, image.Point{3, 23})
testdraw.MustBrailleLine(bc, image.Point{3, 23}, image.Point{3, 21})
testdraw.MustBrailleLine(bc, image.Point{3, 21}, image.Point{4, 20})
testdraw.MustBrailleLine(bc, image.Point{7, 12}, image.Point{8, 10})
testdraw.MustBrailleLine(bc, image.Point{8, 10}, image.Point{8, 8})
testdraw.MustBrailleLine(bc, image.Point{8, 8}, image.Point{9, 7})
testdraw.MustBrailleLine(bc, image.Point{9, 7}, image.Point{9, 5})
testdraw.MustBrailleLine(bc, image.Point{9, 5}, image.Point{10, 4})
testdraw.MustBrailleLine(bc, image.Point{10, 4}, image.Point{10, 2})
testdraw.MustBrailleLine(bc, image.Point{10, 2}, image.Point{11, 0})
testbraille.MustCopyTo(bc, c)
testcanvas.MustApply(c, ft) testcanvas.MustApply(c, ft)
return ft return ft
}, },