需求
邮件中实现统计信息的发送。统计信息以折线图、饼图、柱状图的形式展示。因为邮件中无法支持js解析,所以采用go-chart生成PNG图片后base64编码后发送。
<img src="https://img-blog.csdnimg.cn/2022010623010187796.png">
go-chart实战
go-chart是个强大的go生成图片的库,但是采用默认配置生成线条较多或者文本过长的图片时,无法完美适应。默认不支持中文。但是里面的属性大多可自己定义,整体来说非常强大。
代码
package charter
import (
"bytes"
"encoding/base64"
"fmt"
"math/rand"
"os"
"time"
"github.com/wcharczuk/go-chart"
"github.com/wcharczuk/go-chart/drawing"
)
const (
lineChartXAxisName = "Date"
lineChartYAxisName = "Count"
lineChartHeight = 700
lineChartWidth = 1280
colorMultiplier = 256
imgStrPrefix = "data:image/png;base64,"
pieLabelFormat = "%v %v"
barChartTryAgainErr = "invalid data range; cannot be zero"
)
var (
lineChartStyle = chart.Style{
Padding: chart.Box{
Top: 30,
Left: 150,
},
}
defaultChartStyle = chart.Style{
Padding: chart.Box{
Top: 30,
},
}
timeFormat = chart.TimeDateValueFormatter
)
type LineYValue struct {
Name string
Values []float64
}
type ChartValue struct {
Name string
Value float64
}
// createLineChart 创建线性图
func createLineChart(title string, endTime time.Time, values []LineYValue) (img string, err error) {
if len(values) == 0 {
return
}
// 1、计算X轴
lenX := len(values[0].Values)
// X轴内容xValues 及 X轴坐标ticks
var xValues []time.Time
var ticks []chart.Tick
for i := lenX - 1; i >= 0; i-- {
curTime := endTime.AddDate(0, 0, -i)
xValues = append(xValues, curTime)
ticks = append(ticks, chart.Tick{Value: getNsec(curTime), Label: timeFormat(curTime)})
}
// 2、生成Series
var series []chart.Series
for _, yValue := range val