From 3718ae07e8cd93f768114a3bf71ce45928982b36 Mon Sep 17 00:00:00 2001 From: susiwen8 Date: Sat, 6 Feb 2021 19:49:53 +0800 Subject: [PATCH 1/7] Feat: add polar bar --- README.md | 2 +- README_CN.md | 2 +- charts/bar.go | 4 ++-- charts/base.go | 47 +++++++++++++++++++++++++++++++++++++---------- charts/series.go | 6 ++++++ opts/charts.go | 5 +++++ opts/global.go | 18 +++++++++++++++++- 7 files changed, 69 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 8f3f3369d..0afcca3a8 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ > If a language can be used to build web scrapers, it definitely needs to provide a graceful data visualization library. --- by dongdong. -In the Golang ecosystem, there are not many choices for data visualization libraries. The development of [go-echarts](https://github.com/go-echarts/go-echarts) aims to provide a simple yet powerful data visualization library for Golang. [Echarts](https://echarts.apache.org/) is an outstanding charting and visualization library opensourced by Baidu, it supports adorable chart types and various interactive features. There are many language bindings for Echarts, for example, [pyecharts](https://github.com/pyecharts/pyecharts). go-echarts learns from pyecharts and has evolved a lot. +In the Golang ecosystem, there are not many choices for data visualization libraries. The development of [go-echarts](https://github.com/go-echarts/go-echarts) aims to provide a simple yet powerful data visualization library for Golang. [Apache ECharts](https://echarts.apache.org/) is an outstanding charting and visualization library, it supports adorable chart types and various interactive features. There are many language bindings for Echarts, for example, [pyecharts](https://github.com/pyecharts/pyecharts). go-echarts learns from pyecharts and has evolved a lot. [中文 README](README_CN.md) diff --git a/README_CN.md b/README_CN.md index 6b71dcfe7..2b0e1b4df 100644 --- a/README_CN.md +++ b/README_CN.md @@ -27,7 +27,7 @@ > 如果一门语言可以用来写爬虫,那么它就需要一个优雅的数据可视化库。 --- by dongdong -在 Golang 这门语言中,目前数据可视化的第三方库还是特别少,[go-echarts](https://github.com/go-echarts/go-echarts) 的开发就是为了填补这部分的空隙。[Echarts](http://echarts.apche.com/) 是百度开源的非常优秀的可视化图表库,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可。也有其他语言为其实现了相应语言版本的接口,如 Python 的 [pyecharts](https://github.com/pyecharts/pyecharts),go-echarts 也是借鉴了 pyecharts 的一些设计思想。 +在 Golang 这门语言中,目前数据可视化的第三方库还是特别少,[go-echarts](https://github.com/go-echarts/go-echarts) 的开发就是为了填补这部分的空隙。[Apache ECharts](http://echarts.apache.org/) 是非常优秀的可视化图表库,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可。也有其他语言为其实现了相应语言版本的接口,如 Python 的 [pyecharts](https://github.com/pyecharts/pyecharts),go-echarts 也是借鉴了 pyecharts 的一些设计思想。 ### 🔰 安装 diff --git a/charts/bar.go b/charts/bar.go index a4c884bd1..6c1c11b4e 100644 --- a/charts/bar.go +++ b/charts/bar.go @@ -17,11 +17,11 @@ type Bar struct { func (Bar) Type() string { return types.ChartBar } // NewBar creates a new bar chart instance. -func NewBar() *Bar { +func NewBar(hasXYAxis bool) *Bar { c := &Bar{} c.initBaseConfiguration() c.Renderer = render.NewChartRender(c, c.Validate) - c.hasXYAxis = true + c.hasXYAxis = hasXYAxis return c } diff --git a/charts/base.go b/charts/base.go index a922d5bcb..09db22db9 100644 --- a/charts/base.go +++ b/charts/base.go @@ -11,10 +11,13 @@ type GlobalOpts func(bc *BaseConfiguration) // BaseConfiguration represents an option set needed by all chart types. type BaseConfiguration struct { - opts.Legend `json:"legend"` - opts.Tooltip `json:"tooltip"` - opts.Toolbox `json:"toolbox"` - opts.Title `json:"title"` + opts.Legend `json:"legend"` + opts.Tooltip `json:"tooltip"` + opts.Toolbox `json:"toolbox"` + opts.Title `json:"title"` + opts.Polar `json:"polar"` + opts.AngleAxis `json:"angleAxis"` + opts.RadiusAxis `json:"radiusAxis"` render.Renderer `json:"-"` opts.Initialization `json:"-"` @@ -60,10 +63,13 @@ type BaseConfiguration struct { // bs, _ : = json.Marshal(bar.JSON()) func (bc *BaseConfiguration) JSON() map[string]interface{} { obj := map[string]interface{}{ - "title": bc.Title, - "legend": bc.Legend, - "tooltip": bc.Tooltip, - "series": bc.MultiSeries, + "title": bc.Title, + "legend": bc.Legend, + "tooltip": bc.Tooltip, + "series": bc.MultiSeries, + "polar": bc.Polar, + "angleAxis": bc.AngleAxis, + "radiusAxis": bc.RadiusAxis, } if bc.hasGeo { @@ -132,8 +138,8 @@ func (bc *BaseConfiguration) initBaseConfiguration() { func (bc *BaseConfiguration) initSeriesColors() { bc.Colors = []string{ - "#c23531", "#2f4554", "#61a0a8", "#d48265", "#91c7ae", - "#749f83", "#ca8622", "#bda29a", "#6e7074", "#546570", + "#5470c6", "#91cc75", "#fac858", "#ee6666", "#73c0de", + "#3ba272", "#fc8452", "#9a60b4", "#ea7ccc", } } @@ -152,6 +158,27 @@ func (bc *BaseConfiguration) setBaseGlobalOptions(opts ...GlobalOpts) { } } +// WithPolarOps set angleAxis +func WithAngleAxisOps(opt opts.AngleAxis) GlobalOpts { + return func(bc *BaseConfiguration) { + bc.AngleAxis = opt + } +} + +// WithPolarOps set radiusAxis +func WithRadiusAxisOps(opt opts.RadiusAxis) GlobalOpts { + return func(bc *BaseConfiguration) { + bc.RadiusAxis = opt + } +} + +// WithPolarOps set polar +func WithPolarOps(opt opts.Polar) GlobalOpts { + return func(bc *BaseConfiguration) { + bc.Polar = opt + } +} + // WithTitleOpts func WithTitleOpts(opt opts.Title) GlobalOpts { return func(bc *BaseConfiguration) { diff --git a/charts/series.go b/charts/series.go index 78831cd85..2a2d5908c 100644 --- a/charts/series.go +++ b/charts/series.go @@ -14,6 +14,8 @@ type SingleSeries struct { // Bar BarGap string `json:"barGap,omitempty"` BarCategoryGap string `json:"barCategoryGap,omitempty"` + ShowBackground bool `json:"showBackground,omitempty"` + RoundCap bool `json:"roundCap,omitempty"` // Bar3D Shading string `json:"shading,omitempty"` @@ -121,6 +123,10 @@ func WithBarChartOpts(opt opts.BarChart) SeriesOpts { s.BarCategoryGap = opt.BarCategoryGap s.XAxisIndex = opt.XAxisIndex s.YAxisIndex = opt.YAxisIndex + s.ShowBackground = opt.ShowBackground + s.RoundCap = opt.RoundCap + s.CoordSystem = opt.CoordSystem + s.Type = opt.Type } } diff --git a/opts/charts.go b/opts/charts.go index 6fc3a197e..769a6440d 100644 --- a/opts/charts.go +++ b/opts/charts.go @@ -3,6 +3,7 @@ package opts // BarChart // https://echarts.apache.org/en/option.html#series-bar type BarChart struct { + Type string // Name of stack. On the same category axis, the series with the // same stack name would be put on top of each other. Stack string @@ -28,6 +29,10 @@ type BarChart struct { // Index of y axis to combine with, which is useful for multiple y axes in one chart. YAxisIndex int + + ShowBackground bool + RoundCap bool + CoordSystem string } // BarData diff --git a/opts/global.go b/opts/global.go index 01998969d..0fc2fdd30 100644 --- a/opts/global.go +++ b/opts/global.go @@ -34,7 +34,7 @@ type Initialization struct { ChartID string // Assets host - AssetsHost string `default:"https://go-echarts.github.io/go-echarts-assets/assets/"` + AssetsHost string `default:"https://cdn.jsdelivr.net/npm/echarts@5.0.2/dist/"` // Theme of chart Theme string `default:"white"` @@ -915,6 +915,22 @@ type ParallelAxis struct { Data interface{} `json:"data,omitempty"` } +type Polar struct { + ID string `json:"id,omitempty"` + Zlevel int `json:"zlevel,omitempty"` + z int +} + +type AngleAxis struct { + StartAngle int `json:"startAngle,omitempty"` + Clockwise bool `json:"clockwise,omitempty"` +} + +type RadiusAxis struct { + Type string `json:"type,omitempty"` + Z int `json:"z,omitempty"` +} + var funcPat = regexp.MustCompile(`\n|\t`) const funcMarker = "__f__" From c4a2ea568b6014810662a4c9e29e41dc14c63a57 Mon Sep 17 00:00:00 2001 From: susiwen8 Date: Sun, 7 Feb 2021 13:20:24 +0800 Subject: [PATCH 2/7] Feat: seperate polar bar from bar --- charts/bar.go | 4 ++-- charts/polarBar.go | 36 ++++++++++++++++++++++++++++++++++++ opts/global.go | 43 +++++++++++++++++++++++++++++++++++-------- 3 files changed, 73 insertions(+), 10 deletions(-) create mode 100644 charts/polarBar.go diff --git a/charts/bar.go b/charts/bar.go index 6c1c11b4e..a4c884bd1 100644 --- a/charts/bar.go +++ b/charts/bar.go @@ -17,11 +17,11 @@ type Bar struct { func (Bar) Type() string { return types.ChartBar } // NewBar creates a new bar chart instance. -func NewBar(hasXYAxis bool) *Bar { +func NewBar() *Bar { c := &Bar{} c.initBaseConfiguration() c.Renderer = render.NewChartRender(c, c.Validate) - c.hasXYAxis = hasXYAxis + c.hasXYAxis = true return c } diff --git a/charts/polarBar.go b/charts/polarBar.go new file mode 100644 index 000000000..e1736c243 --- /dev/null +++ b/charts/polarBar.go @@ -0,0 +1,36 @@ +package charts + +import ( + "github.com/go-echarts/go-echarts/v2/opts" + "github.com/go-echarts/go-echarts/v2/render" + "github.com/go-echarts/go-echarts/v2/types" +) + +// PolarBar represents a polar bar chart. +type PolarBar struct { + RectChart +} + +// Type returns the chart type. +func (PolarBar) Type() string { return types.ChartBar } + +// NewPolarBar creates a new bar chart instance. +func NewPolarBar() *PolarBar { + c := &PolarBar{} + c.initBaseConfiguration() + c.Renderer = render.NewChartRender(c, c.Validate) + return c +} + +// AddSeries adds the new series. +func (c *PolarBar) AddSeries(name string, data []opts.BarData, options ...SeriesOpts) *PolarBar { + series := SingleSeries{Name: name, Type: types.ChartBar, Data: data} + series.configureSeriesOpts(options...) + c.MultiSeries = append(c.MultiSeries, series) + return c +} + +// Validate validates the given configuration. +func (c *PolarBar) Validate() { + c.Assets.Validate(c.AssetsHost) +} diff --git a/opts/global.go b/opts/global.go index 0fc2fdd30..1599ca794 100644 --- a/opts/global.go +++ b/opts/global.go @@ -34,7 +34,7 @@ type Initialization struct { ChartID string // Assets host - AssetsHost string `default:"https://cdn.jsdelivr.net/npm/echarts@5.0.2/dist/"` + AssetsHost string `default:"https://go-echarts.github.io/go-echarts-assets/assets/"` // Theme of chart Theme string `default:"white"` @@ -915,20 +915,47 @@ type ParallelAxis struct { Data interface{} `json:"data,omitempty"` } +// Polar Bar options type Polar struct { - ID string `json:"id,omitempty"` - Zlevel int `json:"zlevel,omitempty"` - z int + ID string `json:"id,omitempty"` + Zlevel int `json:"zlevel,omitempty"` + Z int `json:"z,omitempty"` + Center [2]string `json:"center,omitempty"` + Radius [2]string `json:"radius,omitempty"` + Tooltip Tooltip `json:"tooltip,omitempty"` +} + +type PolarAxisBase struct { + ID string `json:"id,omitempty"` + PolarIndex int `json:"polarIndex,omitempty"` + StartAngle float64 `json:"startAngle,omitempty"` + Type string `json:"type,omitempty"` + BoundaryGap bool `json:"boundaryGap,omitempty"` + Min float64 `json:"min,omitempty"` + Max float64 `json:"max,omitempty"` + Scale bool `json:"scale,omitempty"` + SplitNumber int `json:"splitNumber,omitempty"` + MinInterval float64 `json:"minInterval,omitempty"` + MaxInterval float64 `json:"maxInterval,omitempty"` + Interval float64 `json:"interval,omitempty"` + LogBase float64 `json:"logBase,omitempty"` + Silent bool `json:"silent,omitempty"` + TriggerEvent bool `json:"triggerEvent,omitempty"` } type AngleAxis struct { - StartAngle int `json:"startAngle,omitempty"` - Clockwise bool `json:"clockwise,omitempty"` + PolarAxisBase + Clockwise bool `json:"clockwise,omitempty"` } type RadiusAxis struct { - Type string `json:"type,omitempty"` - Z int `json:"z,omitempty"` + PolarAxisBase + Name string `json:"name,omitempty"` + NameLocation string `json:"nameLocation,omitempty"` + NameTextStyle TextStyle `json:"nameTextStyle,omitempty"` + NameGap float64 `json:"nameGap,omitempty"` + NameRadius float64 `json:"nameRotate,omitempty"` + Inverse bool `json:"inverse,omitempty"` } var funcPat = regexp.MustCompile(`\n|\t`) From 80c19946a164e6fafa58f30b962c638f50dde180 Mon Sep 17 00:00:00 2001 From: susiwen8 Date: Sun, 7 Feb 2021 14:50:10 +0800 Subject: [PATCH 3/7] Feat: add `enable` func to enable polar bar --- charts/bar.go | 6 ++++++ charts/polarBar.go | 36 ------------------------------------ 2 files changed, 6 insertions(+), 36 deletions(-) delete mode 100644 charts/polarBar.go diff --git a/charts/bar.go b/charts/bar.go index a4c884bd1..4c543c3eb 100644 --- a/charts/bar.go +++ b/charts/bar.go @@ -25,6 +25,12 @@ func NewBar() *Bar { return c } +// EablePolorType enable polar bar +func (c *Bar) EablePolorType() *Bar { + c.hasXYAxis = false + return c +} + // SetXAxis sets the X axis. func (c *Bar) SetXAxis(x interface{}) *Bar { c.xAxisData = x diff --git a/charts/polarBar.go b/charts/polarBar.go deleted file mode 100644 index e1736c243..000000000 --- a/charts/polarBar.go +++ /dev/null @@ -1,36 +0,0 @@ -package charts - -import ( - "github.com/go-echarts/go-echarts/v2/opts" - "github.com/go-echarts/go-echarts/v2/render" - "github.com/go-echarts/go-echarts/v2/types" -) - -// PolarBar represents a polar bar chart. -type PolarBar struct { - RectChart -} - -// Type returns the chart type. -func (PolarBar) Type() string { return types.ChartBar } - -// NewPolarBar creates a new bar chart instance. -func NewPolarBar() *PolarBar { - c := &PolarBar{} - c.initBaseConfiguration() - c.Renderer = render.NewChartRender(c, c.Validate) - return c -} - -// AddSeries adds the new series. -func (c *PolarBar) AddSeries(name string, data []opts.BarData, options ...SeriesOpts) *PolarBar { - series := SingleSeries{Name: name, Type: types.ChartBar, Data: data} - series.configureSeriesOpts(options...) - c.MultiSeries = append(c.MultiSeries, series) - return c -} - -// Validate validates the given configuration. -func (c *PolarBar) Validate() { - c.Assets.Validate(c.AssetsHost) -} From f2e4d609acd5f93c0452f97ed4d9fbae3da19a3e Mon Sep 17 00:00:00 2001 From: susiwen8 Date: Sun, 7 Feb 2021 15:00:02 +0800 Subject: [PATCH 4/7] Fix: avoid unnecessary option added into global --- charts/bar.go | 1 + charts/base.go | 18 +++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/charts/bar.go b/charts/bar.go index 4c543c3eb..b3b0c48c9 100644 --- a/charts/bar.go +++ b/charts/bar.go @@ -28,6 +28,7 @@ func NewBar() *Bar { // EablePolorType enable polar bar func (c *Bar) EablePolorType() *Bar { c.hasXYAxis = false + c.hasPolar = true return c } diff --git a/charts/base.go b/charts/base.go index 09db22db9..41ee23987 100644 --- a/charts/base.go +++ b/charts/base.go @@ -55,6 +55,7 @@ type BaseConfiguration struct { hasRadar bool hasParallel bool hasSingleAxis bool + hasPolar bool } // JSON wraps all the options to a map so that it could be used in the base template @@ -63,13 +64,16 @@ type BaseConfiguration struct { // bs, _ : = json.Marshal(bar.JSON()) func (bc *BaseConfiguration) JSON() map[string]interface{} { obj := map[string]interface{}{ - "title": bc.Title, - "legend": bc.Legend, - "tooltip": bc.Tooltip, - "series": bc.MultiSeries, - "polar": bc.Polar, - "angleAxis": bc.AngleAxis, - "radiusAxis": bc.RadiusAxis, + "title": bc.Title, + "legend": bc.Legend, + "tooltip": bc.Tooltip, + "series": bc.MultiSeries, + } + + if bc.hasPolar { + obj["polar"] = bc.Polar + obj["angleAxis"] = bc.AngleAxis + obj["radiusAxis"] = bc.RadiusAxis } if bc.hasGeo { From bb6afb642322192a5a5f5ff6a3ce9222f25ab300 Mon Sep 17 00:00:00 2001 From: susiwen8 Date: Sun, 7 Feb 2021 15:08:11 +0800 Subject: [PATCH 5/7] chore: typo --- charts/bar.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/bar.go b/charts/bar.go index b3b0c48c9..3e1d3953b 100644 --- a/charts/bar.go +++ b/charts/bar.go @@ -25,8 +25,8 @@ func NewBar() *Bar { return c } -// EablePolorType enable polar bar -func (c *Bar) EablePolorType() *Bar { +// EablePolarType enable polar bar +func (c *Bar) EablePolarType() *Bar { c.hasXYAxis = false c.hasPolar = true return c From 65e52e13c05f76bf307dc2f5cc2b573a0c9f3aae Mon Sep 17 00:00:00 2001 From: susiwen8 Date: Sun, 7 Feb 2021 15:28:37 +0800 Subject: [PATCH 6/7] Fix: built in theme don't need extra js --- charts/base.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/charts/base.go b/charts/base.go index 41ee23987..e115eae0f 100644 --- a/charts/base.go +++ b/charts/base.go @@ -222,7 +222,9 @@ func WithLegendOpts(opt opts.Legend) GlobalOpts { func WithInitializationOpts(opt opts.Initialization) GlobalOpts { return func(bc *BaseConfiguration) { bc.Initialization = opt - if bc.Initialization.Theme != "" { + if bc.Initialization.Theme != "" && + bc.Initialization.Theme != "white" && + bc.Initialization.Theme != "dark" { bc.JSAssets.Add("themes/" + opt.Theme + ".js") } bc.Initialization.Validate() From 8837912c4100d0f775a4ce9646a4271a38636ba2 Mon Sep 17 00:00:00 2001 From: susiwen8 Date: Sun, 7 Feb 2021 18:00:32 +0800 Subject: [PATCH 7/7] chore: typo --- charts/bar.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/bar.go b/charts/bar.go index 3e1d3953b..56809bdef 100644 --- a/charts/bar.go +++ b/charts/bar.go @@ -25,8 +25,8 @@ func NewBar() *Bar { return c } -// EablePolarType enable polar bar -func (c *Bar) EablePolarType() *Bar { +// EnablePolarType enable polar bar +func (c *Bar) EnablePolarType() *Bar { c.hasXYAxis = false c.hasPolar = true return c