forked from all_user/stat_center
163 lines
3.8 KiB
Go
163 lines
3.8 KiB
Go
package statutils
|
|
|
|
import (
|
|
_ "embed"
|
|
"os"
|
|
"strings"
|
|
|
|
"golang.org/x/exp/slices"
|
|
|
|
"github.com/vicanso/go-charts/v2"
|
|
"github.com/wcharczuk/go-chart/v2/drawing"
|
|
|
|
"github.com/golang/freetype"
|
|
|
|
"github.com/golang/freetype/truetype"
|
|
)
|
|
|
|
//go:embed 微软雅黑.ttf
|
|
var FontData []byte
|
|
var Font *truetype.Font
|
|
|
|
func init() {
|
|
f, err := freetype.ParseFont(FontData)
|
|
if err == nil {
|
|
Font = f
|
|
}
|
|
}
|
|
|
|
func (s *Stat) Table(title string, div int64, compare *Stat, filePath string) error {
|
|
if div == 0 {
|
|
div = 1
|
|
}
|
|
rows := make([][]string, 0)
|
|
if compare != nil {
|
|
rows = append(rows, s.Android.Row("安卓", div, &compare.Android))
|
|
rows = append(rows, s.Ios.Row("苹果", div, &compare.Ios))
|
|
rows = append(rows, s.Light.Rows(div, &compare.Light)...)
|
|
rows = append(rows, s.H5.Rows(div, &compare.H5)...)
|
|
rows = append(rows, s.Total.Row("合计", div, &compare.Total))
|
|
} else {
|
|
rows = append(rows, s.Android.Row("安卓", div, nil))
|
|
rows = append(rows, s.Ios.Row("苹果", div, nil))
|
|
rows = append(rows, s.Light.Rows(div, nil)...)
|
|
rows = append(rows, s.H5.Rows(div, nil)...)
|
|
rows = append(rows, s.Total.Row("合计", div, nil))
|
|
}
|
|
|
|
charts.SetDefaultWidth(810)
|
|
bgColor := drawing.ColorWhite
|
|
p, err := charts.TableOptionRender(charts.TableChartOption{
|
|
Header: s.Total.Header(title),
|
|
BackgroundColor: bgColor,
|
|
HeaderBackgroundColor: drawing.ColorFromHex("808080"),
|
|
RowBackgroundColors: []charts.Color{
|
|
bgColor,
|
|
},
|
|
HeaderFontColor: drawing.ColorBlack,
|
|
FontColor: drawing.ColorBlack,
|
|
Padding: charts.Box{
|
|
Top: 15,
|
|
Right: 10,
|
|
Bottom: 15,
|
|
Left: 10,
|
|
},
|
|
Data: rows,
|
|
Font: Font,
|
|
TextAligns: []string{
|
|
charts.AlignCenter,
|
|
charts.AlignLeft,
|
|
},
|
|
CellStyle: func(tc charts.TableCell) *charts.Style {
|
|
text := strings.TrimSpace(tc.Text)
|
|
style := &charts.Style{
|
|
Padding: charts.Box{
|
|
Bottom: 5,
|
|
},
|
|
}
|
|
if strings.Contains(text, "-") {
|
|
style.FontColor = drawing.ColorRed
|
|
} else if strings.Contains(text, "+") {
|
|
style.FontColor = drawing.ColorGreen
|
|
}
|
|
|
|
if slices.Contains([]int{1, 2, 3}, tc.Row) {
|
|
style.FillColor = drawing.ColorFromHex("ec8f75")
|
|
} else if slices.Contains([]int{4, 5, 6}, tc.Row) {
|
|
style.FillColor = drawing.ColorFromHex("788fc7")
|
|
} else if slices.Contains([]int{7, 8}, tc.Row) {
|
|
style.FillColor = drawing.ColorFromHex("ced6d2")
|
|
} else if slices.Contains([]int{9}, tc.Row) {
|
|
style.FillColor = drawing.ColorFromHex("808080")
|
|
}
|
|
return style
|
|
},
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
buf, err := p.Bytes()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return WriteBytesToFile(buf, filePath)
|
|
}
|
|
|
|
func WriteBytesToFile(buf []byte, filename string) error {
|
|
err := os.WriteFile(filename, buf, 0600)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func CommonTable(headers []string, rows [][]string, tableWidth int, filePath string) error {
|
|
charts.SetDefaultWidth(tableWidth)
|
|
bgColor := drawing.ColorWhite
|
|
p, err := charts.TableOptionRender(charts.TableChartOption{
|
|
Header: headers,
|
|
BackgroundColor: bgColor,
|
|
HeaderBackgroundColor: drawing.ColorFromHex("808080"),
|
|
RowBackgroundColors: []charts.Color{
|
|
bgColor,
|
|
},
|
|
HeaderFontColor: drawing.ColorBlack,
|
|
FontColor: drawing.ColorBlack,
|
|
Padding: charts.Box{
|
|
Top: 15,
|
|
Right: 10,
|
|
Bottom: 15,
|
|
Left: 10,
|
|
},
|
|
Data: rows,
|
|
Font: Font,
|
|
TextAligns: []string{
|
|
charts.AlignCenter,
|
|
charts.AlignLeft,
|
|
},
|
|
CellStyle: func(tc charts.TableCell) *charts.Style {
|
|
style := &charts.Style{
|
|
Padding: charts.Box{
|
|
Bottom: 5,
|
|
},
|
|
}
|
|
if tc.Row%2 == 0 {
|
|
style.FillColor = drawing.ColorFromHex("f8f8f8")
|
|
} else {
|
|
style.FillColor = drawing.ColorWhite
|
|
}
|
|
return style
|
|
},
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
buf, err := p.Bytes()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return WriteBytesToFile(buf, filePath)
|
|
}
|