diff --git a/assets/go-charts.png b/assets/go-charts.png index f556abf..12d0cad 100644 Binary files a/assets/go-charts.png and b/assets/go-charts.png differ diff --git a/assets/go-line-chart.png b/assets/go-line-chart.png new file mode 100644 index 0000000..71c9eb1 Binary files /dev/null and b/assets/go-line-chart.png differ diff --git a/examples/demo/main.go b/examples/demo/main.go index 4ab6b04..e10c7c0 100644 --- a/examples/demo/main.go +++ b/examples/demo/main.go @@ -25,7 +25,6 @@ var html = ` padding: 0; } .charts { - width: 810px; margin: 10px auto; overflow: hidden; } diff --git a/theme.go b/theme.go index 23a010c..d5d51cd 100644 --- a/theme.go +++ b/theme.go @@ -22,124 +22,178 @@ package charts -import "github.com/wcharczuk/go-chart/v2/drawing" +import ( + "github.com/wcharczuk/go-chart/v2/drawing" +) const ThemeDark = "dark" const ThemeLight = "light" +const ThemeGrafana = "grafana" type Theme struct { - mode string + palette *themeColorPalette } -func NewTheme(mode string) *Theme { - return &Theme{ - mode: mode, +type themeColorPalette struct { + isDarkMode bool + axisStrokeColor drawing.Color + axisSplitLineColor drawing.Color + backgroundColor drawing.Color + textColor drawing.Color + seriesColors []drawing.Color +} + +var palettes = map[string]*themeColorPalette{} + +func init() { + echartSeriesColors := []drawing.Color{ + parseColor("#5470c6"), + parseColor("#91cc75"), + parseColor("#fac858"), + parseColor("#ee6666"), + parseColor("#73c0de"), + parseColor("#3ba272"), + parseColor("#fc8452"), + parseColor("#9a60b4"), + parseColor("#ea7ccc"), } -} - -func (t *Theme) IsDark() bool { - return t.mode == ThemeDark -} - -func (t *Theme) GetAxisStrokeColor() drawing.Color { - if t.IsDark() { - return drawing.Color{ + grafanaSeriesColors := []drawing.Color{ + parseColor("#7EB26D"), + parseColor("#EAB839"), + parseColor("#6ED0E0"), + parseColor("#EF843C"), + parseColor("#E24D42"), + parseColor("#1F78C1"), + parseColor("#705DA0"), + parseColor("#508642"), + } + AddTheme( + ThemeDark, + true, + drawing.Color{ R: 185, G: 184, B: 206, A: 255, - } - } - return drawing.Color{ - R: 110, - G: 112, - B: 121, - A: 255, - } -} - -func (t *Theme) GetAxisSplitLineColor() drawing.Color { - if t.IsDark() { - return drawing.Color{ + }, + drawing.Color{ R: 72, G: 71, B: 83, A: 255, - } - } - return drawing.Color{ - R: 224, - G: 230, - B: 242, - A: 255, - } -} - -func (t *Theme) GetSeriesColor(index int) drawing.Color { - colors := t.GetSeriesColors() - return colors[index%len(colors)] -} - -func (t *Theme) GetSeriesColors() []drawing.Color { - return []drawing.Color{ - { - R: 84, - G: 112, - B: 198, - A: 255, }, - { - R: 145, - G: 204, - B: 117, - A: 255, - }, - { - R: 250, - G: 200, - B: 88, - A: 255, - }, - { - R: 238, - G: 102, - B: 102, - A: 255, - }, - { - R: 115, - G: 192, - B: 222, - A: 255, - }, - } -} - -func (t *Theme) GetBackgroundColor() drawing.Color { - if t.IsDark() { - return drawing.Color{ + drawing.Color{ R: 16, G: 12, B: 42, A: 255, - } - } - return drawing.ColorWhite -} - -func (t *Theme) GetTextColor() drawing.Color { - if t.IsDark() { - return drawing.Color{ + }, + drawing.Color{ R: 238, G: 238, B: 238, A: 255, - } - } - return drawing.Color{ - R: 70, - G: 70, - B: 70, - A: 255, + }, + echartSeriesColors, + ) + + AddTheme( + ThemeLight, + false, + drawing.Color{ + R: 110, + G: 112, + B: 121, + A: 255, + }, + drawing.Color{ + R: 224, + G: 230, + B: 242, + A: 255, + }, + drawing.ColorWhite, + drawing.Color{ + R: 70, + G: 70, + B: 70, + A: 255, + }, + echartSeriesColors, + ) + 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) *Theme { + p, ok := palettes[name] + if !ok { + p = palettes[ThemeLight] + } + return &Theme{ + palette: p, + } +} + +func (t *Theme) IsDark() bool { + return t.palette.isDarkMode +} + +func (t *Theme) GetAxisStrokeColor() drawing.Color { + return t.palette.axisStrokeColor +} + +func (t *Theme) GetAxisSplitLineColor() drawing.Color { + return t.palette.axisSplitLineColor +} + +func (t *Theme) GetSeriesColor(index int) drawing.Color { + colors := t.palette.seriesColors + return colors[index%len(colors)] +} + +func (t *Theme) GetBackgroundColor() drawing.Color { + return t.palette.backgroundColor +} + +func (t *Theme) GetTextColor() drawing.Color { + return t.palette.textColor +} diff --git a/theme_test.go b/theme_test.go index 7caf273..bf22afd 100644 --- a/theme_test.go +++ b/theme_test.go @@ -64,71 +64,6 @@ func TestTheme(t *testing.T) { A: 255, }, lightTheme.GetAxisSplitLineColor()) - assert.Equal([]drawing.Color{ - { - R: 84, - G: 112, - B: 198, - A: 255, - }, - { - R: 145, - G: 204, - B: 117, - A: 255, - }, - { - R: 250, - G: 200, - B: 88, - A: 255, - }, - { - R: 238, - G: 102, - B: 102, - A: 255, - }, - { - R: 115, - G: 192, - B: 222, - A: 255, - }, - }, darkTheme.GetSeriesColors()) - assert.Equal([]drawing.Color{ - { - R: 84, - G: 112, - B: 198, - A: 255, - }, - { - R: 145, - G: 204, - B: 117, - A: 255, - }, - { - R: 250, - G: 200, - B: 88, - A: 255, - }, - { - R: 238, - G: 102, - B: 102, - A: 255, - }, - { - R: 115, - G: 192, - B: 222, - A: 255, - }, - }, lightTheme.GetSeriesColors()) - assert.Equal(drawing.Color{ R: 16, G: 12,