From a88e607bfc83b27502a54879ae749050683c9123 Mon Sep 17 00:00:00 2001 From: vicanso Date: Fri, 21 Oct 2022 20:37:09 +0800 Subject: [PATCH] refactor: support custom value formatter --- bar_chart.go | 1 + chart_option.go | 2 ++ charts.go | 8 ++++++-- examples/line_chart/main.go | 4 ++++ horizontal_bar_chart.go | 1 + mark_line_test.go | 1 + painter.go | 8 +++++++- range.go | 9 ++++++++- 8 files changed, 30 insertions(+), 4 deletions(-) diff --git a/bar_chart.go b/bar_chart.go index d798c07..19c1664 100644 --- a/bar_chart.go +++ b/bar_chart.go @@ -69,6 +69,7 @@ func (b *barChart) render(result *defaultRenderResult, seriesList SeriesList) (B seriesPainter := result.seriesPainter xRange := NewRange(AxisRangeOption{ + Painter: b.p, DivideCount: len(opt.XAxis.Data), Size: seriesPainter.Width(), }) diff --git a/chart_option.go b/chart_option.go index f3bf2cb..d4605a1 100644 --- a/chart_option.go +++ b/chart_option.go @@ -74,6 +74,8 @@ type ChartOption struct { FillArea bool // The child charts Children []ChartOption + // The value formatter + ValueFormatter ValueFormatter } // OptionFunc option function diff --git a/charts.go b/charts.go index c7923f1..b66437c 100644 --- a/charts.go +++ b/charts.go @@ -188,8 +188,9 @@ func defaultRender(p *Painter, opt defaultRenderOption) (*defaultRenderResult, e } max, min := opt.SeriesList.GetMaxMin(index) r := NewRange(AxisRangeOption{ - Min: min, - Max: max, + Painter: p, + Min: min, + Max: max, // 高度需要减去x轴的高度 Size: rangeHeight, // 分隔数量 @@ -287,6 +288,9 @@ func Render(opt ChartOption, opts ...OptionFunc) (*Painter, error) { opt.Parent = p } p := opt.Parent + if opt.ValueFormatter != nil { + p.valueFormatter = opt.ValueFormatter + } if !opt.Box.IsZero() { p = p.Child(PainterBoxOption(opt.Box)) } diff --git a/examples/line_chart/main.go b/examples/line_chart/main.go index 97d5859..c1478a6 100644 --- a/examples/line_chart/main.go +++ b/examples/line_chart/main.go @@ -1,6 +1,7 @@ package main import ( + "fmt" "io/ioutil" "os" "path/filepath" @@ -98,6 +99,9 @@ func main() { } opt.SymbolShow = charts.FalseFlag() opt.LineStrokeWidth = 1 + opt.ValueFormatter = func(f float64) string { + return fmt.Sprintf("%.0f", f) + } }, ) diff --git a/horizontal_bar_chart.go b/horizontal_bar_chart.go index 8ffac44..58c6e19 100644 --- a/horizontal_bar_chart.go +++ b/horizontal_bar_chart.go @@ -93,6 +93,7 @@ func (h *horizontalBarChart) render(result *defaultRenderResult, seriesList Seri max, min := seriesList.GetMaxMin(0) xRange := NewRange(AxisRangeOption{ + Painter: p, Min: min, Max: max, DivideCount: defaultAxisDivideCount, diff --git a/mark_line_test.go b/mark_line_test.go index ef29e6f..00d19ef 100644 --- a/mark_line_test.go +++ b/mark_line_test.go @@ -55,6 +55,7 @@ func TestMarkLine(t *testing.T) { StrokeColor: drawing.ColorBlack, Series: series, Range: NewRange(AxisRangeOption{ + Painter: p, Min: 0, Max: 5, Size: p.Height(), diff --git a/painter.go b/painter.go index b7122b7..efd5045 100644 --- a/painter.go +++ b/painter.go @@ -31,6 +31,8 @@ import ( "github.com/wcharczuk/go-chart/v2" ) +type ValueFormatter func(float64) string + type Painter struct { render chart.Renderer box Box @@ -39,7 +41,8 @@ type Painter struct { style Style theme ColorPalette // 类型 - outputType string + outputType string + valueFormatter ValueFormatter } type PainterOptions struct { @@ -188,6 +191,9 @@ func (p *Painter) setOptions(opts ...PainterOption) { func (p *Painter) Child(opt ...PainterOption) *Painter { child := &Painter{ + // 格式化 + valueFormatter: p.valueFormatter, + // render render: p.render, box: p.box.Clone(), font: p.font, diff --git a/range.go b/range.go index ebd0b2d..51d3332 100644 --- a/range.go +++ b/range.go @@ -29,6 +29,7 @@ import ( const defaultAxisDivideCount = 6 type axisRange struct { + p *Painter divideCount int min float64 max float64 @@ -37,6 +38,7 @@ type axisRange struct { } type AxisRangeOption struct { + Painter *Painter // The min value of axis Min float64 // The max value of axis @@ -93,6 +95,7 @@ func NewRange(opt AxisRangeOption) axisRange { max = float64(ceilFloatToInt(expectMax)) } return axisRange{ + p: opt.Painter, divideCount: divideCount, min: min, max: max, @@ -105,9 +108,13 @@ func NewRange(opt AxisRangeOption) axisRange { func (r axisRange) Values() []string { offset := (r.max - r.min) / float64(r.divideCount) 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++ { v := r.min + float64(i)*offset - value := commafWithDigits(v) + value := formatter(v) values = append(values, value) } return values