diff --git a/axis.go b/axis.go index 762a6a2..af104a8 100644 --- a/axis.go +++ b/axis.go @@ -176,7 +176,6 @@ func (a *axisPainter) Render() (Box, error) { unit := opt.Unit if unit <= 0 { - unit = ceilFloatToInt(float64(dataCount) / float64(fitTextCount)) unit = chart.MaxInt(unit, opt.SplitNumber) // 偶数 diff --git a/axis_test.go b/axis_test.go index d0cff41..a04024d 100644 --- a/axis_test.go +++ b/axis_test.go @@ -53,7 +53,7 @@ func TestAxis(t *testing.T) { }).Render() return p.Bytes() }, - result: "\\nMonTueWedThuFriSatSun", + result: "\\nMonTueWedThuFriSatSun", }, // 底部x轴文本居左 { @@ -72,7 +72,7 @@ func TestAxis(t *testing.T) { }).Render() return p.Bytes() }, - result: "\\nMonTueWedThuFriSatSun", + result: "\\nMonTueWedThuFriSatSun", }, // 左侧y轴 { @@ -155,7 +155,7 @@ func TestAxis(t *testing.T) { }).Render() return p.Bytes() }, - result: "\\nMon --Tue --Wed --Thu --Fri --Sat --Sun --", + result: "\\nMon --Tue --Wed --Thu --Fri --Sat --Sun --", }, } diff --git a/bar_chart_test.go b/bar_chart_test.go index e1522d6..aec6428 100644 --- a/bar_chart_test.go +++ b/bar_chart_test.go @@ -102,7 +102,7 @@ func TestBarChart(t *testing.T) { } return p.Bytes() }, - result: "\\n24020016012080400FebMayAugNov24.9723.225.676.7135.6162.232.6206.43.32.65.9926.428.770.7175.6182.248.718.862.3", + result: "\\n24020016012080400JanAprJulSepDec24.9723.225.676.7135.6162.232.6206.43.32.65.9926.428.770.7175.6182.248.718.862.3", }, } diff --git a/chart_option_test.go b/chart_option_test.go index ff17750..b7f4e93 100644 --- a/chart_option_test.go +++ b/chart_option_test.go @@ -204,7 +204,7 @@ func TestLineRender(t *testing.T) { assert.Nil(err) data, err := p.Bytes() assert.Nil(err) - assert.Equal("\\nEmailUnion AdsVideo AdsDirectSearch EngineLine1.44k1.2k9607204802400MonTueWedThuFriSatSun", string(data)) + assert.Equal("\\nEmailUnion AdsVideo AdsDirectSearch EngineLine1.44k1.2k9607204802400MonTueWedThuFriSatSun", string(data)) } func TestBarRender(t *testing.T) { @@ -277,7 +277,7 @@ func TestBarRender(t *testing.T) { assert.Nil(err) data, err := p.Bytes() assert.Nil(err) - assert.Equal("\\nRainfallEvaporation24020016012080400FebMayAugNov162.22182.22.341.6248.07", string(data)) + assert.Equal("\\nRainfallEvaporation24020016012080400JanAprJulSepDec162.22182.22.341.6248.07", string(data)) } func TestHorizontalBarRender(t *testing.T) { @@ -326,7 +326,7 @@ func TestHorizontalBarRender(t *testing.T) { assert.Nil(err) data, err := p.Bytes() assert.Nil(err) - assert.Equal("\\n20112012World PopulationWorldChinaIndiaUSAIndonesiaBrazil0122.28k244.56k366.84k489.12k611.4k733.68k", string(data)) + assert.Equal("\\n20112012World PopulationWorldChinaIndiaUSAIndonesiaBrazil0122.28k244.56k366.84k489.12k611.4k733.68k", string(data)) } func TestPieRender(t *testing.T) { diff --git a/echarts_test.go b/echarts_test.go index 2ce1715..dd7562f 100644 --- a/echarts_test.go +++ b/echarts_test.go @@ -578,5 +578,5 @@ func TestRenderEChartsToSVG(t *testing.T) { ] }`) assert.Nil(err) - assert.Equal("\\nRainfallEvaporationRainfall vs EvaporationFake Data24020016012080400FebMayAugNov162.22182.22.341.6248.07", string(data)) + assert.Equal("\\nRainfallEvaporationRainfall vs EvaporationFake Data24020016012080400JanAprJulSepDec162.22182.22.341.6248.07", string(data)) } diff --git a/horizontal_bar_chart_test.go b/horizontal_bar_chart_test.go index e078c4a..78f3e69 100644 --- a/horizontal_bar_chart_test.go +++ b/horizontal_bar_chart_test.go @@ -83,7 +83,7 @@ func TestHorizontalBarChart(t *testing.T) { } return p.Bytes() }, - result: "\\n20112012World PopulationWorldChinaIndiaUSAIndonesiaBrazil0122.28k244.56k366.84k489.12k611.4k733.68k", + result: "\\n20112012World PopulationWorldChinaIndiaUSAIndonesiaBrazil0122.28k244.56k366.84k489.12k611.4k733.68k", }, } for _, tt := range tests { diff --git a/line_chart_test.go b/line_chart_test.go index e169f90..e8bc1d7 100644 --- a/line_chart_test.go +++ b/line_chart_test.go @@ -117,7 +117,7 @@ func TestLineChart(t *testing.T) { } return p.Bytes() }, - result: "\\nEmailUnion AdsVideo AdsDirectSearch EngineLine1.44k1.2k9607204802400MonTueWedThuFriSatSun", + result: "\\nEmailUnion AdsVideo AdsDirectSearch EngineLine1.44k1.2k9607204802400MonTueWedThuFriSatSun", }, { render: func(p *Painter) ([]byte, error) { @@ -201,7 +201,7 @@ func TestLineChart(t *testing.T) { } return p.Bytes() }, - result: "\\nEmailUnion AdsVideo AdsDirectSearch EngineLine1.44k1.2k9607204802400MonTueWedThuFriSatSun", + result: "\\nEmailUnion AdsVideo AdsDirectSearch EngineLine1.44k1.2k9607204802400MonTueWedThuFriSatSun", }, } diff --git a/painter.go b/painter.go index 18496fd..d74b80d 100644 --- a/painter.go +++ b/painter.go @@ -615,6 +615,20 @@ func (p *Painter) TextFit(body string, x, y, width int, textAligns ...string) ch return output } +func isTick(totalRange int, unit int, index int) bool { + numTicks := (totalRange / unit) + 1 + step := float64(totalRange-1) / float64(numTicks-1) + for i := int(float64(index) / step); i < numTicks; i++ { + value := int((float64(i) * step) + 0.5) + if value == index { + return true + } else if value > index { + break + } + } + return false +} + func (p *Painter) Ticks(opt TicksOption) *Painter { if opt.Count <= 0 || opt.Length <= 0 { return p @@ -638,7 +652,7 @@ func (p *Painter) Ticks(opt TicksOption) *Painter { if index < first { continue } - if (index-first)%unit != 0 { + if ! isTick(len(values), unit, index) { continue } if isVertical { @@ -674,15 +688,13 @@ func (p *Painter) MultiText(opt MultiTextOption) *Painter { } count := len(opt.TextList) positionCenter := true - showIndex := opt.Unit / 2 + tickLimit := true if containsString([]string{ PositionLeft, PositionTop, }, opt.Position) { positionCenter = false count-- - // 非居中 - showIndex = 0 } width := p.Width() height := p.Height() @@ -690,6 +702,7 @@ func (p *Painter) MultiText(opt MultiTextOption) *Painter { isVertical := opt.Orient == OrientVertical if isVertical { values = autoDivide(height, count) + tickLimit = false } else { values = autoDivide(width, count) } @@ -699,7 +712,7 @@ func (p *Painter) MultiText(opt MultiTextOption) *Painter { if index < opt.First { continue } - if opt.Unit != 0 && (index-opt.First)%opt.Unit != showIndex { + if opt.Unit != 0 && tickLimit && ! isTick(len(opt.TextList)-opt.First, opt.Unit, index-opt.First) { continue } if isTextRotation { @@ -724,7 +737,11 @@ func (p *Painter) MultiText(opt MultiTextOption) *Painter { x = 0 } } else { - x = start - box.Width()>>1 + if index == len(opt.TextList) - 1 { + x = start - box.Width() + 10 + } else { + x = start - box.Width()>>1 + } } x += offset.Left y += offset.Top @@ -749,7 +766,6 @@ func (p *Painter) Grid(opt GridOption) *Painter { x1 := 0 y1 := 0 if isVertical { - x0 = v x1 = v y1 = height diff --git a/xaxis.go b/xaxis.go index 61698d7..5557015 100644 --- a/xaxis.go +++ b/xaxis.go @@ -40,7 +40,7 @@ type XAxisOption struct { FontSize float64 // The flag for show axis, set this to *false will hide axis Show *bool - // Number of segments that the axis is split into. Note that this number serves only as a recommendation. + // Number of segments that the axis is split into. Note that this number serves only as a recommendation to avoid writing overlap. SplitNumber int // The position of axis, it can be 'top' or 'bottom' Position string @@ -55,6 +55,8 @@ type XAxisOption struct { // The offset of label LabelOffset Box isValueAxis bool + // This value overrides SplitNumber, specifying directly the frequency at which the axis is split into, higher numbers result in less ticks + Unit int } const defaultXAxisHeight = 30 @@ -90,6 +92,7 @@ func (opt *XAxisOption) ToAxisOption() AxisOption { TextRotation: opt.TextRotation, LabelOffset: opt.LabelOffset, FirstAxis: opt.FirstAxis, + Unit: opt.Unit, } if opt.isValueAxis { axisOpt.SplitLineShow = true