refactor: support custom value formatter

This commit is contained in:
vicanso 2022-10-21 20:37:09 +08:00
parent 74a47a9858
commit a88e607bfc
8 changed files with 30 additions and 4 deletions

View file

@ -69,6 +69,7 @@ func (b *barChart) render(result *defaultRenderResult, seriesList SeriesList) (B
seriesPainter := result.seriesPainter seriesPainter := result.seriesPainter
xRange := NewRange(AxisRangeOption{ xRange := NewRange(AxisRangeOption{
Painter: b.p,
DivideCount: len(opt.XAxis.Data), DivideCount: len(opt.XAxis.Data),
Size: seriesPainter.Width(), Size: seriesPainter.Width(),
}) })

View file

@ -74,6 +74,8 @@ type ChartOption struct {
FillArea bool FillArea bool
// The child charts // The child charts
Children []ChartOption Children []ChartOption
// The value formatter
ValueFormatter ValueFormatter
} }
// OptionFunc option function // OptionFunc option function

View file

@ -188,8 +188,9 @@ func defaultRender(p *Painter, opt defaultRenderOption) (*defaultRenderResult, e
} }
max, min := opt.SeriesList.GetMaxMin(index) max, min := opt.SeriesList.GetMaxMin(index)
r := NewRange(AxisRangeOption{ r := NewRange(AxisRangeOption{
Min: min, Painter: p,
Max: max, Min: min,
Max: max,
// 高度需要减去x轴的高度 // 高度需要减去x轴的高度
Size: rangeHeight, Size: rangeHeight,
// 分隔数量 // 分隔数量
@ -287,6 +288,9 @@ func Render(opt ChartOption, opts ...OptionFunc) (*Painter, error) {
opt.Parent = p opt.Parent = p
} }
p := opt.Parent p := opt.Parent
if opt.ValueFormatter != nil {
p.valueFormatter = opt.ValueFormatter
}
if !opt.Box.IsZero() { if !opt.Box.IsZero() {
p = p.Child(PainterBoxOption(opt.Box)) p = p.Child(PainterBoxOption(opt.Box))
} }

View file

@ -1,6 +1,7 @@
package main package main
import ( import (
"fmt"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
@ -98,6 +99,9 @@ func main() {
} }
opt.SymbolShow = charts.FalseFlag() opt.SymbolShow = charts.FalseFlag()
opt.LineStrokeWidth = 1 opt.LineStrokeWidth = 1
opt.ValueFormatter = func(f float64) string {
return fmt.Sprintf("%.0f", f)
}
}, },
) )

View file

@ -93,6 +93,7 @@ func (h *horizontalBarChart) render(result *defaultRenderResult, seriesList Seri
max, min := seriesList.GetMaxMin(0) max, min := seriesList.GetMaxMin(0)
xRange := NewRange(AxisRangeOption{ xRange := NewRange(AxisRangeOption{
Painter: p,
Min: min, Min: min,
Max: max, Max: max,
DivideCount: defaultAxisDivideCount, DivideCount: defaultAxisDivideCount,

View file

@ -55,6 +55,7 @@ func TestMarkLine(t *testing.T) {
StrokeColor: drawing.ColorBlack, StrokeColor: drawing.ColorBlack,
Series: series, Series: series,
Range: NewRange(AxisRangeOption{ Range: NewRange(AxisRangeOption{
Painter: p,
Min: 0, Min: 0,
Max: 5, Max: 5,
Size: p.Height(), Size: p.Height(),

View file

@ -31,6 +31,8 @@ import (
"github.com/wcharczuk/go-chart/v2" "github.com/wcharczuk/go-chart/v2"
) )
type ValueFormatter func(float64) string
type Painter struct { type Painter struct {
render chart.Renderer render chart.Renderer
box Box box Box
@ -39,7 +41,8 @@ type Painter struct {
style Style style Style
theme ColorPalette theme ColorPalette
// 类型 // 类型
outputType string outputType string
valueFormatter ValueFormatter
} }
type PainterOptions struct { type PainterOptions struct {
@ -188,6 +191,9 @@ func (p *Painter) setOptions(opts ...PainterOption) {
func (p *Painter) Child(opt ...PainterOption) *Painter { func (p *Painter) Child(opt ...PainterOption) *Painter {
child := &Painter{ child := &Painter{
// 格式化
valueFormatter: p.valueFormatter,
// render
render: p.render, render: p.render,
box: p.box.Clone(), box: p.box.Clone(),
font: p.font, font: p.font,

View file

@ -29,6 +29,7 @@ import (
const defaultAxisDivideCount = 6 const defaultAxisDivideCount = 6
type axisRange struct { type axisRange struct {
p *Painter
divideCount int divideCount int
min float64 min float64
max float64 max float64
@ -37,6 +38,7 @@ type axisRange struct {
} }
type AxisRangeOption struct { type AxisRangeOption struct {
Painter *Painter
// The min value of axis // The min value of axis
Min float64 Min float64
// The max value of axis // The max value of axis
@ -93,6 +95,7 @@ func NewRange(opt AxisRangeOption) axisRange {
max = float64(ceilFloatToInt(expectMax)) max = float64(ceilFloatToInt(expectMax))
} }
return axisRange{ return axisRange{
p: opt.Painter,
divideCount: divideCount, divideCount: divideCount,
min: min, min: min,
max: max, max: max,
@ -105,9 +108,13 @@ func NewRange(opt AxisRangeOption) axisRange {
func (r axisRange) Values() []string { func (r axisRange) Values() []string {
offset := (r.max - r.min) / float64(r.divideCount) offset := (r.max - r.min) / float64(r.divideCount)
values := make([]string, 0) values := make([]string, 0)
formatter := commafWithDigits
if r.p != nil && r.p.valueFormatter != nil {
formatter = r.p.valueFormatter
}
for i := 0; i <= r.divideCount; i++ { for i := 0; i <= r.divideCount; i++ {
v := r.min + float64(i)*offset v := r.min + float64(i)*offset
value := commafWithDigits(v) value := formatter(v)
values = append(values, value) values = append(values, value)
} }
return values return values