feat: support fill area of line chart

This commit is contained in:
vicanso 2022-08-25 20:19:05 +08:00
parent 93e03856ca
commit dc1a89d3ff
6 changed files with 130 additions and 1 deletions

1
.gitignore vendored
View file

@ -17,3 +17,4 @@
*.svg *.svg
tmp tmp
NotoSansSC.ttf NotoSansSC.ttf
.vscode

View file

@ -66,6 +66,8 @@ type ChartOption struct {
SymbolShow *bool SymbolShow *bool
// The stroke width of line chart // The stroke width of line chart
LineStrokeWidth float64 LineStrokeWidth float64
// Fill the area of line chart
FillArea bool
// The child charts // The child charts
Children []ChartOption Children []ChartOption
} }

View file

@ -381,6 +381,7 @@ func Render(opt ChartOption, opts ...OptionFunc) (*Painter, error) {
XAxis: opt.XAxis, XAxis: opt.XAxis,
SymbolShow: opt.SymbolShow, SymbolShow: opt.SymbolShow,
StrokeWidth: opt.LineStrokeWidth, StrokeWidth: opt.LineStrokeWidth,
FillArea: opt.FillArea,
}).render(renderResult, lineSeriesList) }).render(renderResult, lineSeriesList)
return err return err
}) })

View file

@ -0,0 +1,74 @@
package main
import (
"io/ioutil"
"os"
"path/filepath"
"github.com/vicanso/go-charts/v2"
)
func writeFile(buf []byte) error {
tmpPath := "./tmp"
err := os.MkdirAll(tmpPath, 0700)
if err != nil {
return err
}
file := filepath.Join(tmpPath, "area-line-chart.png")
err = ioutil.WriteFile(file, buf, 0600)
if err != nil {
return err
}
return nil
}
func main() {
values := [][]float64{
{
120,
132,
101,
134,
90,
230,
210,
},
}
p, err := charts.LineRender(
values,
charts.TitleTextOptionFunc("Line"),
charts.XAxisDataOptionFunc([]string{
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
"Sun",
}),
charts.LegendLabelsOptionFunc([]string{
"Email",
}, "50"),
func(opt *charts.ChartOption) {
opt.Legend.Padding = charts.Box{
Top: 5,
Bottom: 10,
}
opt.FillArea = true
},
)
if err != nil {
panic(err)
}
buf, err := p.Bytes()
if err != nil {
panic(err)
}
err = writeFile(buf)
if err != nil {
panic(err)
}
}

View file

@ -2,6 +2,7 @@ package main
import ( import (
"bytes" "bytes"
"fmt"
"net/http" "net/http"
"strconv" "strconv"
@ -261,6 +262,35 @@ func indexHandler(w http.ResponseWriter, req *http.Request) {
}, },
}, },
}, },
{
Title: charts.TitleOption{
Text: "Line Area",
},
Legend: charts.NewLegendOption([]string{
"Email",
}),
XAxis: charts.NewXAxisOption([]string{
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
"Sun",
}),
SeriesList: []charts.Series{
charts.NewSeriesFromValues([]float64{
120,
132,
101,
134,
90,
230,
210,
}),
},
FillArea: true,
},
// 柱状图 // 柱状图
{ {
Title: charts.TitleOption{ Title: charts.TitleOption{
@ -1935,5 +1965,6 @@ func echartsHandler(w http.ResponseWriter, req *http.Request) {
func main() { func main() {
http.HandleFunc("/", indexHandler) http.HandleFunc("/", indexHandler)
http.HandleFunc("/echarts", echartsHandler) http.HandleFunc("/echarts", echartsHandler)
fmt.Println("http://127.0.0.1:3012/")
http.ListenAndServe(":3012", nil) http.ListenAndServe(":3012", nil)
} }

View file

@ -64,6 +64,8 @@ type LineChartOption struct {
SymbolShow *bool SymbolShow *bool
// The stroke width of line // The stroke width of line
StrokeWidth float64 StrokeWidth float64
// Fill the area of line
FillArea bool
// background is filled // background is filled
backgroundIsFilled bool backgroundIsFilled bool
} }
@ -109,7 +111,6 @@ func (l *lineChart) render(result *defaultRenderResult, seriesList SeriesList) (
StrokeWidth: strokeWidth, StrokeWidth: strokeWidth,
} }
seriesPainter.SetDrawingStyle(drawingStyle)
yRange := result.axisRanges[series.AxisIndex] yRange := result.axisRanges[series.AxisIndex]
points := make([]Point, 0) points := make([]Point, 0)
for i, item := range series.Data { for i, item := range series.Data {
@ -120,6 +121,25 @@ func (l *lineChart) render(result *defaultRenderResult, seriesList SeriesList) (
} }
points = append(points, p) points = append(points, p)
} }
// 如果需要填充区域
if opt.FillArea {
areaPoints := make([]Point, len(points))
copy(areaPoints, points)
bottomY := yRange.getRestHeight(yRange.min)
areaPoints = append(areaPoints, Point{
X: areaPoints[len(areaPoints)-1].X,
Y: bottomY,
}, Point{
X: areaPoints[0].X,
Y: bottomY,
}, areaPoints[0])
seriesPainter.SetDrawingStyle(Style{
FillColor: seriesColor.WithAlpha(200),
})
seriesPainter.FillArea(areaPoints)
}
seriesPainter.SetDrawingStyle(drawingStyle)
// 画线 // 画线
seriesPainter.LineStroke(points) seriesPainter.LineStroke(points)