charts/main.go

124 lines
2.7 KiB
Go

package main
import (
"bytes"
"context"
"fmt"
"log"
"os"
"os/signal"
"github.com/go-echarts/go-echarts/v2/charts"
"github.com/go-echarts/go-echarts/v2/opts"
)
func main() {
ctx, can := signal.NotifyContext(context.Background())
defer can()
if err := run(ctx); err != nil {
panic(err)
}
}
func run(ctx context.Context) error {
config, err := newConfig()
if err != nil {
return err
}
log.Printf("%+v", config)
x, y, data, err := config.Data.AsScatterData()
if err != nil {
return err
}
log.Printf("%s: (%s, %s) = %v", config.Data.Title, x, y, data)
minX, maxX := data[0][0].Value.([]float64)[0], data[0][0].Value.([]float64)[0]
minY, maxY := data[0][0].Value.([]float64)[1], data[0][0].Value.([]float64)[1]
for _, series := range data {
for _, datum := range series {
x := datum.Value.([]float64)[0]
if x < minX {
minX = x
} else if x > maxX {
maxX = x
}
y := datum.Value.([]float64)[1]
if y < minY {
minY = y
} else if y > maxY {
maxY = y
}
}
}
if 0 <= minX && minX <= 1 {
minX = 0
} else if 1 <= minX {
minX -= 1
maxX += 1
}
if 0 <= minY && minY <= 1 {
minY = 0
} else if 1 <= minY {
minY -= 1
maxY += 1
}
log.Printf("x=[%v, %v] y=[%v, %v]", minX, maxX, minY, maxY)
globalOpts := []charts.GlobalOpts{
charts.WithTitleOpts(opts.Title{
Title: config.Data.Title,
Subtitle: config.Data.Subtitle,
}),
charts.WithTooltipOpts(opts.Tooltip{
Show: true,
Formatter: `{c}`,
}),
charts.WithLegendOpts(opts.Legend{Show: true}),
charts.WithXAxisOpts(opts.XAxis{
Name: x,
NameLocation: "middle",
NameGap: config.Data.Weight.Floor + config.Data.Weight.Range,
Min: minX,
Max: maxX,
}),
charts.WithYAxisOpts(opts.YAxis{
Name: y,
NameLocation: "middle",
NameGap: config.Data.Weight.Floor + config.Data.Weight.Range,
Min: minY,
Max: maxY,
}),
}
buff := bytes.NewBuffer(nil)
switch config.Graph.Type {
case "line":
line := charts.NewLine()
line.SetGlobalOptions(globalOpts...)
for i, series := range scatterAsLineData(data) {
line.AddSeries(fmt.Sprintf("%s[%d]", y, i), series)
}
if err := line.Render(buff); err != nil {
return err
}
case "scatter":
scatter := charts.NewScatter()
scatter.SetGlobalOptions(globalOpts...)
for i, series := range data {
scatter.AddSeries(fmt.Sprintf("%s[%d]", y, i), series)
}
if err := scatter.Render(buff); err != nil {
return err
}
}
switch config.Output.Scheme {
case "file":
return os.WriteFile(config.Output.Path, buff.Bytes(), os.ModePerm)
}
return fmt.Errorf("not impl output scheme: %s", config.Output.Scheme)
}