diff --git a/Makefile b/Makefile index 3836c65..cc16258 100644 --- a/Makefile +++ b/Makefile @@ -2,3 +2,8 @@ all: test test: @go test ./... + +cover: + @go test -short -covermode=set -coverprofile=profile.cov + @go tool cover -html=profile.cov + @rm profile.cov \ No newline at end of file diff --git a/box.go b/box.go index 3af4e79..5df34e0 100644 --- a/box.go +++ b/box.go @@ -185,25 +185,12 @@ func (b Box) Fit(other Box) Box { // more literally like the opposite of grow. func (b Box) Constrain(other Box) Box { newBox := b.Clone() - if other.Top < b.Top { - delta := b.Top - other.Top - newBox.Top = other.Top + delta - } - if other.Left < b.Left { - delta := b.Left - other.Left - newBox.Left = other.Left + delta - } + newBox.Top = MaxInt(newBox.Top, other.Top) + newBox.Left = MaxInt(newBox.Left, other.Left) + newBox.Right = MinInt(newBox.Right, other.Right) + newBox.Bottom = MinInt(newBox.Bottom, other.Bottom) - if other.Right > b.Right { - delta := other.Right - b.Right - newBox.Right = other.Right - delta - } - - if other.Bottom > b.Bottom { - delta := other.Bottom - b.Bottom - newBox.Bottom = other.Bottom - delta - } return newBox } diff --git a/box_test.go b/box_test.go index 84787e8..fa95468 100644 --- a/box_test.go +++ b/box_test.go @@ -86,6 +86,26 @@ func TestBoxFit(t *testing.T) { assert.True(math.Abs(c.Aspect()-fac.Aspect()) < 0.02) } +func TestBoxConstrain(t *testing.T) { + assert := assert.New(t) + + a := Box{Top: 64, Left: 64, Right: 192, Bottom: 192} + b := Box{Top: 16, Left: 16, Right: 256, Bottom: 170} + c := Box{Top: 16, Left: 16, Right: 170, Bottom: 256} + + cab := a.Constrain(b) + assert.Equal(64, cab.Top) + assert.Equal(64, cab.Left) + assert.Equal(192, cab.Right) + assert.Equal(170, cab.Bottom) + + cac := a.Constrain(c) + assert.Equal(64, cac.Top) + assert.Equal(64, cac.Left) + assert.Equal(170, cac.Right) + assert.Equal(192, cac.Bottom) +} + func TestBoxOuterConstrain(t *testing.T) { assert := assert.New(t) diff --git a/continuous_series_test.go b/continuous_series_test.go new file mode 100644 index 0000000..df2e3b8 --- /dev/null +++ b/continuous_series_test.go @@ -0,0 +1,31 @@ +package chart + +import ( + "testing" + + assert "github.com/blendlabs/go-assert" +) + +func TestContinuousSeries(t *testing.T) { + assert := assert.New(t) + + cs := ContinuousSeries{ + Name: "Test Series", + XValues: Seq(1.0, 10.0), + YValues: Seq(1.0, 10.0), + } + + assert.Equal("Test Series", cs.GetName()) + assert.Equal(10, cs.Len()) + x0, y0 := cs.GetValue(0) + assert.Equal(1.0, x0) + assert.Equal(1.0, y0) + + xn, yn := cs.GetValue(9) + assert.Equal(10.0, xn) + assert.Equal(10.0, yn) + + xn, yn = cs.GetLastValue() + assert.Equal(10.0, xn) + assert.Equal(10.0, yn) +} diff --git a/histogram_series_test.go b/histogram_series_test.go new file mode 100644 index 0000000..80a2fec --- /dev/null +++ b/histogram_series_test.go @@ -0,0 +1,31 @@ +package chart + +import ( + "testing" + + assert "github.com/blendlabs/go-assert" +) + +func TestHistogramSeries(t *testing.T) { + assert := assert.New(t) + + cs := ContinuousSeries{ + Name: "Test Series", + XValues: Seq(1.0, 20.0), + YValues: Seq(10.0, -10.0), + } + + hs := HistogramSeries{ + InnerSeries: cs, + } + + for x := 0; x < hs.Len(); x++ { + csx, csy := cs.GetValue(0) + hsx, hsy1, hsy2 := hs.GetBoundedValue(0) + assert.Equal(csx, hsx) + assert.True(hsy1 > 0) + assert.True(hsy2 <= 0) + assert.True(csy < 0 || (csy > 0 && csy == hsy1)) + assert.True(csy > 0 || (csy < 0 && csy == hsy2)) + } +} diff --git a/util_test.go b/util_test.go index c50ffa7..d3cd9c3 100644 --- a/util_test.go +++ b/util_test.go @@ -84,6 +84,20 @@ func TestGetRoundToForDelta(t *testing.T) { assert.Equal(1.0, GetRoundToForDelta(11.00)) } +func TestRoundUp(t *testing.T) { + assert := assert.New(t) + assert.Equal(0.5, RoundUp(0.49, 0.1)) + assert.Equal(1.0, RoundUp(0.51, 1.0)) + assert.Equal(0.4999, RoundUp(0.49988, 0.0001)) +} + +func TestRoundDown(t *testing.T) { + assert := assert.New(t) + assert.Equal(0.5, RoundDown(0.51, 0.1)) + assert.Equal(1.0, RoundDown(1.01, 1.0)) + assert.Equal(0.5001, RoundDown(0.50011, 0.0001)) +} + func TestSeq(t *testing.T) { assert := assert.New(t) @@ -101,6 +115,16 @@ func TestPercentDifference(t *testing.T) { assert.Equal(-0.5, PercentDifference(2.0, 1.0)) } +func TestNormalize(t *testing.T) { + assert := assert.New(t) + + values := []float64{10, 9, 8, 7, 6} + normalized := Normalize(values...) + assert.Len(normalized, 5) + assert.Equal(0.25, normalized[0]) + assert.Equal(0.15, normalized[4]) +} + var ( _degreesToRadians = map[float64]float64{ 0: 0, // !_2pi b/c no irrational nums in floats. diff --git a/value.go b/value.go index 0a2a27d..acae226 100644 --- a/value.go +++ b/value.go @@ -32,7 +32,7 @@ func (vs Values) Normalize() []Value { output[index] = Value{ Style: v.Style, Label: v.Label, - Value: (v.Value / total), + Value: RoundDown(v.Value/total, 0.001), } } return output diff --git a/value_test.go b/value_test.go new file mode 100644 index 0000000..f13a916 --- /dev/null +++ b/value_test.go @@ -0,0 +1,69 @@ +package chart + +import ( + "testing" + + assert "github.com/blendlabs/go-assert" +) + +func TestValuesValues(t *testing.T) { + assert := assert.New(t) + + vs := []Value{ + {Value: 10, Label: "Blue"}, + {Value: 9, Label: "Green"}, + {Value: 8, Label: "Gray"}, + {Value: 7, Label: "Orange"}, + {Value: 6, Label: "HEANG"}, + {Value: 5, Label: "??"}, + {Value: 2, Label: "!!"}, + } + + values := Values(vs).Values() + assert.Len(values, 7) + assert.Equal(10, values[0]) + assert.Equal(9, values[1]) + assert.Equal(8, values[2]) + assert.Equal(7, values[3]) + assert.Equal(6, values[4]) + assert.Equal(5, values[5]) + assert.Equal(2, values[6]) +} + +func TestValuesValuesNormalized(t *testing.T) { + assert := assert.New(t) + + vs := []Value{ + {Value: 10, Label: "Blue"}, + {Value: 9, Label: "Green"}, + {Value: 8, Label: "Gray"}, + {Value: 7, Label: "Orange"}, + {Value: 6, Label: "HEANG"}, + {Value: 5, Label: "??"}, + {Value: 2, Label: "!!"}, + } + + values := Values(vs).ValuesNormalized() + assert.Len(values, 7) + assert.Equal(0.212, values[0]) + assert.Equal(0.042, values[6]) +} + +func TestValuesNormalize(t *testing.T) { + assert := assert.New(t) + + vs := []Value{ + {Value: 10, Label: "Blue"}, + {Value: 9, Label: "Green"}, + {Value: 8, Label: "Gray"}, + {Value: 7, Label: "Orange"}, + {Value: 6, Label: "HEANG"}, + {Value: 5, Label: "??"}, + {Value: 2, Label: "!!"}, + } + + values := Values(vs).Normalize() + assert.Len(values, 7) + assert.Equal(0.212, values[0].Value) + assert.Equal(0.042, values[6].Value) +} diff --git a/xaxis_test.go b/xaxis_test.go index 407d02d..8b749da 100644 --- a/xaxis_test.go +++ b/xaxis_test.go @@ -47,3 +47,21 @@ func TestXAxisGetTicksWithUserDefaults(t *testing.T) { ticks := xa.GetTicks(r, xr, styleDefaults, vf) assert.Len(ticks, 1) } + +func TestXAxisMeasure(t *testing.T) { + assert := assert.New(t) + + f, err := GetDefaultFont() + assert.Nil(err) + style := Style{ + Font: f, + FontSize: 10.0, + } + r, err := PNG(100, 100) + assert.Nil(err) + ticks := []Tick{{Value: 1.0, Label: "1.0"}, {Value: 2.0, Label: "2.0"}, {Value: 3.0, Label: "3.0"}} + xa := XAxis{} + xab := xa.Measure(r, Box{0, 0, 100, 100}, &ContinuousRange{Min: 1.0, Max: 3.0, Domain: 100}, style, ticks) + assert.Equal(122, xab.Width()) + assert.Equal(21, xab.Height()) +}