refactor: support custom value formatter
This commit is contained in:
parent
74a47a9858
commit
a88e607bfc
8 changed files with 30 additions and 4 deletions
|
|
@ -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(),
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -188,6 +188,7 @@ 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{
|
||||||
|
Painter: p,
|
||||||
Min: min,
|
Min: min,
|
||||||
Max: max,
|
Max: max,
|
||||||
// 高度需要减去x轴的高度
|
// 高度需要减去x轴的高度
|
||||||
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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(),
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -40,6 +42,7 @@ type Painter struct {
|
||||||
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,
|
||||||
|
|
|
||||||
9
range.go
9
range.go
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue