refactor: enhance chart render function
This commit is contained in:
parent
65a1cb11ad
commit
38c4978e44
20 changed files with 665 additions and 462 deletions
32
README.md
32
README.md
|
|
@ -49,25 +49,21 @@ func writeFile(file string, buf []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func chartsRender() ([]byte, error) {
|
func chartsRender() ([]byte, error) {
|
||||||
d, err := charts.LineRender([][]float64{
|
values := [][]float64{
|
||||||
{
|
{
|
||||||
150,
|
120,
|
||||||
|
132,
|
||||||
|
101,
|
||||||
|
134,
|
||||||
|
90,
|
||||||
230,
|
230,
|
||||||
224,
|
210,
|
||||||
218,
|
|
||||||
135,
|
|
||||||
147,
|
|
||||||
260,
|
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
// output type
|
p, err := charts.LineRender(
|
||||||
charts.PNGTypeOption(),
|
values,
|
||||||
// title
|
charts.TitleTextOptionFunc("Line"),
|
||||||
charts.TitleOptionFunc(charts.TitleOption{
|
charts.XAxisDataOptionFunc([]string{
|
||||||
Text: "Line",
|
|
||||||
}),
|
|
||||||
// x axis
|
|
||||||
charts.XAxisOptionFunc(charts.NewXAxisOption([]string{
|
|
||||||
"Mon",
|
"Mon",
|
||||||
"Tue",
|
"Tue",
|
||||||
"Wed",
|
"Wed",
|
||||||
|
|
@ -75,12 +71,12 @@ func chartsRender() ([]byte, error) {
|
||||||
"Fri",
|
"Fri",
|
||||||
"Sat",
|
"Sat",
|
||||||
"Sun",
|
"Sun",
|
||||||
})),
|
}),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return d.Bytes()
|
return p.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
func echartsRender() ([]byte, error) {
|
func echartsRender() ([]byte, error) {
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ type barChart struct {
|
||||||
|
|
||||||
func NewBarChart(p *Painter, opt BarChartOption) *barChart {
|
func NewBarChart(p *Painter, opt BarChartOption) *barChart {
|
||||||
if opt.Theme == nil {
|
if opt.Theme == nil {
|
||||||
opt.Theme = NewTheme("")
|
opt.Theme = defaultTheme
|
||||||
}
|
}
|
||||||
return &barChart{
|
return &barChart{
|
||||||
p: p,
|
p: p,
|
||||||
|
|
|
||||||
238
chart_option.go
238
chart_option.go
|
|
@ -66,6 +66,182 @@ type ChartOption struct {
|
||||||
Children []ChartOption
|
Children []ChartOption
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OptionFunc option function
|
||||||
|
type OptionFunc func(opt *ChartOption)
|
||||||
|
|
||||||
|
// PNGTypeOption set png type of chart's output
|
||||||
|
func PNGTypeOption() OptionFunc {
|
||||||
|
return TypeOptionFunc(ChartOutputPNG)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TypeOptionFunc set type of chart's output
|
||||||
|
func TypeOptionFunc(t string) OptionFunc {
|
||||||
|
return func(opt *ChartOption) {
|
||||||
|
opt.Type = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FontFamilyOptionFunc set font family of chart
|
||||||
|
func FontFamilyOptionFunc(fontFamily string) OptionFunc {
|
||||||
|
return func(opt *ChartOption) {
|
||||||
|
opt.FontFamily = fontFamily
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ThemeOptionFunc set them of chart
|
||||||
|
func ThemeOptionFunc(theme string) OptionFunc {
|
||||||
|
return func(opt *ChartOption) {
|
||||||
|
opt.Theme = theme
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TitleOptionFunc set title of chart
|
||||||
|
func TitleOptionFunc(title TitleOption) OptionFunc {
|
||||||
|
return func(opt *ChartOption) {
|
||||||
|
opt.Title = title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TitleTextOptionFunc set title text of chart
|
||||||
|
func TitleTextOptionFunc(text string) OptionFunc {
|
||||||
|
return func(opt *ChartOption) {
|
||||||
|
opt.Title.Text = text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LegendOptionFunc set legend of chart
|
||||||
|
func LegendOptionFunc(legend LegendOption) OptionFunc {
|
||||||
|
return func(opt *ChartOption) {
|
||||||
|
opt.Legend = legend
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LegendLabelsOptionFunc set legend labels of chart
|
||||||
|
func LegendLabelsOptionFunc(labels []string, left ...string) OptionFunc {
|
||||||
|
return func(opt *ChartOption) {
|
||||||
|
opt.Legend = NewLegendOption(labels, left...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// XAxisOptionFunc set x axis of chart
|
||||||
|
func XAxisOptionFunc(xAxisOption XAxisOption) OptionFunc {
|
||||||
|
return func(opt *ChartOption) {
|
||||||
|
opt.XAxis = xAxisOption
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// XAxisDataOptionFunc set x axis data of chart
|
||||||
|
func XAxisDataOptionFunc(data []string, boundaryGap ...*bool) OptionFunc {
|
||||||
|
return func(opt *ChartOption) {
|
||||||
|
opt.XAxis = NewXAxisOption(data, boundaryGap...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// YAxisOptionFunc set y axis of chart, support two y axis
|
||||||
|
func YAxisOptionFunc(yAxisOption ...YAxisOption) OptionFunc {
|
||||||
|
return func(opt *ChartOption) {
|
||||||
|
opt.YAxisOptions = yAxisOption
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// YAxisDataOptionFunc set y axis data of chart
|
||||||
|
func YAxisDataOptionFunc(data []string) OptionFunc {
|
||||||
|
return func(opt *ChartOption) {
|
||||||
|
opt.YAxisOptions = NewYAxisOptions(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WidthOptionFunc set width of chart
|
||||||
|
func WidthOptionFunc(width int) OptionFunc {
|
||||||
|
return func(opt *ChartOption) {
|
||||||
|
opt.Width = width
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// HeightOptionFunc set height of chart
|
||||||
|
func HeightOptionFunc(height int) OptionFunc {
|
||||||
|
return func(opt *ChartOption) {
|
||||||
|
opt.Height = height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PaddingOptionFunc set padding of chart
|
||||||
|
func PaddingOptionFunc(padding Box) OptionFunc {
|
||||||
|
return func(opt *ChartOption) {
|
||||||
|
opt.Padding = padding
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BoxOptionFunc set box of chart
|
||||||
|
func BoxOptionFunc(box Box) OptionFunc {
|
||||||
|
return func(opt *ChartOption) {
|
||||||
|
opt.Box = box
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PieSeriesShowLabel set pie series show label
|
||||||
|
func PieSeriesShowLabel() OptionFunc {
|
||||||
|
return func(opt *ChartOption) {
|
||||||
|
for index := range opt.SeriesList {
|
||||||
|
opt.SeriesList[index].Label.Show = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChildOptionFunc add child chart
|
||||||
|
func ChildOptionFunc(child ...ChartOption) OptionFunc {
|
||||||
|
return func(opt *ChartOption) {
|
||||||
|
if opt.Children == nil {
|
||||||
|
opt.Children = make([]ChartOption, 0)
|
||||||
|
}
|
||||||
|
opt.Children = append(opt.Children, child...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RadarIndicatorOptionFunc set radar indicator of chart
|
||||||
|
func RadarIndicatorOptionFunc(names []string, values []float64) OptionFunc {
|
||||||
|
return func(opt *ChartOption) {
|
||||||
|
if len(names) != len(values) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
indicators := make([]RadarIndicator, len(names))
|
||||||
|
for index, name := range names {
|
||||||
|
indicators[index] = RadarIndicator{
|
||||||
|
Name: name,
|
||||||
|
Max: values[index],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
opt.RadarIndicators = indicators
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BackgroundColorOptionFunc set background color of chart
|
||||||
|
func BackgroundColorOptionFunc(color Color) OptionFunc {
|
||||||
|
return func(opt *ChartOption) {
|
||||||
|
opt.BackgroundColor = color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarkLineOptionFunc set mark line for series of chart
|
||||||
|
func MarkLineOptionFunc(seriesIndex int, markLineTypes ...string) OptionFunc {
|
||||||
|
return func(opt *ChartOption) {
|
||||||
|
if len(opt.SeriesList) <= seriesIndex {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
opt.SeriesList[seriesIndex].MarkLine = NewMarkLine(markLineTypes...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarkPointOptionFunc set mark point for series of chart
|
||||||
|
func MarkPointOptionFunc(seriesIndex int, markPointTypes ...string) OptionFunc {
|
||||||
|
return func(opt *ChartOption) {
|
||||||
|
if len(opt.SeriesList) <= seriesIndex {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
opt.SeriesList[seriesIndex].MarkPoint = NewMarkPoint(markPointTypes...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (o *ChartOption) fillDefault() {
|
func (o *ChartOption) fillDefault() {
|
||||||
t := NewTheme(o.Theme)
|
t := NewTheme(o.Theme)
|
||||||
o.theme = t
|
o.theme = t
|
||||||
|
|
@ -90,11 +266,11 @@ func (o *ChartOption) fillDefault() {
|
||||||
o.BackgroundColor = t.GetBackgroundColor()
|
o.BackgroundColor = t.GetBackgroundColor()
|
||||||
}
|
}
|
||||||
if o.Padding.IsZero() {
|
if o.Padding.IsZero() {
|
||||||
o.Padding = chart.Box{
|
o.Padding = Box{
|
||||||
Top: 10,
|
Top: 20,
|
||||||
Right: 10,
|
Right: 20,
|
||||||
Bottom: 10,
|
Bottom: 20,
|
||||||
Left: 10,
|
Left: 20,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// legend与series name的关联
|
// legend与series name的关联
|
||||||
|
|
@ -118,3 +294,55 @@ func (o *ChartOption) fillDefault() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LineRender line chart render
|
||||||
|
func LineRender(values [][]float64, opts ...OptionFunc) (*Painter, error) {
|
||||||
|
seriesList := NewSeriesListDataFromValues(values, ChartTypeLine)
|
||||||
|
return Render(ChartOption{
|
||||||
|
SeriesList: seriesList,
|
||||||
|
}, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BarRender bar chart render
|
||||||
|
func BarRender(values [][]float64, opts ...OptionFunc) (*Painter, error) {
|
||||||
|
seriesList := NewSeriesListDataFromValues(values, ChartTypeBar)
|
||||||
|
return Render(ChartOption{
|
||||||
|
SeriesList: seriesList,
|
||||||
|
}, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HorizontalBarRender horizontal bar chart render
|
||||||
|
func HorizontalBarRender(values [][]float64, opts ...OptionFunc) (*Painter, error) {
|
||||||
|
seriesList := NewSeriesListDataFromValues(values, ChartTypeHorizontalBar)
|
||||||
|
return Render(ChartOption{
|
||||||
|
SeriesList: seriesList,
|
||||||
|
}, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PieRender pie chart render
|
||||||
|
func PieRender(values []float64, opts ...OptionFunc) (*Painter, error) {
|
||||||
|
return Render(ChartOption{
|
||||||
|
SeriesList: NewPieSeriesList(values),
|
||||||
|
}, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RadarRender radar chart render
|
||||||
|
func RadarRender(values [][]float64, opts ...OptionFunc) (*Painter, error) {
|
||||||
|
seriesList := NewSeriesListDataFromValues(values, ChartTypeRadar)
|
||||||
|
return Render(ChartOption{
|
||||||
|
SeriesList: seriesList,
|
||||||
|
}, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FunnelRender funnel chart render
|
||||||
|
func FunnelRender(values []float64, opts ...OptionFunc) (*Painter, error) {
|
||||||
|
seriesList := make(SeriesList, len(values))
|
||||||
|
for index, value := range values {
|
||||||
|
seriesList[index] = NewSeriesFromValues([]float64{
|
||||||
|
value,
|
||||||
|
}, ChartTypeFunnel)
|
||||||
|
}
|
||||||
|
return Render(ChartOption{
|
||||||
|
SeriesList: seriesList,
|
||||||
|
}, opts...)
|
||||||
|
}
|
||||||
|
|
|
||||||
11
charts.go
11
charts.go
|
|
@ -239,7 +239,10 @@ func doRender(renderers ...Renderer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Render(opt ChartOption) (*Painter, error) {
|
func Render(opt ChartOption, opts ...OptionFunc) (*Painter, error) {
|
||||||
|
for _, fn := range opts {
|
||||||
|
fn(&opt)
|
||||||
|
}
|
||||||
opt.fillDefault()
|
opt.fillDefault()
|
||||||
|
|
||||||
isChild := true
|
isChild := true
|
||||||
|
|
@ -398,6 +401,12 @@ func Render(opt ChartOption) (*Painter, error) {
|
||||||
}
|
}
|
||||||
for _, item := range opt.Children {
|
for _, item := range opt.Children {
|
||||||
item.Parent = p
|
item.Parent = p
|
||||||
|
if item.Theme == "" {
|
||||||
|
item.Theme = opt.Theme
|
||||||
|
}
|
||||||
|
if item.FontFamily == "" {
|
||||||
|
item.FontFamily = opt.FontFamily
|
||||||
|
}
|
||||||
_, err = Render(item)
|
_, err = Render(item)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
18
echarts.go
18
echarts.go
|
|
@ -130,6 +130,7 @@ type EChartsXAxisData struct {
|
||||||
BoundaryGap *bool `json:"boundaryGap"`
|
BoundaryGap *bool `json:"boundaryGap"`
|
||||||
SplitNumber int `json:"splitNumber"`
|
SplitNumber int `json:"splitNumber"`
|
||||||
Data []string `json:"data"`
|
Data []string `json:"data"`
|
||||||
|
Type string `json:"type"`
|
||||||
}
|
}
|
||||||
type EChartsXAxis struct {
|
type EChartsXAxis struct {
|
||||||
Data []EChartsXAxisData
|
Data []EChartsXAxisData
|
||||||
|
|
@ -155,6 +156,7 @@ type EChartsYAxisData struct {
|
||||||
Color string `json:"color"`
|
Color string `json:"color"`
|
||||||
} `json:"lineStyle"`
|
} `json:"lineStyle"`
|
||||||
} `json:"axisLine"`
|
} `json:"axisLine"`
|
||||||
|
Data []string `json:"data"`
|
||||||
}
|
}
|
||||||
type EChartsYAxis struct {
|
type EChartsYAxis struct {
|
||||||
Data []EChartsYAxisData `json:"data"`
|
Data []EChartsYAxisData `json:"data"`
|
||||||
|
|
@ -453,6 +455,21 @@ func (eo *EChartsOption) ToOption() ChartOption {
|
||||||
Box: eo.Box,
|
Box: eo.Box,
|
||||||
SeriesList: eo.Series.ToSeriesList(),
|
SeriesList: eo.Series.ToSeriesList(),
|
||||||
}
|
}
|
||||||
|
isHorizontalChart := false
|
||||||
|
for _, item := range eo.XAxis.Data {
|
||||||
|
if item.Type == "value" {
|
||||||
|
isHorizontalChart = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if isHorizontalChart {
|
||||||
|
for index := range o.SeriesList {
|
||||||
|
series := o.SeriesList[index]
|
||||||
|
if series.Type == ChartTypeBar {
|
||||||
|
o.SeriesList[index].Type = ChartTypeHorizontalBar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(eo.XAxis.Data) != 0 {
|
if len(eo.XAxis.Data) != 0 {
|
||||||
xAxisData := eo.XAxis.Data[0]
|
xAxisData := eo.XAxis.Data[0]
|
||||||
o.XAxis = XAxisOption{
|
o.XAxis = XAxisOption{
|
||||||
|
|
@ -468,6 +485,7 @@ func (eo *EChartsOption) ToOption() ChartOption {
|
||||||
Max: item.Max,
|
Max: item.Max,
|
||||||
Formatter: item.AxisLabel.Formatter,
|
Formatter: item.AxisLabel.Formatter,
|
||||||
Color: parseColor(item.AxisLine.LineStyle.Color),
|
Color: parseColor(item.AxisLine.LineStyle.Color),
|
||||||
|
Data: item.Data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
o.YAxisOptions = yAxisOptions
|
o.YAxisOptions = yAxisOptions
|
||||||
|
|
|
||||||
|
|
@ -24,26 +24,39 @@ func writeFile(buf []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
p, err := charts.NewPainter(charts.PainterOptions{
|
values := [][]float64{
|
||||||
Width: 800,
|
{
|
||||||
Height: 600,
|
2.0,
|
||||||
Type: charts.ChartOutputPNG,
|
4.9,
|
||||||
})
|
7.0,
|
||||||
if err != nil {
|
23.2,
|
||||||
panic(err)
|
25.6,
|
||||||
|
76.7,
|
||||||
|
135.6,
|
||||||
|
162.2,
|
||||||
|
32.6,
|
||||||
|
20.0,
|
||||||
|
6.4,
|
||||||
|
3.3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
2.6,
|
||||||
|
5.9,
|
||||||
|
9.0,
|
||||||
|
26.4,
|
||||||
|
28.7,
|
||||||
|
70.7,
|
||||||
|
175.6,
|
||||||
|
182.2,
|
||||||
|
48.7,
|
||||||
|
18.8,
|
||||||
|
6.0,
|
||||||
|
2.3,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
_, err = charts.NewBarChart(p, charts.BarChartOption{
|
p, err := charts.BarRender(
|
||||||
Title: charts.TitleOption{
|
values,
|
||||||
Text: "Rainfall vs Evaporation",
|
charts.XAxisDataOptionFunc([]string{
|
||||||
Subtext: "Fake Data",
|
|
||||||
},
|
|
||||||
Padding: charts.Box{
|
|
||||||
Top: 20,
|
|
||||||
Right: 20,
|
|
||||||
Bottom: 20,
|
|
||||||
Left: 20,
|
|
||||||
},
|
|
||||||
XAxis: charts.NewXAxisOption([]string{
|
|
||||||
"Jan",
|
"Jan",
|
||||||
"Feb",
|
"Feb",
|
||||||
"Mar",
|
"Mar",
|
||||||
|
|
@ -57,61 +70,24 @@ func main() {
|
||||||
"Nov",
|
"Nov",
|
||||||
"Dec",
|
"Dec",
|
||||||
}),
|
}),
|
||||||
Legend: charts.NewLegendOption([]string{
|
charts.LegendLabelsOptionFunc([]string{
|
||||||
"Rainfall",
|
"Rainfall",
|
||||||
"Evaporation",
|
"Evaporation",
|
||||||
}, charts.PositionRight),
|
}, charts.PositionRight),
|
||||||
SeriesList: []charts.Series{
|
charts.MarkLineOptionFunc(0, charts.SeriesMarkDataTypeAverage),
|
||||||
{
|
charts.MarkPointOptionFunc(0, charts.SeriesMarkDataTypeMax,
|
||||||
Type: charts.ChartTypeBar,
|
charts.SeriesMarkDataTypeMin),
|
||||||
Data: charts.NewSeriesDataFromValues([]float64{
|
// custom option func
|
||||||
2.0,
|
func(opt *charts.ChartOption) {
|
||||||
4.9,
|
opt.SeriesList[1].MarkPoint = charts.NewMarkPoint(
|
||||||
7.0,
|
|
||||||
23.2,
|
|
||||||
25.6,
|
|
||||||
76.7,
|
|
||||||
135.6,
|
|
||||||
162.2,
|
|
||||||
32.6,
|
|
||||||
20.0,
|
|
||||||
6.4,
|
|
||||||
3.3,
|
|
||||||
}),
|
|
||||||
MarkPoint: charts.NewMarkPoint(
|
|
||||||
charts.SeriesMarkDataTypeMax,
|
charts.SeriesMarkDataTypeMax,
|
||||||
charts.SeriesMarkDataTypeMin,
|
charts.SeriesMarkDataTypeMin,
|
||||||
),
|
)
|
||||||
MarkLine: charts.NewMarkLine(
|
opt.SeriesList[1].MarkLine = charts.NewMarkLine(
|
||||||
charts.SeriesMarkDataTypeAverage,
|
charts.SeriesMarkDataTypeAverage,
|
||||||
),
|
)
|
||||||
},
|
},
|
||||||
{
|
)
|
||||||
Type: charts.ChartTypeBar,
|
|
||||||
Data: charts.NewSeriesDataFromValues([]float64{
|
|
||||||
2.6,
|
|
||||||
5.9,
|
|
||||||
9.0,
|
|
||||||
26.4,
|
|
||||||
28.7,
|
|
||||||
70.7,
|
|
||||||
175.6,
|
|
||||||
182.2,
|
|
||||||
48.7,
|
|
||||||
18.8,
|
|
||||||
6.0,
|
|
||||||
2.3,
|
|
||||||
}),
|
|
||||||
MarkPoint: charts.NewMarkPoint(
|
|
||||||
charts.SeriesMarkDataTypeMax,
|
|
||||||
charts.SeriesMarkDataTypeMin,
|
|
||||||
),
|
|
||||||
MarkLine: charts.NewMarkLine(
|
|
||||||
charts.SeriesMarkDataTypeAverage,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}).Render()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@ func handler(w http.ResponseWriter, req *http.Request, chartOptions []charts.Cha
|
||||||
bytesList := make([][]byte, 0)
|
bytesList := make([][]byte, 0)
|
||||||
for _, opt := range chartOptions {
|
for _, opt := range chartOptions {
|
||||||
opt.Theme = theme
|
opt.Theme = theme
|
||||||
|
opt.Type = charts.ChartOutputSVG
|
||||||
d, err := charts.Render(opt)
|
d, err := charts.Render(opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
@ -1055,6 +1056,64 @@ func echartsHandler(w http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}`,
|
}`,
|
||||||
|
`{
|
||||||
|
"title": {
|
||||||
|
"text": "World Population"
|
||||||
|
},
|
||||||
|
"tooltip": {
|
||||||
|
"trigger": "axis",
|
||||||
|
"axisPointer": {
|
||||||
|
"type": "shadow"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"legend": {},
|
||||||
|
"grid": {
|
||||||
|
"left": "3%",
|
||||||
|
"right": "4%",
|
||||||
|
"bottom": "3%",
|
||||||
|
"containLabel": true
|
||||||
|
},
|
||||||
|
"xAxis": {
|
||||||
|
"type": "value"
|
||||||
|
},
|
||||||
|
"yAxis": {
|
||||||
|
"type": "category",
|
||||||
|
"data": [
|
||||||
|
"Brazil",
|
||||||
|
"Indonesia",
|
||||||
|
"USA",
|
||||||
|
"India",
|
||||||
|
"China",
|
||||||
|
"World"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"series": [
|
||||||
|
{
|
||||||
|
"name": "2011",
|
||||||
|
"type": "bar",
|
||||||
|
"data": [
|
||||||
|
18203,
|
||||||
|
23489,
|
||||||
|
29034,
|
||||||
|
104970,
|
||||||
|
131744,
|
||||||
|
630230
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "2012",
|
||||||
|
"type": "bar",
|
||||||
|
"data": [
|
||||||
|
19325,
|
||||||
|
23438,
|
||||||
|
31000,
|
||||||
|
121594,
|
||||||
|
134141,
|
||||||
|
681807
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}`,
|
||||||
`{
|
`{
|
||||||
"title": {
|
"title": {
|
||||||
"text": "Rainfall vs Evaporation",
|
"text": "Rainfall vs Evaporation",
|
||||||
|
|
|
||||||
|
|
@ -24,64 +24,24 @@ func writeFile(buf []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
p, err := charts.NewPainter(charts.PainterOptions{
|
values := []float64{
|
||||||
Width: 800,
|
100,
|
||||||
Height: 600,
|
80,
|
||||||
Type: charts.ChartOutputPNG,
|
60,
|
||||||
})
|
40,
|
||||||
if err != nil {
|
20,
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
_, err = charts.NewFunnelChart(p, charts.FunnelChartOption{
|
p, err := charts.FunnelRender(
|
||||||
Title: charts.TitleOption{
|
values,
|
||||||
Text: "Funnel",
|
charts.TitleTextOptionFunc("Funnel"),
|
||||||
},
|
charts.LegendLabelsOptionFunc([]string{
|
||||||
Legend: charts.NewLegendOption([]string{
|
|
||||||
"Show",
|
"Show",
|
||||||
"Click",
|
"Click",
|
||||||
"Visit",
|
"Visit",
|
||||||
"Inquiry",
|
"Inquiry",
|
||||||
"Order",
|
"Order",
|
||||||
}),
|
}),
|
||||||
SeriesList: []charts.Series{
|
)
|
||||||
|
|
||||||
{
|
|
||||||
Type: charts.ChartTypeFunnel,
|
|
||||||
Name: "Show",
|
|
||||||
Data: charts.NewSeriesDataFromValues([]float64{
|
|
||||||
100,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: charts.ChartTypeFunnel,
|
|
||||||
Name: "Click",
|
|
||||||
Data: charts.NewSeriesDataFromValues([]float64{
|
|
||||||
80,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: charts.ChartTypeFunnel,
|
|
||||||
Name: "Visit",
|
|
||||||
Data: charts.NewSeriesDataFromValues([]float64{
|
|
||||||
60,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: charts.ChartTypeFunnel,
|
|
||||||
Name: "Inquiry",
|
|
||||||
Data: charts.NewSeriesDataFromValues([]float64{
|
|
||||||
40,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: charts.ChartTypeFunnel,
|
|
||||||
Name: "Order",
|
|
||||||
Data: charts.NewSeriesDataFromValues([]float64{
|
|
||||||
20,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}).Render()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,29 +24,38 @@ func writeFile(buf []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
p, err := charts.NewPainter(charts.PainterOptions{
|
values := [][]float64{
|
||||||
Width: 800,
|
{
|
||||||
Height: 600,
|
18203,
|
||||||
Type: charts.ChartOutputPNG,
|
23489,
|
||||||
})
|
29034,
|
||||||
if err != nil {
|
104970,
|
||||||
panic(err)
|
131744,
|
||||||
}
|
630230,
|
||||||
_, err = charts.NewHorizontalBarChart(p, charts.HorizontalBarChartOption{
|
|
||||||
Title: charts.TitleOption{
|
|
||||||
Text: "World Population",
|
|
||||||
},
|
},
|
||||||
Padding: charts.Box{
|
{
|
||||||
|
19325,
|
||||||
|
23438,
|
||||||
|
31000,
|
||||||
|
121594,
|
||||||
|
134141,
|
||||||
|
681807,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
p, err := charts.HorizontalBarRender(
|
||||||
|
values,
|
||||||
|
charts.TitleTextOptionFunc("World Population"),
|
||||||
|
charts.PaddingOptionFunc(charts.Box{
|
||||||
Top: 20,
|
Top: 20,
|
||||||
Right: 40,
|
Right: 40,
|
||||||
Bottom: 20,
|
Bottom: 20,
|
||||||
Left: 20,
|
Left: 20,
|
||||||
},
|
}),
|
||||||
Legend: charts.NewLegendOption([]string{
|
charts.LegendLabelsOptionFunc([]string{
|
||||||
"2011",
|
"2011",
|
||||||
"2012",
|
"2012",
|
||||||
}),
|
}),
|
||||||
YAxisOptions: charts.NewYAxisOptions([]string{
|
charts.YAxisDataOptionFunc([]string{
|
||||||
"Brazil",
|
"Brazil",
|
||||||
"Indonesia",
|
"Indonesia",
|
||||||
"USA",
|
"USA",
|
||||||
|
|
@ -54,31 +63,7 @@ func main() {
|
||||||
"China",
|
"China",
|
||||||
"World",
|
"World",
|
||||||
}),
|
}),
|
||||||
SeriesList: []charts.Series{
|
)
|
||||||
{
|
|
||||||
Type: charts.ChartTypeHorizontalBar,
|
|
||||||
Data: charts.NewSeriesDataFromValues([]float64{
|
|
||||||
18203,
|
|
||||||
23489,
|
|
||||||
29034,
|
|
||||||
104970,
|
|
||||||
131744,
|
|
||||||
630230,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Type: charts.ChartTypeHorizontalBar,
|
|
||||||
Data: charts.NewSeriesDataFromValues([]float64{
|
|
||||||
19325,
|
|
||||||
23438,
|
|
||||||
31000,
|
|
||||||
121594,
|
|
||||||
134141,
|
|
||||||
681807,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}).Render()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,35 +24,57 @@ func writeFile(buf []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
p, err := charts.NewPainter(charts.PainterOptions{
|
values := [][]float64{
|
||||||
Width: 800,
|
{
|
||||||
Height: 600,
|
120,
|
||||||
Type: charts.ChartOutputPNG,
|
132,
|
||||||
})
|
101,
|
||||||
if err != nil {
|
134,
|
||||||
panic(err)
|
90,
|
||||||
|
230,
|
||||||
|
210,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
220,
|
||||||
|
182,
|
||||||
|
191,
|
||||||
|
234,
|
||||||
|
290,
|
||||||
|
330,
|
||||||
|
310,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
150,
|
||||||
|
232,
|
||||||
|
201,
|
||||||
|
154,
|
||||||
|
190,
|
||||||
|
330,
|
||||||
|
410,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
320,
|
||||||
|
332,
|
||||||
|
301,
|
||||||
|
334,
|
||||||
|
390,
|
||||||
|
330,
|
||||||
|
320,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
820,
|
||||||
|
932,
|
||||||
|
901,
|
||||||
|
934,
|
||||||
|
1290,
|
||||||
|
1330,
|
||||||
|
1320,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
_, err = charts.NewLineChart(p, charts.LineChartOption{
|
p, err := charts.LineRender(
|
||||||
Padding: charts.Box{
|
values,
|
||||||
Left: 10,
|
charts.TitleTextOptionFunc("Line"),
|
||||||
Top: 10,
|
charts.XAxisDataOptionFunc([]string{
|
||||||
Right: 10,
|
|
||||||
Bottom: 10,
|
|
||||||
},
|
|
||||||
Title: charts.TitleOption{
|
|
||||||
Text: "Line",
|
|
||||||
},
|
|
||||||
Legend: charts.LegendOption{
|
|
||||||
Data: []string{
|
|
||||||
"Email",
|
|
||||||
"Union Ads",
|
|
||||||
"Video Ads",
|
|
||||||
"Direct",
|
|
||||||
"Search Engine",
|
|
||||||
},
|
|
||||||
Left: charts.PositionCenter,
|
|
||||||
},
|
|
||||||
XAxis: charts.NewXAxisOption([]string{
|
|
||||||
"Mon",
|
"Mon",
|
||||||
"Tue",
|
"Tue",
|
||||||
"Wed",
|
"Wed",
|
||||||
|
|
@ -61,54 +83,15 @@ func main() {
|
||||||
"Sat",
|
"Sat",
|
||||||
"Sun",
|
"Sun",
|
||||||
}),
|
}),
|
||||||
SeriesList: charts.SeriesList{
|
charts.LegendLabelsOptionFunc([]string{
|
||||||
charts.NewSeriesFromValues([]float64{
|
"Email",
|
||||||
120,
|
"Union Ads",
|
||||||
132,
|
"Video Ads",
|
||||||
101,
|
"Direct",
|
||||||
134,
|
"Search Engine",
|
||||||
90,
|
}, charts.PositionCenter),
|
||||||
230,
|
)
|
||||||
210,
|
|
||||||
}),
|
|
||||||
charts.NewSeriesFromValues([]float64{
|
|
||||||
220,
|
|
||||||
182,
|
|
||||||
191,
|
|
||||||
234,
|
|
||||||
290,
|
|
||||||
330,
|
|
||||||
310,
|
|
||||||
}),
|
|
||||||
charts.NewSeriesFromValues([]float64{
|
|
||||||
150,
|
|
||||||
232,
|
|
||||||
201,
|
|
||||||
154,
|
|
||||||
190,
|
|
||||||
330,
|
|
||||||
410,
|
|
||||||
}),
|
|
||||||
charts.NewSeriesFromValues([]float64{
|
|
||||||
320,
|
|
||||||
332,
|
|
||||||
301,
|
|
||||||
334,
|
|
||||||
390,
|
|
||||||
330,
|
|
||||||
320,
|
|
||||||
}),
|
|
||||||
charts.NewSeriesFromValues([]float64{
|
|
||||||
820,
|
|
||||||
932,
|
|
||||||
901,
|
|
||||||
934,
|
|
||||||
1290,
|
|
||||||
1330,
|
|
||||||
1320,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
}).Render()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,27 +24,27 @@ func writeFile(buf []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
p, err := charts.NewPainter(charts.PainterOptions{
|
values := []float64{
|
||||||
Width: 800,
|
1048,
|
||||||
Height: 600,
|
735,
|
||||||
Type: charts.ChartOutputPNG,
|
580,
|
||||||
})
|
484,
|
||||||
if err != nil {
|
300,
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
_, err = charts.NewPieChart(p, charts.PieChartOption{
|
p, err := charts.PieRender(
|
||||||
Title: charts.TitleOption{
|
values,
|
||||||
|
charts.TitleOptionFunc(charts.TitleOption{
|
||||||
Text: "Rainfall vs Evaporation",
|
Text: "Rainfall vs Evaporation",
|
||||||
Subtext: "Fake Data",
|
Subtext: "Fake Data",
|
||||||
Left: charts.PositionCenter,
|
Left: charts.PositionCenter,
|
||||||
},
|
}),
|
||||||
Padding: charts.Box{
|
charts.PaddingOptionFunc(charts.Box{
|
||||||
Top: 20,
|
Top: 20,
|
||||||
Right: 20,
|
Right: 20,
|
||||||
Bottom: 20,
|
Bottom: 20,
|
||||||
Left: 20,
|
Left: 20,
|
||||||
},
|
}),
|
||||||
Legend: charts.LegendOption{
|
charts.LegendOptionFunc(charts.LegendOption{
|
||||||
Orient: charts.OrientVertical,
|
Orient: charts.OrientVertical,
|
||||||
Data: []string{
|
Data: []string{
|
||||||
"Search Engine",
|
"Search Engine",
|
||||||
|
|
@ -54,20 +54,9 @@ func main() {
|
||||||
"Video Ads",
|
"Video Ads",
|
||||||
},
|
},
|
||||||
Left: charts.PositionLeft,
|
Left: charts.PositionLeft,
|
||||||
},
|
|
||||||
SeriesList: charts.NewPieSeriesList([]float64{
|
|
||||||
1048,
|
|
||||||
735,
|
|
||||||
580,
|
|
||||||
484,
|
|
||||||
300,
|
|
||||||
}, charts.PieSeriesOption{
|
|
||||||
Label: charts.SeriesLabel{
|
|
||||||
Show: true,
|
|
||||||
},
|
|
||||||
Radius: "35%",
|
|
||||||
}),
|
}),
|
||||||
}).Render()
|
charts.PieSeriesShowLabel(),
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,79 +24,47 @@ func writeFile(buf []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
p, err := charts.NewPainter(charts.PainterOptions{
|
values := [][]float64{
|
||||||
Width: 800,
|
|
||||||
Height: 600,
|
|
||||||
Type: charts.ChartOutputPNG,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
_, err = charts.NewRadarChart(p, charts.RadarChartOption{
|
|
||||||
Padding: charts.Box{
|
|
||||||
Left: 10,
|
|
||||||
Top: 10,
|
|
||||||
Right: 10,
|
|
||||||
Bottom: 10,
|
|
||||||
},
|
|
||||||
Title: charts.TitleOption{
|
|
||||||
Text: "Basic Radar Chart",
|
|
||||||
},
|
|
||||||
Legend: charts.NewLegendOption([]string{
|
|
||||||
"Allocated Budget",
|
|
||||||
"Actual Spending",
|
|
||||||
}),
|
|
||||||
RadarIndicators: []charts.RadarIndicator{
|
|
||||||
{
|
{
|
||||||
Name: "Sales",
|
|
||||||
Max: 6500,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "Administration",
|
|
||||||
Max: 16000,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "Information Technology",
|
|
||||||
Max: 30000,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "Customer Support",
|
|
||||||
Max: 38000,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "Development",
|
|
||||||
Max: 52000,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "Marketing",
|
|
||||||
Max: 25000,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
SeriesList: charts.SeriesList{
|
|
||||||
{
|
|
||||||
Type: charts.ChartTypeRadar,
|
|
||||||
Data: charts.NewSeriesDataFromValues([]float64{
|
|
||||||
4200,
|
4200,
|
||||||
3000,
|
3000,
|
||||||
20000,
|
20000,
|
||||||
35000,
|
35000,
|
||||||
50000,
|
50000,
|
||||||
18000,
|
18000,
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Type: charts.ChartTypeRadar,
|
|
||||||
Data: charts.NewSeriesDataFromValues([]float64{
|
|
||||||
5000,
|
5000,
|
||||||
14000,
|
14000,
|
||||||
28000,
|
28000,
|
||||||
26000,
|
26000,
|
||||||
42000,
|
42000,
|
||||||
21000,
|
21000,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
p, err := charts.RadarRender(
|
||||||
|
values,
|
||||||
|
charts.TitleTextOptionFunc("Basic Radar Chart"),
|
||||||
|
charts.LegendLabelsOptionFunc([]string{
|
||||||
|
"Allocated Budget",
|
||||||
|
"Actual Spending",
|
||||||
}),
|
}),
|
||||||
},
|
charts.RadarIndicatorOptionFunc([]string{
|
||||||
},
|
"Sales",
|
||||||
}).Render()
|
"Administration",
|
||||||
|
"Information Technology",
|
||||||
|
"Customer Support",
|
||||||
|
"Development",
|
||||||
|
"Marketing",
|
||||||
|
}, []float64{
|
||||||
|
6500,
|
||||||
|
16000,
|
||||||
|
30000,
|
||||||
|
38000,
|
||||||
|
52000,
|
||||||
|
25000,
|
||||||
|
}),
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ type funnelChart struct {
|
||||||
|
|
||||||
func NewFunnelChart(p *Painter, opt FunnelChartOption) *funnelChart {
|
func NewFunnelChart(p *Painter, opt FunnelChartOption) *funnelChart {
|
||||||
if opt.Theme == nil {
|
if opt.Theme == nil {
|
||||||
opt.Theme = NewTheme("")
|
opt.Theme = defaultTheme
|
||||||
}
|
}
|
||||||
return &funnelChart{
|
return &funnelChart{
|
||||||
p: p,
|
p: p,
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ type HorizontalBarChartOption struct {
|
||||||
|
|
||||||
func NewHorizontalBarChart(p *Painter, opt HorizontalBarChartOption) *horizontalBarChart {
|
func NewHorizontalBarChart(p *Painter, opt HorizontalBarChartOption) *horizontalBarChart {
|
||||||
if opt.Theme == nil {
|
if opt.Theme == nil {
|
||||||
opt.Theme = NewTheme("")
|
opt.Theme = defaultTheme
|
||||||
}
|
}
|
||||||
return &horizontalBarChart{
|
return &horizontalBarChart{
|
||||||
p: p,
|
p: p,
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ type lineChart struct {
|
||||||
|
|
||||||
func NewLineChart(p *Painter, opt LineChartOption) *lineChart {
|
func NewLineChart(p *Painter, opt LineChartOption) *lineChart {
|
||||||
if opt.Theme == nil {
|
if opt.Theme == nil {
|
||||||
opt.Theme = NewTheme("")
|
opt.Theme = defaultTheme
|
||||||
}
|
}
|
||||||
return &lineChart{
|
return &lineChart{
|
||||||
p: p,
|
p: p,
|
||||||
|
|
|
||||||
|
|
@ -149,9 +149,9 @@ func NewPainter(opts PainterOptions, opt ...PainterOption) (*Painter, error) {
|
||||||
}
|
}
|
||||||
font = f
|
font = f
|
||||||
}
|
}
|
||||||
fn := chart.SVG
|
fn := chart.PNG
|
||||||
if opts.Type == ChartOutputPNG {
|
if opts.Type == ChartOutputSVG {
|
||||||
fn = chart.PNG
|
fn = chart.SVG
|
||||||
}
|
}
|
||||||
width := opts.Width
|
width := opts.Width
|
||||||
height := opts.Height
|
height := opts.Height
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ type PieChartOption struct {
|
||||||
|
|
||||||
func NewPieChart(p *Painter, opt PieChartOption) *pieChart {
|
func NewPieChart(p *Painter, opt PieChartOption) *pieChart {
|
||||||
if opt.Theme == nil {
|
if opt.Theme == nil {
|
||||||
opt.Theme = NewTheme("")
|
opt.Theme = defaultTheme
|
||||||
}
|
}
|
||||||
return &pieChart{
|
return &pieChart{
|
||||||
p: p,
|
p: p,
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ type RadarChartOption struct {
|
||||||
|
|
||||||
func NewRadarChart(p *Painter, opt RadarChartOption) *radarChart {
|
func NewRadarChart(p *Painter, opt RadarChartOption) *radarChart {
|
||||||
if opt.Theme == nil {
|
if opt.Theme == nil {
|
||||||
opt.Theme = NewTheme("")
|
opt.Theme = defaultTheme
|
||||||
}
|
}
|
||||||
return &radarChart{
|
return &radarChart{
|
||||||
p: p,
|
p: p,
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,14 @@ type SeriesData struct {
|
||||||
Style Style
|
Style Style
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewSeriesListDataFromValues(values [][]float64, chartType ...string) SeriesList {
|
||||||
|
seriesList := make(SeriesList, len(values))
|
||||||
|
for index, value := range values {
|
||||||
|
seriesList[index] = NewSeriesFromValues(value, chartType...)
|
||||||
|
}
|
||||||
|
return seriesList
|
||||||
|
}
|
||||||
|
|
||||||
func NewSeriesFromValues(values []float64, chartType ...string) Series {
|
func NewSeriesFromValues(values []float64, chartType ...string) Series {
|
||||||
s := Series{
|
s := Series{
|
||||||
Data: NewSeriesDataFromValues(values),
|
Data: NewSeriesDataFromValues(values),
|
||||||
|
|
|
||||||
86
theme.go
86
theme.go
|
|
@ -55,10 +55,21 @@ type themeColorPalette struct {
|
||||||
font *truetype.Font
|
font *truetype.Font
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ThemeOption struct {
|
||||||
|
IsDarkMode bool
|
||||||
|
AxisStrokeColor Color
|
||||||
|
AxisSplitLineColor Color
|
||||||
|
BackgroundColor Color
|
||||||
|
TextColor Color
|
||||||
|
SeriesColors []Color
|
||||||
|
}
|
||||||
|
|
||||||
var palettes = map[string]ColorPalette{}
|
var palettes = map[string]ColorPalette{}
|
||||||
|
|
||||||
const defaultFontSize = 12.0
|
const defaultFontSize = 12.0
|
||||||
|
|
||||||
|
var defaultTheme ColorPalette
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
echartSeriesColors := []Color{
|
echartSeriesColors := []Color{
|
||||||
parseColor("#5470c6"),
|
parseColor("#5470c6"),
|
||||||
|
|
@ -93,121 +104,134 @@ func init() {
|
||||||
}
|
}
|
||||||
AddTheme(
|
AddTheme(
|
||||||
ThemeDark,
|
ThemeDark,
|
||||||
true,
|
ThemeOption{
|
||||||
Color{
|
IsDarkMode: true,
|
||||||
|
AxisStrokeColor: Color{
|
||||||
R: 185,
|
R: 185,
|
||||||
G: 184,
|
G: 184,
|
||||||
B: 206,
|
B: 206,
|
||||||
A: 255,
|
A: 255,
|
||||||
},
|
},
|
||||||
Color{
|
AxisSplitLineColor: Color{
|
||||||
R: 72,
|
R: 72,
|
||||||
G: 71,
|
G: 71,
|
||||||
B: 83,
|
B: 83,
|
||||||
A: 255,
|
A: 255,
|
||||||
},
|
},
|
||||||
Color{
|
BackgroundColor: Color{
|
||||||
R: 16,
|
R: 16,
|
||||||
G: 12,
|
G: 12,
|
||||||
B: 42,
|
B: 42,
|
||||||
A: 255,
|
A: 255,
|
||||||
},
|
},
|
||||||
Color{
|
TextColor: Color{
|
||||||
R: 238,
|
R: 238,
|
||||||
G: 238,
|
G: 238,
|
||||||
B: 238,
|
B: 238,
|
||||||
A: 255,
|
A: 255,
|
||||||
},
|
},
|
||||||
echartSeriesColors,
|
SeriesColors: echartSeriesColors,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
AddTheme(
|
AddTheme(
|
||||||
ThemeLight,
|
ThemeLight,
|
||||||
false,
|
ThemeOption{
|
||||||
Color{
|
IsDarkMode: false,
|
||||||
|
AxisStrokeColor: Color{
|
||||||
R: 110,
|
R: 110,
|
||||||
G: 112,
|
G: 112,
|
||||||
B: 121,
|
B: 121,
|
||||||
A: 255,
|
A: 255,
|
||||||
},
|
},
|
||||||
Color{
|
AxisSplitLineColor: Color{
|
||||||
R: 224,
|
R: 224,
|
||||||
G: 230,
|
G: 230,
|
||||||
B: 242,
|
B: 242,
|
||||||
A: 255,
|
A: 255,
|
||||||
},
|
},
|
||||||
drawing.ColorWhite,
|
BackgroundColor: drawing.ColorWhite,
|
||||||
drawing.Color{
|
TextColor: Color{
|
||||||
R: 70,
|
R: 70,
|
||||||
G: 70,
|
G: 70,
|
||||||
B: 70,
|
B: 70,
|
||||||
A: 255,
|
A: 255,
|
||||||
},
|
},
|
||||||
echartSeriesColors,
|
SeriesColors: echartSeriesColors,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
AddTheme(
|
AddTheme(
|
||||||
ThemeAnt,
|
ThemeAnt,
|
||||||
false,
|
ThemeOption{
|
||||||
Color{
|
IsDarkMode: false,
|
||||||
|
AxisStrokeColor: Color{
|
||||||
R: 110,
|
R: 110,
|
||||||
G: 112,
|
G: 112,
|
||||||
B: 121,
|
B: 121,
|
||||||
A: 255,
|
A: 255,
|
||||||
},
|
},
|
||||||
Color{
|
AxisSplitLineColor: Color{
|
||||||
R: 224,
|
R: 224,
|
||||||
G: 230,
|
G: 230,
|
||||||
B: 242,
|
B: 242,
|
||||||
A: 255,
|
A: 255,
|
||||||
},
|
},
|
||||||
drawing.ColorWhite,
|
BackgroundColor: drawing.ColorWhite,
|
||||||
drawing.Color{
|
TextColor: drawing.Color{
|
||||||
R: 70,
|
R: 70,
|
||||||
G: 70,
|
G: 70,
|
||||||
B: 70,
|
B: 70,
|
||||||
A: 255,
|
A: 255,
|
||||||
},
|
},
|
||||||
antSeriesColors,
|
SeriesColors: antSeriesColors,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
AddTheme(
|
AddTheme(
|
||||||
ThemeGrafana,
|
ThemeGrafana,
|
||||||
true,
|
ThemeOption{
|
||||||
drawing.Color{
|
IsDarkMode: true,
|
||||||
|
AxisStrokeColor: Color{
|
||||||
R: 185,
|
R: 185,
|
||||||
G: 184,
|
G: 184,
|
||||||
B: 206,
|
B: 206,
|
||||||
A: 255,
|
A: 255,
|
||||||
},
|
},
|
||||||
drawing.Color{
|
AxisSplitLineColor: Color{
|
||||||
R: 68,
|
R: 68,
|
||||||
G: 67,
|
G: 67,
|
||||||
B: 67,
|
B: 67,
|
||||||
A: 255,
|
A: 255,
|
||||||
},
|
},
|
||||||
drawing.Color{
|
BackgroundColor: drawing.Color{
|
||||||
R: 31,
|
R: 31,
|
||||||
G: 29,
|
G: 29,
|
||||||
B: 29,
|
B: 29,
|
||||||
A: 255,
|
A: 255,
|
||||||
},
|
},
|
||||||
drawing.Color{
|
TextColor: Color{
|
||||||
R: 216,
|
R: 216,
|
||||||
G: 217,
|
G: 217,
|
||||||
B: 218,
|
B: 218,
|
||||||
A: 255,
|
A: 255,
|
||||||
},
|
},
|
||||||
grafanaSeriesColors,
|
SeriesColors: grafanaSeriesColors,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
SetDefaultTheme(ThemeLight)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddTheme(name string, isDarkMode bool, axisStrokeColor, axisSplitLineColor, backgroundColor, textColor drawing.Color, seriesColors []drawing.Color) {
|
func SetDefaultTheme(name string) {
|
||||||
|
defaultTheme = NewTheme(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddTheme(name string, opt ThemeOption) {
|
||||||
palettes[name] = &themeColorPalette{
|
palettes[name] = &themeColorPalette{
|
||||||
isDarkMode: isDarkMode,
|
isDarkMode: opt.IsDarkMode,
|
||||||
axisStrokeColor: axisStrokeColor,
|
axisStrokeColor: opt.AxisStrokeColor,
|
||||||
axisSplitLineColor: axisSplitLineColor,
|
axisSplitLineColor: opt.AxisSplitLineColor,
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: opt.BackgroundColor,
|
||||||
textColor: textColor,
|
textColor: opt.TextColor,
|
||||||
seriesColors: seriesColors,
|
seriesColors: opt.SeriesColors,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue