diff --git a/color.go b/color.go index da19c8c..afb9fed 100644 --- a/color.go +++ b/color.go @@ -1,6 +1,7 @@ package charts import ( + "image/color" "math" "strings" @@ -151,7 +152,13 @@ func ColorFromRGBA(color string) Color { return drawing.ColorFromRGBA(color) } -// ColorFromRGBAValues returns the system alpha mixed rgba values. -func ColorFromRGBAValues(r, g, b, a uint32) Color { - return drawing.ColorFromAlphaMixedRGBA(r, g, b, a) +// ColorRGB constructs a fully opaque color with the color specified. +func ColorRGB(r, g, b uint8) Color { + return Color{R: r, G: g, B: b, A: 255} +} + +// ColorConvertGo converts go's built in colors to our Color struct. +// This allows easy use of colors defined in image/colornames. +func ColorConvertGo(c color.RGBA) Color { + return Color{R: c.R, G: c.G, B: c.B, A: c.A} } diff --git a/color_test.go b/color_test.go index d4a7607..06e034f 100644 --- a/color_test.go +++ b/color_test.go @@ -5,6 +5,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "golang.org/x/image/colornames" ) func BenchmarkParseColor(b *testing.B) { @@ -39,7 +40,11 @@ func testColorShades(t *testing.T, colors ...Color) { sampleWidth := p.Width() / len(colors) for i, c := range colors { - p.FilledRect(i*sampleWidth, 0, (i+1)*sampleWidth, p.Height(), + endX := (i + 1) * sampleWidth + if i == len(colors)-1 { + endX = p.Width() // ensure edge is painted + } + p.FilledRect(i*sampleWidth, 0, endX, p.Height(), c, ColorTransparent, 0.0) } @@ -49,19 +54,22 @@ func testColorShades(t *testing.T, colors ...Color) { } func TestGrayColors(t *testing.T) { - testColorShades(t, ColorDarkGray, ColorGray, ColorLightGray) + testColorShades(t, ColorDarkGray, ColorGray, ColorSilver, ColorLightGray, ColorAzure, + ColorSlateGray, ColorLightSlateGray) } func TestBlueColors(t *testing.T) { - testColorShades(t, ColorBlue, ColorBlueAlt1, ColorBlueAlt2) + testColorShades(t, ColorBlue, ColorNavy, ColorBlueAlt1, ColorBlueAlt2, ColorLightSlateGray) } func TestGreenColors(t *testing.T) { - testColorShades(t, ColorGreen, ColorGreenAlt1, ColorGreenAlt2, ColorGreenAlt3, ColorGreenAlt4) + testColorShades(t, ColorGreen, ColorOlive, ColorLime, + ColorGreenAlt1, ColorGreenAlt2, ColorGreenAlt3, ColorGreenAlt4) } func TestRedColors(t *testing.T) { - testColorShades(t, ColorRed, ColorRedAlt1, ColorRedAlt2) + testColorShades(t, ColorRed, ColorPink, ColorSalmon, ColorMaroon, ColorBrown, ColorChocolate, + ColorRedAlt1, ColorRedAlt2) } func TestOrangeColors(t *testing.T) { @@ -69,15 +77,19 @@ func TestOrangeColors(t *testing.T) { } func TestAquaColors(t *testing.T) { - testColorShades(t, ColorAqua, ColorAquaAlt1) + testColorShades(t, ColorAqua, ColorTeal, ColorTurquoise, ColorAquaAlt1) } func TestYellowColors(t *testing.T) { - testColorShades(t, ColorYellow, ColorYellowAlt1) + testColorShades(t, ColorYellow, ColorGold, ColorYellowAlt1) +} + +func TestTanColors(t *testing.T) { + testColorShades(t, ColorAzure, ColorIvory, ColorBeige, ColorKhaki, ColorTan, ColorCoral, ColorSalmon) } func TestPurpleColors(t *testing.T) { - testColorShades(t, ColorPurple, ColorViolet, ColorPlum, ColorFuchsia) + testColorShades(t, ColorPurple, ColorViolet, ColorIndigo, ColorPlum, ColorFuchsia) } func TestIsLightColor(t *testing.T) { @@ -97,6 +109,9 @@ func TestParseColor(t *testing.T) { c := ParseColor("") assert.True(t, c.IsZero()) + c = ParseColor("unknown") + assert.Equal(t, ColorBlack, c) + c = ParseColor("#333") assert.Equal(t, Color{R: 51, G: 51, B: 51, A: 255}, c) @@ -112,3 +127,18 @@ func TestParseColor(t *testing.T) { c = ParseColor("rgba(50,51,52,250)") assert.Equal(t, Color{R: 50, G: 51, B: 52, A: 250}, c) } + +func TestColorConvertGo(t *testing.T) { + t.Parallel() + + goC := colornames.Lavender + ourC := ColorConvertGo(goC) + + goR, goG, goB, goA := goC.RGBA() + ourR, ourG, ourB, ourA := ourC.RGBA() + + assert.Equal(t, goR, ourR) + assert.Equal(t, goG, ourG) + assert.Equal(t, goB, ourB) + assert.Equal(t, goA, ourA) +} diff --git a/examples/table-1/main.go b/examples/table-1/main.go index f787303..020f01a 100644 --- a/examples/table-1/main.go +++ b/examples/table-1/main.go @@ -78,11 +78,11 @@ func main() { panic(err) } - bgColor := charts.Color{R: 28, G: 28, B: 32, A: 255} + bgColor := charts.ColorRGB(28, 28, 32) p, err = charts.TableOptionRenderDirect(charts.TableChartOption{ Header: []string{"Name", "Price", "Change"}, BackgroundColor: bgColor, - HeaderBackgroundColor: charts.Color{R: 80, G: 80, B: 80, A: 255}, + HeaderBackgroundColor: charts.ColorRGB(80, 80, 80), RowBackgroundColors: []charts.Color{bgColor}, HeaderFontColor: charts.ColorWhite, FontStyle: charts.FontStyle{ @@ -127,9 +127,9 @@ func main() { } if value > 0 { - tc.FillColor = charts.Color{R: 179, G: 53, B: 20, A: 255} + tc.FillColor = charts.ColorRGB(179, 53, 20) } else { - tc.FillColor = charts.Color{R: 33, G: 124, B: 50, A: 255} + tc.FillColor = charts.ColorRGB(33, 124, 50) } return tc }, diff --git a/examples/web-1/main.go b/examples/web-1/main.go index b91d9c6..1f539f3 100644 --- a/examples/web-1/main.go +++ b/examples/web-1/main.go @@ -378,11 +378,11 @@ func indexHandler(w http.ResponseWriter, req *http.Request) { YAxis: []charts.YAxisOption{ { Formatter: "{value}ml", - AxisColor: charts.Color{R: 84, G: 112, B: 198, A: 255}, + AxisColor: charts.ColorRGB(84, 112, 198), }, { Formatter: "{value}°C", - AxisColor: charts.Color{R: 250, G: 200, B: 88, A: 255}, + AxisColor: charts.ColorRGB(250, 200, 88), }, }, SeriesList: append(charts.NewSeriesListBar([][]float64{ diff --git a/painter_test.go b/painter_test.go index b94f79b..46f9b26 100644 --- a/painter_test.go +++ b/painter_test.go @@ -266,7 +266,7 @@ func TestPainterExternal(t *testing.T) { _ = p.LineChart(opt) p = p.Child(PainterBoxOption(chartdraw.NewBox(0, 200, 400, 200))) opt = makeMinimalLineChartOption() - opt.Theme = GetDefaultTheme().WithBackgroundColor(ColorFromRGBAValues(0, 0, 0, 0)) + opt.Theme = GetDefaultTheme().WithBackgroundColor(ColorTransparent) _ = p.LineChart(opt) }, result: "14401280112096080064048032016001.44k1.28k1.12k9608006404803201600",