refactor: enhance painter

This commit is contained in:
vicanso 2022-05-23 21:00:10 +08:00
parent c363d1d5e3
commit ddd5cf6d43
3 changed files with 215 additions and 28 deletions

View file

@ -38,7 +38,7 @@ type Painter struct {
parent *Painter
style Style
previousStyle Style
theme *Theme
theme ColorPalette
}
type PainterOptions struct {
@ -92,7 +92,7 @@ func PainterStyleOption(style Style) PainterOption {
}
// PainterThemeOption sets the theme of draw painter
func PainterThemeOption(theme *Theme) PainterOption {
func PainterThemeOption(theme ColorPalette) PainterOption {
return func(p *Painter) {
if theme == nil {
return
@ -194,6 +194,7 @@ func (p *Painter) SetTextStyle(style Style) {
func (p *Painter) RestoreStyle() {
p.style = p.previousStyle
p.style.WriteToRenderer(p.render)
}
// Bytes returns the data of draw canvas
@ -336,13 +337,7 @@ func (p *Painter) SetStrokeColor(color Color) {
p.render.SetStrokeColor(color)
}
func (p *Painter) LineStroke(points []Point, style LineStyle) {
s := style.Style()
if !s.ShouldDrawStroke() {
return
}
defer p.RestoreStyle()
p.SetDrawingStyle(s.GetStrokeOptions())
func (p *Painter) LineStroke(points []Point) {
for index, point := range points {
x := point.X
y := point.Y
@ -360,8 +355,9 @@ func (p *Painter) SetBackground(width, height int, color Color) {
s := chart.Style{
FillColor: color,
}
defer p.RestoreStyle()
// 背景色
p.SetStyle(s)
defer p.RestoreStyle()
// 设置背景色不使用box因此不直接使用Painter
r.MoveTo(0, 0)
r.LineTo(width, 0)
@ -396,13 +392,8 @@ func (p *Painter) Polygon(center Point, radius float64, sides int) {
p.Stroke()
}
func (p *Painter) FillArea(points []Point, s Style) {
if !s.ShouldDrawFill() {
return
}
defer p.RestoreStyle()
func (p *Painter) FillArea(points []Point) {
var x, y int
p.SetDrawingStyle(s.GetFillOptions())
for index, point := range points {
x = point.X
y = point.Y

View file

@ -99,6 +99,10 @@ func TestPainter(t *testing.T) {
// line stroke
{
fn: func(p *Painter) {
p.SetDrawingStyle(Style{
StrokeColor: drawing.ColorBlack,
StrokeWidth: 1,
})
p.LineStroke([]Point{
{
X: 1,
@ -108,9 +112,6 @@ func TestPainter(t *testing.T) {
X: 3,
Y: 4,
},
}, LineStyle{
StrokeColor: drawing.ColorBlack,
StrokeWidth: 1,
})
},
result: "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"400\" height=\"300\">\\n<path d=\"M 6 12\nL 8 14\" style=\"stroke-width:1;stroke:rgba(0,0,0,1.0);fill:none\"/></svg>",
@ -294,6 +295,14 @@ func TestPainter(t *testing.T) {
// FillArea
{
fn: func(p *Painter) {
p.SetDrawingStyle(Style{
FillColor: drawing.Color{
R: 84,
G: 112,
B: 198,
A: 255,
},
})
p.FillArea([]Point{
{
X: 0,
@ -311,13 +320,6 @@ func TestPainter(t *testing.T) {
X: 0,
Y: 0,
},
}, Style{
FillColor: drawing.Color{
R: 84,
G: 112,
B: 198,
A: 255,
},
})
},
result: "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"400\" height=\"300\">\\n<path d=\"M 5 10\nL 5 110\nL 105 110\nL 5 10\" style=\"stroke-width:0;stroke:none;fill:rgba(84,112,198,1.0)\"/></svg>",

198
theme.go
View file

@ -22,13 +22,20 @@
package charts
import "github.com/wcharczuk/go-chart/v2/drawing"
const ThemeDark = "dark"
const ThemeLight = "light"
const ThemeGrafana = "grafana"
const ThemeAnt = "ant"
type Theme struct {
palette *themeColorPalette
type ColorPalette interface {
IsDark() bool
GetAxisStrokeColor() Color
GetAxisSplitLineColor() Color
GetSeriesColor(int) Color
GetBackgroundColor() Color
GetTextColor() Color
}
type themeColorPalette struct {
@ -39,3 +46,190 @@ type themeColorPalette struct {
textColor Color
seriesColors []Color
}
var palettes = map[string]ColorPalette{}
func init() {
echartSeriesColors := []Color{
parseColor("#5470c6"),
parseColor("#91cc75"),
parseColor("#fac858"),
parseColor("#ee6666"),
parseColor("#73c0de"),
parseColor("#3ba272"),
parseColor("#fc8452"),
parseColor("#9a60b4"),
parseColor("#ea7ccc"),
}
grafanaSeriesColors := []Color{
parseColor("#7EB26D"),
parseColor("#EAB839"),
parseColor("#6ED0E0"),
parseColor("#EF843C"),
parseColor("#E24D42"),
parseColor("#1F78C1"),
parseColor("#705DA0"),
parseColor("#508642"),
}
antSeriesColors := []Color{
parseColor("#5b8ff9"),
parseColor("#5ad8a6"),
parseColor("#5d7092"),
parseColor("#f6bd16"),
parseColor("#6f5ef9"),
parseColor("#6dc8ec"),
parseColor("#945fb9"),
parseColor("#ff9845"),
}
AddTheme(
ThemeDark,
true,
Color{
R: 185,
G: 184,
B: 206,
A: 255,
},
Color{
R: 72,
G: 71,
B: 83,
A: 255,
},
Color{
R: 16,
G: 12,
B: 42,
A: 255,
},
Color{
R: 238,
G: 238,
B: 238,
A: 255,
},
echartSeriesColors,
)
AddTheme(
ThemeLight,
false,
Color{
R: 110,
G: 112,
B: 121,
A: 255,
},
Color{
R: 224,
G: 230,
B: 242,
A: 255,
},
drawing.ColorWhite,
drawing.Color{
R: 70,
G: 70,
B: 70,
A: 255,
},
echartSeriesColors,
)
AddTheme(
ThemeAnt,
false,
Color{
R: 110,
G: 112,
B: 121,
A: 255,
},
Color{
R: 224,
G: 230,
B: 242,
A: 255,
},
drawing.ColorWhite,
drawing.Color{
R: 70,
G: 70,
B: 70,
A: 255,
},
antSeriesColors,
)
AddTheme(
ThemeGrafana,
true,
drawing.Color{
R: 185,
G: 184,
B: 206,
A: 255,
},
drawing.Color{
R: 68,
G: 67,
B: 67,
A: 255,
},
drawing.Color{
R: 31,
G: 29,
B: 29,
A: 255,
},
drawing.Color{
R: 216,
G: 217,
B: 218,
A: 255,
},
grafanaSeriesColors,
)
}
func AddTheme(name string, isDarkMode bool, axisStrokeColor, axisSplitLineColor, backgroundColor, textColor drawing.Color, seriesColors []drawing.Color) {
palettes[name] = &themeColorPalette{
isDarkMode: isDarkMode,
axisStrokeColor: axisStrokeColor,
axisSplitLineColor: axisSplitLineColor,
backgroundColor: backgroundColor,
textColor: textColor,
seriesColors: seriesColors,
}
}
func NewTheme(name string) ColorPalette {
p, ok := palettes[name]
if !ok {
p = palettes[ThemeLight]
}
return p
}
func (t *themeColorPalette) IsDark() bool {
return t.isDarkMode
}
func (t *themeColorPalette) GetAxisStrokeColor() Color {
return t.axisStrokeColor
}
func (t *themeColorPalette) GetAxisSplitLineColor() Color {
return t.axisSplitLineColor
}
func (t *themeColorPalette) GetSeriesColor(index int) Color {
colors := t.seriesColors
return colors[index%len(colors)]
}
func (t *themeColorPalette) GetBackgroundColor() Color {
return t.backgroundColor
}
func (t *themeColorPalette) GetTextColor() Color {
return t.textColor
}