feat: support to set the first axis
This commit is contained in:
parent
29a5ece545
commit
20e8d4a078
4 changed files with 102 additions and 2 deletions
4
axis.go
4
axis.go
|
|
@ -63,6 +63,8 @@ type AxisOption struct {
|
|||
StrokeWidth float64
|
||||
// The length of the axis tick
|
||||
TickLength int
|
||||
// The first axis
|
||||
FirstAxis int
|
||||
// The margin value of label
|
||||
LabelMargin int
|
||||
// The font size of label
|
||||
|
|
@ -255,6 +257,7 @@ func (a *axisPainter) Render() (Box, error) {
|
|||
Length: tickLength,
|
||||
Unit: unit,
|
||||
Orient: orient,
|
||||
First: opt.FirstAxis,
|
||||
})
|
||||
p.LineStroke([]Point{
|
||||
{
|
||||
|
|
@ -273,6 +276,7 @@ func (a *axisPainter) Render() (Box, error) {
|
|||
Top: labelPaddingTop,
|
||||
Right: labelPaddingRight,
|
||||
})).MultiText(MultiTextOption{
|
||||
First: opt.FirstAxis,
|
||||
Align: textAlign,
|
||||
TextList: data,
|
||||
Orient: orient,
|
||||
|
|
|
|||
82
examples/time_line_chart/main.go
Normal file
82
examples/time_line_chart/main.go
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/vicanso/go-charts/v2"
|
||||
)
|
||||
|
||||
func writeFile(buf []byte) error {
|
||||
tmpPath := "./tmp"
|
||||
err := os.MkdirAll(tmpPath, 0700)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
file := filepath.Join(tmpPath, "time-line-chart.png")
|
||||
err = ioutil.WriteFile(file, buf, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
xAxisValue := []string{}
|
||||
values := []float64{}
|
||||
now := time.Now()
|
||||
firstAxis := 0
|
||||
for i := 0; i < 300; i++ {
|
||||
// 设置首个axis为xx:00的时间点
|
||||
if firstAxis == 0 && now.Minute() == 0 {
|
||||
firstAxis = i
|
||||
}
|
||||
xAxisValue = append(xAxisValue, now.Format("15:04"))
|
||||
now = now.Add(time.Minute)
|
||||
value, _ := rand.Int(rand.Reader, big.NewInt(100))
|
||||
values = append(values, float64(value.Int64()))
|
||||
}
|
||||
p, err := charts.LineRender(
|
||||
[][]float64{
|
||||
values,
|
||||
},
|
||||
charts.TitleTextOptionFunc("Line"),
|
||||
charts.XAxisDataOptionFunc(xAxisValue, charts.FalseFlag()),
|
||||
charts.LegendLabelsOptionFunc([]string{
|
||||
"Demo",
|
||||
}, "50"),
|
||||
func(opt *charts.ChartOption) {
|
||||
opt.XAxis.FirstAxis = firstAxis
|
||||
// 必须要比计算得来的最小值更大(每60分钟)
|
||||
opt.XAxis.SplitNumber = 60
|
||||
opt.Legend.Padding = charts.Box{
|
||||
Top: 5,
|
||||
Bottom: 10,
|
||||
}
|
||||
opt.SymbolShow = charts.FalseFlag()
|
||||
opt.LineStrokeWidth = 1
|
||||
opt.ValueFormatter = func(f float64) string {
|
||||
return fmt.Sprintf("%.0f", f)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
buf, err := p.Bytes()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = writeFile(buf)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
15
painter.go
15
painter.go
|
|
@ -59,6 +59,8 @@ type PainterOptions struct {
|
|||
type PainterOption func(*Painter)
|
||||
|
||||
type TicksOption struct {
|
||||
// the first tick
|
||||
First int
|
||||
Length int
|
||||
Orient string
|
||||
Count int
|
||||
|
|
@ -74,6 +76,8 @@ type MultiTextOption struct {
|
|||
// The text rotation of label
|
||||
TextRotation float64
|
||||
Offset Box
|
||||
// The first text index
|
||||
First int
|
||||
}
|
||||
|
||||
type GridOption struct {
|
||||
|
|
@ -616,6 +620,7 @@ func (p *Painter) Ticks(opt TicksOption) *Painter {
|
|||
return p
|
||||
}
|
||||
count := opt.Count
|
||||
first := opt.First
|
||||
width := p.Width()
|
||||
height := p.Height()
|
||||
unit := 1
|
||||
|
|
@ -630,7 +635,10 @@ func (p *Painter) Ticks(opt TicksOption) *Painter {
|
|||
values = autoDivide(width, count)
|
||||
}
|
||||
for index, value := range values {
|
||||
if index%unit != 0 {
|
||||
if index < first {
|
||||
continue
|
||||
}
|
||||
if (index-first)%unit != 0 {
|
||||
continue
|
||||
}
|
||||
if isVertical {
|
||||
|
|
@ -688,7 +696,10 @@ func (p *Painter) MultiText(opt MultiTextOption) *Painter {
|
|||
isTextRotation := opt.TextRotation != 0
|
||||
offset := opt.Offset
|
||||
for index, text := range opt.TextList {
|
||||
if opt.Unit != 0 && index%opt.Unit != showIndex {
|
||||
if index < opt.First {
|
||||
continue
|
||||
}
|
||||
if opt.Unit != 0 && (index-opt.First)%opt.Unit != showIndex {
|
||||
continue
|
||||
}
|
||||
if isTextRotation {
|
||||
|
|
|
|||
3
xaxis.go
3
xaxis.go
|
|
@ -50,6 +50,8 @@ type XAxisOption struct {
|
|||
FontColor Color
|
||||
// The text rotation of label
|
||||
TextRotation float64
|
||||
// The first axis
|
||||
FirstAxis int
|
||||
// The offset of label
|
||||
LabelOffset Box
|
||||
isValueAxis bool
|
||||
|
|
@ -87,6 +89,7 @@ func (opt *XAxisOption) ToAxisOption() AxisOption {
|
|||
SplitLineColor: opt.Theme.GetAxisSplitLineColor(),
|
||||
TextRotation: opt.TextRotation,
|
||||
LabelOffset: opt.LabelOffset,
|
||||
FirstAxis: opt.FirstAxis,
|
||||
}
|
||||
if opt.isValueAxis {
|
||||
axisOpt.SplitLineShow = true
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue