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].Value.([]float64)[0], data[0].Value.([]float64)[0] minY, maxY := data[0].Value.([]float64)[1], data[0].Value.([]float64)[1] for _, datum := range data { 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) scatter := charts.NewScatter() scatter.SetGlobalOptions( 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: false}), 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, }), ) scatter.AddSeries(y, data) buff := bytes.NewBuffer(nil) 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) }