From 7c1c0670db15eaafd6f44235bef16fa9068de3a9 Mon Sep 17 00:00:00 2001 From: shoopea Date: Mon, 6 Dec 2021 21:55:59 +0800 Subject: [PATCH] update graphs --- bot.go | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++++- version.go | 8 +-- 2 files changed, 183 insertions(+), 6 deletions(-) diff --git a/bot.go b/bot.go index 99d9bf1..1835cdc 100644 --- a/bot.go +++ b/bot.go @@ -108,6 +108,8 @@ func (b *Bot) BotHandlers() { b.bot.Handle("/transfer", botTransfer) b.bot.Handle("/value", botGraphValue) + b.bot.Handle("/value_delta", botGraphValueDelta) + b.bot.Handle("/planes", botGraphPlanes) b.bot.Handle(tb.OnPhoto, botPhoto) b.bot.Handle(tb.OnChannelPost, botChannelPost) @@ -948,7 +950,7 @@ func botGraphValue(m *tb.Message) { cc := cfg.GetCompanyClient(coID) l, s, err := plotter.NewLinePoints(xys) - logErrorDebug(err, "Stats.ValueGraph : plotter.NewLinePoints") + logErrorDebug(err, "botGraphValue : plotter.NewLinePoints") if err != nil { bot.SendChat(m.Chat.ID, fmt.Sprintf("plotter.NewLinePoints : %s", err)) return @@ -967,7 +969,182 @@ func botGraphValue(m *tb.Message) { } err := p.Save(6*vg.Inch, 4*vg.Inch, "/app/data/points.png") - logErrorDebug(err, "Stats.ValueGraph : plot.Save") + logErrorDebug(err, "botGraphValue : plot.Save") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("plot.Save : %s", err)) + return + } + + bot.SendChatImage(m.Chat.ID, "/app/data/points.png") + + return +} + +func botGraphValueDelta(m *tb.Message) { + var ( + maxVal float64 + unitFactor float64 + unitName string + ) + + var vals map[uint8]plotter.XYs + vals = make(map[uint8]plotter.XYs) + for coID, dStats := range cfg.Stats { + if cfg.CompanyIsRegistered(coID) { + vals[coID] = make(plotter.XYs, 0) + for dStr, stat := range dStats { + d, err := time.Parse("20060102", dStr) + logErrorDebug(err, "botGraphValueDelta : time.Parse") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("time.Parse : %s", err)) + return + } + dateFloat := float64(d.Year()) + float64(d.Month()-1)/12 + valueFloat := float64(stat.CompanyValueLastQuarter) + pt := plotter.XY{ + X: dateFloat, + Y: valueFloat / unitFactor, + } + vals[coID] = append(vals[coID], pt) + } + sort.Slice(vals[coID], func(i, j int) bool { return vals[coID][i].X < vals[coID][j].X }) + } + } + + for coID, v := range vals { + for i := 1; i < len(vals); i++ { + v[i].Y = v[i].Y - v[i-1].Y + if math.Abs(v[i].Y) > maxVal { + maxVal = math.Abs(v[i].Y) + } + } + vals[coID] = v[1:] + } + + if maxVal > 1000000000 { + unitFactor = 1000000000 + unitName = "billion" + } else if maxVal > 1000000 { + unitFactor = 1000000 + unitName = "million" + } else { + unitFactor = 1 + unitName = "" + } + + for coID, v := range vals { + for i := 1; i < len(vals)-1; i++ { + v[i].Y = v[i].Y / unitFactor + } + vals[coID] = v + } + + p := plot.New() + p.Title.Text = "Company Values (delta)" + p.X.Label.Text = "Year" + if unitName != "" { + p.Y.Label.Text = fmt.Sprintf("Variation (%s)", unitName) + } else { + p.Y.Label.Text = "Variation" + } + + i := 0 + for coID, xys := range vals { + cc := cfg.GetCompanyClient(coID) + + l, s, err := plotter.NewLinePoints(xys) + logErrorDebug(err, "botGraphValueDelta : plotter.NewLinePoints") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("plotter.NewLinePoints : %s", err)) + return + } + + l.Color = plotutil.Color(i) + l.Dashes = plotutil.Dashes(2) + s.Color = plotutil.Color(i) + s.Shape = plotutil.Shape(0) + + p.Add(l) + p.Add(s) + p.Legend.Add(cc.Username, l, s) + + i++ + } + + err := p.Save(6*vg.Inch, 4*vg.Inch, "/app/data/points.png") + logErrorDebug(err, "botGraphValueDelta : plot.Save") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("plot.Save : %s", err)) + return + } + + bot.SendChatImage(m.Chat.ID, "/app/data/points.png") + + return +} + +func botGraphPlanes(m *tb.Message) { + var planes, airports map[uint8]plotter.XYs + planes = make(map[uint8]plotter.XYs) + airports = make(map[uint8]plotter.XYs) + for coID, dStats := range cfg.Stats { + if cfg.CompanyIsRegistered(coID) { + planes[coID] = make(plotter.XYs, 0) + for dStr, stat := range dStats { + d, err := time.Parse("20060102", dStr) + logErrorDebug(err, "botGraphPlanes : time.Parse") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("time.Parse : %s", err)) + return + } + dateFloat := float64(d.Year()) + float64(d.Month()-1)/12 + pt := plotter.XY{ + X: dateFloat, + Y: float64(stat.Planes), + } + planes[coID] = append(planes[coID], pt) + pt = plotter.XY{ + X: dateFloat, + Y: float64(stat.Airports), + } + airports[coID] = append(airports[coID], pt) + } + sort.Slice(planes[coID], func(i, j int) bool { return planes[coID][i].X < planes[coID][j].X }) + sort.Slice(airports[coID], func(i, j int) bool { return airports[coID][i].X < airports[coID][j].X }) + + } + } + + p := plot.New() + p.Title.Text = "Planes summary" + p.X.Label.Text = "Year" + p.Y.Label.Text = "Planes" + + i := 0 + for coID, xys := range planes { + cc := cfg.GetCompanyClient(coID) + + l, s, err := plotter.NewLinePoints(xys) + logErrorDebug(err, "botGraphPlanes : plotter.NewLinePoints") + if err != nil { + bot.SendChat(m.Chat.ID, fmt.Sprintf("plotter.NewLinePoints : %s", err)) + return + } + + l.Color = plotutil.Color(i) + l.Dashes = plotutil.Dashes(2) + s.Color = plotutil.Color(i) + s.Shape = plotutil.Shape(0) + + p.Add(l) + p.Add(s) + p.Legend.Add(cc.Username, l, s) + + i++ + } + + err := p.Save(6*vg.Inch, 4*vg.Inch, "/app/data/points.png") + logErrorDebug(err, "botGraphPlanes : plot.Save") if err != nil { bot.SendChat(m.Chat.ID, fmt.Sprintf("plot.Save : %s", err)) return diff --git a/version.go b/version.go index 6e931a0..32b64c7 100644 --- a/version.go +++ b/version.go @@ -1,6 +1,6 @@ // Code generated by version.sh (@generated) DO NOT EDIT. package main -var githash = "365c8a9" -var buildstamp = "2021-12-05_14:39:05" -var commits = "232" -var version = "365c8a9-b232 - 2021-12-05_14:39:05" +var githash = "c3225a7" +var buildstamp = "2021-12-06_13:54:50" +var commits = "233" +var version = "c3225a7-b233 - 2021-12-06_13:54:50"