mirror of
https://github.com/mum4k/termdash.git
synced 2025-04-28 13:48:51 +08:00
LineChart now correctly displays series without zero.
This commit is contained in:
parent
852f989dd5
commit
406c365847
@ -14,6 +14,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
- The LineChart now correctly displays positive and negative series that don't
|
||||||
|
contain zero value.
|
||||||
- Lint errors reported on the Go report card.
|
- Lint errors reported on the Go report card.
|
||||||
|
|
||||||
## [0.5.0] - 21-Jan-2019
|
## [0.5.0] - 21-Jan-2019
|
||||||
|
@ -55,10 +55,10 @@ func NewYScale(min, max float64, graphHeight, nonZeroDecimals int) (*YScale, err
|
|||||||
brailleHeight := graphHeight * braille.RowMult
|
brailleHeight := graphHeight * braille.RowMult
|
||||||
usablePixels := brailleHeight - 1 // One pixel reserved for value zero.
|
usablePixels := brailleHeight - 1 // One pixel reserved for value zero.
|
||||||
|
|
||||||
if min > 0 { // If we only have positive data points, make the scale zero based (min).
|
if min > 0 && min == max { // If all the data points are equal, make the scale zero based so we can draw something.
|
||||||
min = 0
|
min = 0
|
||||||
}
|
}
|
||||||
if max < 0 { // If we only have negative data points, make the scale zero based (max).
|
if max < 0 && min == max { // If all the data points are equal, make the scale zero based so we can draw something.
|
||||||
max = 0
|
max = 0
|
||||||
}
|
}
|
||||||
diff := max - min
|
diff := max - min
|
||||||
@ -87,7 +87,11 @@ func (ys *YScale) PixelToValue(y int) (float64, error) {
|
|||||||
case pos == ys.brailleHeight-1:
|
case pos == ys.brailleHeight-1:
|
||||||
return ys.Max.Rounded, nil
|
return ys.Max.Rounded, nil
|
||||||
default:
|
default:
|
||||||
|
|
||||||
v := float64(pos) * ys.Step.Rounded
|
v := float64(pos) * ys.Step.Rounded
|
||||||
|
if ys.Min.Value > 0 {
|
||||||
|
v += ys.Min.Value
|
||||||
|
}
|
||||||
if ys.Min.Value < 0 {
|
if ys.Min.Value < 0 {
|
||||||
diff := -1 * ys.Min.Value
|
diff := -1 * ys.Min.Value
|
||||||
v -= diff
|
v -= diff
|
||||||
@ -105,6 +109,9 @@ func (ys *YScale) ValueToPixel(v float64) (int, error) {
|
|||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ys.Min.Value > 0 {
|
||||||
|
v -= ys.Min.Value
|
||||||
|
}
|
||||||
if ys.Min.Value < 0 {
|
if ys.Min.Value < 0 {
|
||||||
diff := -1 * ys.Min.Value
|
diff := -1 * ys.Min.Value
|
||||||
v += diff
|
v += diff
|
||||||
|
@ -183,28 +183,53 @@ func TestYScale(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "min is non-zero positive, not equal to max, scale is zero based",
|
desc: "min and max are non-zero negative and equal, scale is zero based",
|
||||||
min: 1,
|
min: -6,
|
||||||
max: 6,
|
max: -6,
|
||||||
graphHeight: 1,
|
graphHeight: 1,
|
||||||
nonZeroDecimals: 2,
|
nonZeroDecimals: 2,
|
||||||
pixelToValueTests: []pixelToValueTest{
|
pixelToValueTests: []pixelToValueTest{
|
||||||
{3, 0, false},
|
{3, -6, false},
|
||||||
{2, 2, false},
|
{2, -4, false},
|
||||||
{1, 4, false},
|
{1, -2, false},
|
||||||
{0, 6, false},
|
{0, 0, false},
|
||||||
},
|
},
|
||||||
valueToPixelTests: []valueToPixelTest{
|
valueToPixelTests: []valueToPixelTest{
|
||||||
{0, 3, false},
|
{0, 0, false},
|
||||||
|
{0.5, 0, false},
|
||||||
|
{-1, 0, false},
|
||||||
|
{-1.5, 1, false},
|
||||||
|
{-2, 1, false},
|
||||||
|
{-4, 2, false},
|
||||||
|
{-6, 3, false},
|
||||||
|
},
|
||||||
|
cellLabelTests: []cellLabelTest{
|
||||||
|
{0, NewValue(-6, 2), false},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "min is non-zero positive, not equal to max, scale is min based",
|
||||||
|
min: 1,
|
||||||
|
max: 7,
|
||||||
|
graphHeight: 1,
|
||||||
|
nonZeroDecimals: 2,
|
||||||
|
pixelToValueTests: []pixelToValueTest{
|
||||||
|
{3, 1, false},
|
||||||
|
{2, 3, false},
|
||||||
|
{1, 5, false},
|
||||||
|
{0, 7, false},
|
||||||
|
},
|
||||||
|
valueToPixelTests: []valueToPixelTest{
|
||||||
|
{0, 3, true},
|
||||||
{0.5, 3, false},
|
{0.5, 3, false},
|
||||||
{1, 2, false},
|
{1, 3, false},
|
||||||
{1.5, 2, false},
|
{1.5, 3, false},
|
||||||
{2, 2, false},
|
{2, 2, false},
|
||||||
{4, 1, false},
|
{4, 1, false},
|
||||||
{6, 0, false},
|
{6, 0, false},
|
||||||
},
|
},
|
||||||
cellLabelTests: []cellLabelTest{
|
cellLabelTests: []cellLabelTest{
|
||||||
{0, NewValue(0, 2), false},
|
{0, NewValue(1, 2), false},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -310,25 +335,25 @@ func TestYScale(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "negative integer scale, max is also negative, scale has max of zero",
|
desc: "negative integer scale, max is also negative",
|
||||||
min: -6,
|
min: -7,
|
||||||
max: -1,
|
max: -1,
|
||||||
graphHeight: 1,
|
graphHeight: 1,
|
||||||
nonZeroDecimals: 2,
|
nonZeroDecimals: 2,
|
||||||
pixelToValueTests: []pixelToValueTest{
|
pixelToValueTests: []pixelToValueTest{
|
||||||
{3, -6, false},
|
{3, -7, false},
|
||||||
{2, -4, false},
|
{2, -5, false},
|
||||||
{1, -2, false},
|
{1, -3, false},
|
||||||
{0, 0, false},
|
{0, -1, false},
|
||||||
},
|
},
|
||||||
valueToPixelTests: []valueToPixelTest{
|
valueToPixelTests: []valueToPixelTest{
|
||||||
{-6, 3, false},
|
{-7, 3, false},
|
||||||
{-4, 2, false},
|
{-4, 1, false},
|
||||||
{-2, 1, false},
|
{-2, 0, false},
|
||||||
{0, 0, false},
|
{-1, 0, false},
|
||||||
},
|
},
|
||||||
cellLabelTests: []cellLabelTest{
|
cellLabelTests: []cellLabelTest{
|
||||||
{0, NewValue(-6, 2), false},
|
{0, NewValue(-7, 2), false},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -366,6 +391,157 @@ func TestYScale(t *testing.T) {
|
|||||||
{111, -0.19, false},
|
{111, -0.19, false},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
desc: "regression for #92, positive values only",
|
||||||
|
min: 1600,
|
||||||
|
max: 1900,
|
||||||
|
graphHeight: 4,
|
||||||
|
nonZeroDecimals: 2,
|
||||||
|
pixelToValueTests: []pixelToValueTest{
|
||||||
|
{15, 1600, false},
|
||||||
|
{14, 1620, false},
|
||||||
|
{13, 1640, false},
|
||||||
|
{12, 1660, false},
|
||||||
|
{11, 1680, false},
|
||||||
|
{10, 1700, false},
|
||||||
|
{9, 1720, false},
|
||||||
|
{8, 1740, false},
|
||||||
|
{7, 1760, false},
|
||||||
|
{6, 1780, false},
|
||||||
|
{5, 1800, false},
|
||||||
|
{4, 1820, false},
|
||||||
|
{3, 1840, false},
|
||||||
|
{2, 1860, false},
|
||||||
|
{1, 1880, false},
|
||||||
|
{0, 1900, false},
|
||||||
|
},
|
||||||
|
valueToPixelTests: []valueToPixelTest{
|
||||||
|
{1590, 0, true},
|
||||||
|
{1600, 15, false},
|
||||||
|
{1620, 14, false},
|
||||||
|
{1640, 13, false},
|
||||||
|
{1660, 12, false},
|
||||||
|
{1680, 11, false},
|
||||||
|
{1700, 10, false},
|
||||||
|
{1720, 9, false},
|
||||||
|
{1740, 8, false},
|
||||||
|
{1760, 7, false},
|
||||||
|
{1780, 6, false},
|
||||||
|
{1800, 5, false},
|
||||||
|
{1820, 4, false},
|
||||||
|
{1840, 3, false},
|
||||||
|
{1860, 2, false},
|
||||||
|
{1880, 1, false},
|
||||||
|
{1900, 0, false},
|
||||||
|
{1910, 0, true},
|
||||||
|
},
|
||||||
|
cellLabelTests: []cellLabelTest{
|
||||||
|
{3, NewValue(1600, 2), false},
|
||||||
|
{2, NewValue(1680, 2), false},
|
||||||
|
{1, NewValue(1760, 2), false},
|
||||||
|
{0, NewValue(1840, 2), false},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "regression for #92, negative values only",
|
||||||
|
min: -1900,
|
||||||
|
max: -1600,
|
||||||
|
graphHeight: 4,
|
||||||
|
nonZeroDecimals: 2,
|
||||||
|
pixelToValueTests: []pixelToValueTest{
|
||||||
|
{15, -1900, false},
|
||||||
|
{14, -1880, false},
|
||||||
|
{13, -1860, false},
|
||||||
|
{12, -1840, false},
|
||||||
|
{11, -1820, false},
|
||||||
|
{10, -1800, false},
|
||||||
|
{9, -1780, false},
|
||||||
|
{8, -1760, false},
|
||||||
|
{7, -1740, false},
|
||||||
|
{6, -1720, false},
|
||||||
|
{5, -1700, false},
|
||||||
|
{4, -1680, false},
|
||||||
|
{3, -1660, false},
|
||||||
|
{2, -1640, false},
|
||||||
|
{1, -1620, false},
|
||||||
|
{0, -1600, false},
|
||||||
|
},
|
||||||
|
valueToPixelTests: []valueToPixelTest{
|
||||||
|
{-1910, 15, true},
|
||||||
|
{-1900, 15, false},
|
||||||
|
{-1880, 14, false},
|
||||||
|
{-1860, 13, false},
|
||||||
|
{-1840, 12, false},
|
||||||
|
{-1820, 11, false},
|
||||||
|
{-1800, 10, false},
|
||||||
|
{-1780, 9, false},
|
||||||
|
{-1760, 8, false},
|
||||||
|
{-1740, 7, false},
|
||||||
|
{-1720, 6, false},
|
||||||
|
{-1700, 5, false},
|
||||||
|
{-1680, 4, false},
|
||||||
|
{-1660, 3, false},
|
||||||
|
{-1640, 2, false},
|
||||||
|
{-1620, 1, false},
|
||||||
|
{-1600, 0, false},
|
||||||
|
{-1590, 0, true},
|
||||||
|
},
|
||||||
|
cellLabelTests: []cellLabelTest{
|
||||||
|
{3, NewValue(-1900, 2), false},
|
||||||
|
{2, NewValue(-1820, 2), false},
|
||||||
|
{1, NewValue(-1740, 2), false},
|
||||||
|
{0, NewValue(-1660, 2), false},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "regression for #92, negative and positive values",
|
||||||
|
min: -100,
|
||||||
|
max: 200,
|
||||||
|
graphHeight: 4,
|
||||||
|
nonZeroDecimals: 2,
|
||||||
|
pixelToValueTests: []pixelToValueTest{
|
||||||
|
{15, -100, false},
|
||||||
|
{14, -80, false},
|
||||||
|
{13, -60, false},
|
||||||
|
{12, -40, false},
|
||||||
|
{11, -20, false},
|
||||||
|
{10, 0, false},
|
||||||
|
{9, 20, false},
|
||||||
|
{8, 40, false},
|
||||||
|
{7, 60, false},
|
||||||
|
{6, 80, false},
|
||||||
|
{5, 100, false},
|
||||||
|
{4, 120, false},
|
||||||
|
{3, 140, false},
|
||||||
|
{2, 160, false},
|
||||||
|
{1, 180, false},
|
||||||
|
{0, 200, false},
|
||||||
|
},
|
||||||
|
valueToPixelTests: []valueToPixelTest{
|
||||||
|
{-100, 15, false},
|
||||||
|
{-80, 14, false},
|
||||||
|
{-60, 13, false},
|
||||||
|
{-40, 12, false},
|
||||||
|
{-20, 11, false},
|
||||||
|
{0, 10, false},
|
||||||
|
{20, 9, false},
|
||||||
|
{40, 8, false},
|
||||||
|
{60, 7, false},
|
||||||
|
{80, 6, false},
|
||||||
|
{100, 5, false},
|
||||||
|
{120, 4, false},
|
||||||
|
{140, 3, false},
|
||||||
|
{160, 2, false},
|
||||||
|
{180, 1, false},
|
||||||
|
{200, 0, false},
|
||||||
|
},
|
||||||
|
cellLabelTests: []cellLabelTest{
|
||||||
|
{3, NewValue(-100, 2), false},
|
||||||
|
{2, NewValue(-20, 2), false},
|
||||||
|
{1, NewValue(60, 2), false},
|
||||||
|
{0, NewValue(140, 2), false},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
@ -381,7 +557,7 @@ func TestYScale(t *testing.T) {
|
|||||||
for _, tc := range test.pixelToValueTests {
|
for _, tc := range test.pixelToValueTests {
|
||||||
got, err := scale.PixelToValue(tc.pixel)
|
got, err := scale.PixelToValue(tc.pixel)
|
||||||
if (err != nil) != tc.wantErr {
|
if (err != nil) != tc.wantErr {
|
||||||
t.Errorf("PixelToValue => unexpected error: %v, wantErr: %v", err, tc.wantErr)
|
t.Errorf("PixelToValue(%v) => unexpected error: %v, wantErr: %v", tc.pixel, err, tc.wantErr)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
@ -396,7 +572,7 @@ func TestYScale(t *testing.T) {
|
|||||||
for _, tc := range test.valueToPixelTests {
|
for _, tc := range test.valueToPixelTests {
|
||||||
got, err := scale.ValueToPixel(tc.value)
|
got, err := scale.ValueToPixel(tc.value)
|
||||||
if (err != nil) != tc.wantErr {
|
if (err != nil) != tc.wantErr {
|
||||||
t.Errorf("ValueToPixel => unexpected error: %v, wantErr: %v", err, tc.wantErr)
|
t.Errorf("ValueToPixel(%v) => unexpected error: %v, wantErr: %v", tc.value, err, tc.wantErr)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
@ -411,7 +587,7 @@ func TestYScale(t *testing.T) {
|
|||||||
for _, tc := range test.cellLabelTests {
|
for _, tc := range test.cellLabelTests {
|
||||||
got, err := scale.CellLabel(tc.cell)
|
got, err := scale.CellLabel(tc.cell)
|
||||||
if (err != nil) != tc.wantErr {
|
if (err != nil) != tc.wantErr {
|
||||||
t.Errorf("CellLabel => unexpected error: %v, wantErr: %v", err, tc.wantErr)
|
t.Errorf("CellLabel(%v) => unexpected error: %v, wantErr: %v", tc.cell, err, tc.wantErr)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
|
Loading…
x
Reference in New Issue
Block a user