gottdad/bot_graph.go
2021-12-12 14:31:43 +08:00

1022 lines
24 KiB
Go

package main
import (
"fmt"
"math"
"sort"
"time"
"gonum.org/v1/plot"
"gonum.org/v1/plot/plotter"
"gonum.org/v1/plot/plotutil"
"gonum.org/v1/plot/vg"
tb "gopkg.in/tucnak/telebot.v2"
)
func botGraphValue(m *tb.Message) {
var (
maxVal float64
unitFactor float64
unitName string
)
for _, dStats := range cfg.StatsMonthly {
for _, stat := range dStats {
valueFloat := float64(stat.CompanyValueLastQuarter)
if math.Abs(valueFloat) > maxVal {
maxVal = math.Abs(valueFloat)
}
}
}
if maxVal > 1000000000 {
unitFactor = 1000000000
unitName = "billion"
} else if maxVal > 1000000 {
unitFactor = 1000000
unitName = "million"
} else {
unitFactor = 1
unitName = ""
}
var vals map[int]plotter.XYs
vals = make(map[int]plotter.XYs)
for ccID, dStats := range cfg.StatsMonthly {
vals[ccID] = make(plotter.XYs, 0)
for dStr, stat := range dStats {
d, err := time.Parse("20060102", dStr)
logErrorDebug(err, "botGraphValue : 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[ccID] = append(vals[ccID], pt)
}
sort.Slice(vals[ccID], func(i, j int) bool { return vals[ccID][i].X < vals[ccID][j].X })
}
p := plot.New()
p.Title.Text = "Company Values"
p.X.Label.Text = "Year"
if unitName != "" {
p.Y.Label.Text = fmt.Sprintf("Value (%s)", unitName)
} else {
p.Y.Label.Text = "Value"
}
i := 0
for ccID, xys := range vals {
cc := cfg.Clients[ccID]
l, s, err := plotter.NewLinePoints(xys)
logErrorDebug(err, "botGraphValue : plotter.NewLinePoints")
if err != nil {
bot.SendChat(m.Chat.ID, fmt.Sprintf("plotter.NewLinePoints : %s", err))
return
}
l.Color = cfg.GetClientColor(ccID)
l.Dashes = plotutil.Dashes(2)
s.Color = cfg.GetClientColor(ccID)
s.Shape = plotutil.Shape(0)
p.Add(l)
p.Add(s)
p.Legend.Add(cc.Username, l, s)
i++
}
err := p.Save(12*vg.Inch, 8*vg.Inch, "/app/data/points.png")
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[int]plotter.XYs
vals = make(map[int]plotter.XYs)
for ccID, dStats := range cfg.StatsMonthly {
vals[ccID] = 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
}
pt := plotter.XY{
X: float64(d.Year()) + float64(d.Month()-1)/12,
Y: float64(stat.CompanyValuePreviousQuarter),
}
vals[ccID] = append(vals[ccID], pt)
}
sort.Slice(vals[ccID], func(i, j int) bool { return vals[ccID][i].X < vals[ccID][j].X })
}
for ccID, v := range vals {
v2 := make(plotter.XYs, 0)
for i := 0; i < len(v); i = i + 3 {
v2 = append(v2, v[i])
}
vals[ccID] = v2
}
for ccID, v := range vals {
v0 := v[0].Y
for i := 1; i < len(v); i++ {
v[i].Y, v0 = v[i].Y-v0, v[i].Y
if math.Abs(v[i].Y) > maxVal {
maxVal = math.Abs(v[i].Y)
}
}
vals[ccID] = v[1:]
}
if maxVal > 1000000000 {
unitFactor = 1000000000
unitName = "billion"
} else if maxVal > 1000000 {
unitFactor = 1000000
unitName = "million"
} else {
unitFactor = 1
unitName = ""
}
for ccID, v := range vals {
for i := 0; i < len(v); i++ {
v[i].Y = v[i].Y / unitFactor
if math.IsNaN(v[i].Y) {
logInfoDebug("botGraphValueDelta : NaN : %d / %f", ccID, v[i].X)
}
}
vals[ccID] = 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 ccID, xys := range vals {
cc := cfg.Clients[ccID]
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 = cfg.GetClientColor(ccID)
l.Dashes = plotutil.Dashes(2)
s.Color = cfg.GetClientColor(ccID)
s.Shape = plotutil.Shape(0)
p.Add(l)
p.Add(s)
p.Legend.Add(cc.Username, l, s)
i++
}
err := p.Save(12*vg.Inch, 8*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 botGraphDeliveries(m *tb.Message) {
var (
maxVal float64
unitFactor float64
unitName string
)
for _, dStats := range cfg.StatsMonthly {
for _, stat := range dStats {
valueFloat := float64(stat.DeliveredCargoLastQuarter)
if math.Abs(valueFloat) > maxVal {
maxVal = math.Abs(valueFloat)
}
}
}
if maxVal > 1000000000 {
unitFactor = 1000000000
unitName = "billion"
} else if maxVal > 1000000 {
unitFactor = 1000000
unitName = "million"
} else {
unitFactor = 1
unitName = ""
}
var vals map[int]plotter.XYs
vals = make(map[int]plotter.XYs)
for ccID, dStats := range cfg.StatsMonthly {
vals[ccID] = make(plotter.XYs, 0)
for dStr, stat := range dStats {
d, err := time.Parse("20060102", dStr)
logErrorDebug(err, "botGraphDeliveries : 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.DeliveredCargoLastQuarter)
pt := plotter.XY{
X: dateFloat,
Y: valueFloat / unitFactor,
}
vals[ccID] = append(vals[ccID], pt)
}
sort.Slice(vals[ccID], func(i, j int) bool { return vals[ccID][i].X < vals[ccID][j].X })
}
p := plot.New()
p.Title.Text = "Company Deliveries"
p.X.Label.Text = "Year"
if unitName != "" {
p.Y.Label.Text = fmt.Sprintf("Deliveries (%s)", unitName)
} else {
p.Y.Label.Text = "Deliveries"
}
i := 0
for ccID, xys := range vals {
cc := cfg.Clients[ccID]
l, s, err := plotter.NewLinePoints(xys)
logErrorDebug(err, "botGraphDeliveries : plotter.NewLinePoints")
if err != nil {
bot.SendChat(m.Chat.ID, fmt.Sprintf("plotter.NewLinePoints : %s", err))
return
}
l.Color = cfg.GetClientColor(ccID)
l.Dashes = plotutil.Dashes(2)
s.Color = cfg.GetClientColor(ccID)
s.Shape = plotutil.Shape(0)
p.Add(l)
p.Add(s)
p.Legend.Add(cc.Username, l, s)
i++
}
err := p.Save(12*vg.Inch, 8*vg.Inch, "/app/data/points.png")
logErrorDebug(err, "botGraphDeliveries : 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 botGraphMoney(m *tb.Message) {
var (
maxVal float64
unitFactor float64
unitName string
)
for _, dStats := range cfg.StatsMonthly {
for _, stat := range dStats {
valueFloat := float64(stat.Money)
if math.Abs(valueFloat) > maxVal {
maxVal = math.Abs(valueFloat)
}
}
}
if maxVal > 1000000000 {
unitFactor = 1000000000
unitName = "billion"
} else if maxVal > 1000000 {
unitFactor = 1000000
unitName = "million"
} else {
unitFactor = 1
unitName = ""
}
var vals map[int]plotter.XYs
vals = make(map[int]plotter.XYs)
for ccID, dStats := range cfg.StatsMonthly {
vals[ccID] = make(plotter.XYs, 0)
for dStr, stat := range dStats {
d, err := time.Parse("20060102", dStr)
logErrorDebug(err, "botGraphMoney : 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.Money)
pt := plotter.XY{
X: dateFloat,
Y: valueFloat / unitFactor,
}
vals[ccID] = append(vals[ccID], pt)
}
sort.Slice(vals[ccID], func(i, j int) bool { return vals[ccID][i].X < vals[ccID][j].X })
}
p := plot.New()
p.Title.Text = "Company Money"
p.X.Label.Text = "Year"
if unitName != "" {
p.Y.Label.Text = fmt.Sprintf("Money (%s)", unitName)
} else {
p.Y.Label.Text = "Money"
}
i := 0
for ccID, xys := range vals {
cc := cfg.Clients[ccID]
l, s, err := plotter.NewLinePoints(xys)
logErrorDebug(err, "botGraphMoney : plotter.NewLinePoints")
if err != nil {
bot.SendChat(m.Chat.ID, fmt.Sprintf("plotter.NewLinePoints : %s", err))
return
}
l.Color = cfg.GetClientColor(ccID)
l.Dashes = plotutil.Dashes(2)
s.Color = cfg.GetClientColor(ccID)
s.Shape = plotutil.Shape(0)
p.Add(l)
p.Add(s)
p.Legend.Add(cc.Username, l, s)
i++
}
err := p.Save(12*vg.Inch, 8*vg.Inch, "/app/data/points.png")
logErrorDebug(err, "botGraphMoney : 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 botGraphIncome(m *tb.Message) {
var (
maxVal float64
unitFactor float64
unitName string
)
for _, dStats := range cfg.StatsMonthly {
for _, stat := range dStats {
valueFloat := float64(stat.Income)
if math.Abs(valueFloat) > maxVal {
maxVal = math.Abs(valueFloat)
}
}
}
if maxVal > 1000000000 {
unitFactor = 1000000000
unitName = "billion"
} else if maxVal > 1000000 {
unitFactor = 1000000
unitName = "million"
} else {
unitFactor = 1
unitName = ""
}
var vals map[int]plotter.XYs
vals = make(map[int]plotter.XYs)
for ccID, dStats := range cfg.StatsMonthly {
vals[ccID] = make(plotter.XYs, 0)
for dStr, stat := range dStats {
d, err := time.Parse("20060102", dStr)
logErrorDebug(err, "botGraphIncome : 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.Income)
pt := plotter.XY{
X: dateFloat,
Y: valueFloat / unitFactor,
}
vals[ccID] = append(vals[ccID], pt)
}
sort.Slice(vals[ccID], func(i, j int) bool { return vals[ccID][i].X < vals[ccID][j].X })
}
p := plot.New()
p.Title.Text = "Company Income"
p.X.Label.Text = "Year"
if unitName != "" {
p.Y.Label.Text = fmt.Sprintf("Income (%s)", unitName)
} else {
p.Y.Label.Text = "Income"
}
i := 0
for ccID, xys := range vals {
cc := cfg.Clients[ccID]
l, s, err := plotter.NewLinePoints(xys)
logErrorDebug(err, "botGraphIncome : plotter.NewLinePoints")
if err != nil {
bot.SendChat(m.Chat.ID, fmt.Sprintf("plotter.NewLinePoints : %s", err))
return
}
l.Color = cfg.GetClientColor(ccID)
l.Dashes = plotutil.Dashes(2)
s.Color = cfg.GetClientColor(ccID)
s.Shape = plotutil.Shape(0)
p.Add(l)
p.Add(s)
p.Legend.Add(cc.Username, l, s)
i++
}
err := p.Save(12*vg.Inch, 8*vg.Inch, "/app/data/points.png")
logErrorDebug(err, "botGraphIncome : 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 botGraphLoan(m *tb.Message) {
var (
maxVal float64
unitFactor float64
unitName string
)
for _, dStats := range cfg.StatsMonthly {
for _, stat := range dStats {
valueFloat := float64(stat.Loan)
if math.Abs(valueFloat) > maxVal {
maxVal = math.Abs(valueFloat)
}
}
}
if maxVal > 1000000000 {
unitFactor = 1000000000
unitName = "billion"
} else if maxVal > 1000000 {
unitFactor = 1000000
unitName = "million"
} else {
unitFactor = 1
unitName = ""
}
var vals map[int]plotter.XYs
vals = make(map[int]plotter.XYs)
for ccID, dStats := range cfg.StatsMonthly {
vals[ccID] = make(plotter.XYs, 0)
for dStr, stat := range dStats {
d, err := time.Parse("20060102", dStr)
logErrorDebug(err, "botGraphLoan : 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.Loan)
pt := plotter.XY{
X: dateFloat,
Y: valueFloat / unitFactor,
}
vals[ccID] = append(vals[ccID], pt)
}
sort.Slice(vals[ccID], func(i, j int) bool { return vals[ccID][i].X < vals[ccID][j].X })
}
p := plot.New()
p.Title.Text = "Company Loan"
p.X.Label.Text = "Year"
if unitName != "" {
p.Y.Label.Text = fmt.Sprintf("Loan (%s)", unitName)
} else {
p.Y.Label.Text = "Loan"
}
i := 0
for ccID, xys := range vals {
cc := cfg.Clients[ccID]
l, s, err := plotter.NewLinePoints(xys)
logErrorDebug(err, "botGraphLoan : plotter.NewLinePoints")
if err != nil {
bot.SendChat(m.Chat.ID, fmt.Sprintf("plotter.NewLinePoints : %s", err))
return
}
l.Color = cfg.GetClientColor(ccID)
l.Dashes = plotutil.Dashes(2)
s.Color = cfg.GetClientColor(ccID)
s.Shape = plotutil.Shape(0)
p.Add(l)
p.Add(s)
p.Legend.Add(cc.Username, l, s)
i++
}
err := p.Save(12*vg.Inch, 8*vg.Inch, "/app/data/points.png")
logErrorDebug(err, "botGraphLoan : 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 botGraphPerf(m *tb.Message) {
var (
maxVal float64
unitFactor float64
unitName string
)
for _, dStats := range cfg.StatsMonthly {
for _, stat := range dStats {
valueFloat := float64(stat.PerformancePreviousQuarter)
if math.Abs(valueFloat) > maxVal {
maxVal = math.Abs(valueFloat)
}
}
}
if maxVal > 1000000000 {
unitFactor = 1000000000
unitName = "billion"
} else if maxVal > 1000000 {
unitFactor = 1000000
unitName = "million"
} else {
unitFactor = 1
unitName = ""
}
var vals map[int]plotter.XYs
vals = make(map[int]plotter.XYs)
for ccID, dStats := range cfg.StatsMonthly {
vals[ccID] = make(plotter.XYs, 0)
for dStr, stat := range dStats {
d, err := time.Parse("20060102", dStr)
logErrorDebug(err, "botGraphPerf : 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.PerformancePreviousQuarter)
pt := plotter.XY{
X: dateFloat,
Y: valueFloat / unitFactor,
}
vals[ccID] = append(vals[ccID], pt)
}
sort.Slice(vals[ccID], func(i, j int) bool { return vals[ccID][i].X < vals[ccID][j].X })
}
p := plot.New()
p.Title.Text = "Company Perf"
p.X.Label.Text = "Year"
if unitName != "" {
p.Y.Label.Text = fmt.Sprintf("Perf (%s)", unitName)
} else {
p.Y.Label.Text = "Perf"
}
i := 0
for ccID, xys := range vals {
cc := cfg.Clients[ccID]
l, s, err := plotter.NewLinePoints(xys)
logErrorDebug(err, "botGraphPerf : plotter.NewLinePoints")
if err != nil {
bot.SendChat(m.Chat.ID, fmt.Sprintf("plotter.NewLinePoints : %s", err))
return
}
l.Color = cfg.GetClientColor(ccID)
l.Dashes = plotutil.Dashes(2)
s.Color = cfg.GetClientColor(ccID)
s.Shape = plotutil.Shape(0)
p.Add(l)
p.Add(s)
p.Legend.Add(cc.Username, l, s)
i++
}
err := p.Save(12*vg.Inch, 8*vg.Inch, "/app/data/points.png")
logErrorDebug(err, "botGraphPerf : 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[int]plotter.XYs
planes = make(map[int]plotter.XYs)
airports = make(map[int]plotter.XYs)
for ccID, dStats := range cfg.StatsMonthly {
planes[ccID] = 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[ccID] = append(planes[ccID], pt)
pt = plotter.XY{
X: dateFloat,
Y: float64(stat.Airports),
}
airports[ccID] = append(airports[ccID], pt)
}
sort.Slice(planes[ccID], func(i, j int) bool { return planes[ccID][i].X < planes[ccID][j].X })
sort.Slice(airports[ccID], func(i, j int) bool { return airports[ccID][i].X < airports[ccID][j].X })
}
p := plot.New()
p.Title.Text = "Planes summary"
p.X.Label.Text = "Year"
p.Y.Label.Text = "Planes"
p.Y.Min = 0
i := 0
for ccID, xys := range planes {
cc := cfg.Clients[ccID]
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 = cfg.GetClientColor(ccID)
l.Dashes = plotutil.Dashes(2)
s.Color = cfg.GetClientColor(ccID)
s.Shape = plotutil.Shape(0)
p.Add(l)
p.Add(s)
p.Legend.Add(cc.Username, l, s)
i++
}
err := p.Save(12*vg.Inch, 8*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
}
bot.SendChatImage(m.Chat.ID, "/app/data/points.png")
return
}
func botGraphBusses(m *tb.Message) {
var busses, busStops map[int]plotter.XYs
busses = make(map[int]plotter.XYs)
busStops = make(map[int]plotter.XYs)
for ccID, dStats := range cfg.StatsMonthly {
busses[ccID] = make(plotter.XYs, 0)
for dStr, stat := range dStats {
d, err := time.Parse("20060102", dStr)
logErrorDebug(err, "botGraphBusses : 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.Busses),
}
busses[ccID] = append(busses[ccID], pt)
pt = plotter.XY{
X: dateFloat,
Y: float64(stat.BusStops),
}
busStops[ccID] = append(busStops[ccID], pt)
}
sort.Slice(busses[ccID], func(i, j int) bool { return busses[ccID][i].X < busses[ccID][j].X })
sort.Slice(busStops[ccID], func(i, j int) bool { return busStops[ccID][i].X < busStops[ccID][j].X })
}
p := plot.New()
p.Title.Text = "Busses summary"
p.X.Label.Text = "Year"
p.Y.Label.Text = "Busses"
p.Y.Min = 0
i := 0
for ccID, xys := range busses {
cc := cfg.Clients[ccID]
l, s, err := plotter.NewLinePoints(xys)
logErrorDebug(err, "botGraphBusses : plotter.NewLinePoints")
if err != nil {
bot.SendChat(m.Chat.ID, fmt.Sprintf("plotter.NewLinePoints : %s", err))
return
}
l.Color = cfg.GetClientColor(ccID)
l.Dashes = plotutil.Dashes(2)
s.Color = cfg.GetClientColor(ccID)
s.Shape = plotutil.Shape(0)
p.Add(l)
p.Add(s)
p.Legend.Add(cc.Username, l, s)
i++
}
err := p.Save(12*vg.Inch, 8*vg.Inch, "/app/data/points.png")
logErrorDebug(err, "botGraphBusses : 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 botGraphTrains(m *tb.Message) {
var trains, trainStations map[int]plotter.XYs
trains = make(map[int]plotter.XYs)
trainStations = make(map[int]plotter.XYs)
for ccID, dStats := range cfg.StatsMonthly {
trains[ccID] = make(plotter.XYs, 0)
for dStr, stat := range dStats {
d, err := time.Parse("20060102", dStr)
logErrorDebug(err, "botGraphTrains : 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.Trains),
}
trains[ccID] = append(trains[ccID], pt)
pt = plotter.XY{
X: dateFloat,
Y: float64(stat.TrainStations),
}
trainStations[ccID] = append(trainStations[ccID], pt)
}
sort.Slice(trains[ccID], func(i, j int) bool { return trains[ccID][i].X < trains[ccID][j].X })
sort.Slice(trainStations[ccID], func(i, j int) bool { return trainStations[ccID][i].X < trainStations[ccID][j].X })
}
p := plot.New()
p.Title.Text = "Trains summary"
p.X.Label.Text = "Year"
p.Y.Label.Text = "Trains"
p.Y.Min = 0
i := 0
for ccID, xys := range trains {
cc := cfg.Clients[ccID]
l, s, err := plotter.NewLinePoints(xys)
logErrorDebug(err, "botGraphTrains : plotter.NewLinePoints")
if err != nil {
bot.SendChat(m.Chat.ID, fmt.Sprintf("plotter.NewLinePoints : %s", err))
return
}
l.Color = cfg.GetClientColor(ccID)
l.Dashes = plotutil.Dashes(2)
s.Color = cfg.GetClientColor(ccID)
s.Shape = plotutil.Shape(0)
p.Add(l)
p.Add(s)
p.Legend.Add(cc.Username, l, s)
i++
}
err := p.Save(12*vg.Inch, 8*vg.Inch, "/app/data/points.png")
logErrorDebug(err, "botGraphTrains : 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 botGraphLorries(m *tb.Message) {
var lorries, lorriesStations map[int]plotter.XYs
lorries = make(map[int]plotter.XYs)
lorriesStations = make(map[int]plotter.XYs)
for ccID, dStats := range cfg.StatsMonthly {
lorries[ccID] = make(plotter.XYs, 0)
for dStr, stat := range dStats {
d, err := time.Parse("20060102", dStr)
logErrorDebug(err, "botGraphLorries : 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.Lorries),
}
lorries[ccID] = append(lorries[ccID], pt)
pt = plotter.XY{
X: dateFloat,
Y: float64(stat.LorryStations),
}
lorriesStations[ccID] = append(lorriesStations[ccID], pt)
}
sort.Slice(lorries[ccID], func(i, j int) bool { return lorries[ccID][i].X < lorries[ccID][j].X })
sort.Slice(lorriesStations[ccID], func(i, j int) bool { return lorriesStations[ccID][i].X < lorriesStations[ccID][j].X })
}
p := plot.New()
p.Title.Text = "Lorries summary"
p.X.Label.Text = "Year"
p.Y.Label.Text = "Lorries"
p.Y.Min = 0
i := 0
for ccID, xys := range lorries {
cc := cfg.Clients[ccID]
l, s, err := plotter.NewLinePoints(xys)
logErrorDebug(err, "botGraphLorries : plotter.NewLinePoints")
if err != nil {
bot.SendChat(m.Chat.ID, fmt.Sprintf("plotter.NewLinePoints : %s", err))
return
}
l.Color = cfg.GetClientColor(ccID)
l.Dashes = plotutil.Dashes(2)
s.Color = cfg.GetClientColor(ccID)
s.Shape = plotutil.Shape(0)
p.Add(l)
p.Add(s)
p.Legend.Add(cc.Username, l, s)
i++
}
err := p.Save(12*vg.Inch, 8*vg.Inch, "/app/data/points.png")
logErrorDebug(err, "botGraphLorries : 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 botGraphShips(m *tb.Message) {
var ships, harbours map[int]plotter.XYs
ships = make(map[int]plotter.XYs)
harbours = make(map[int]plotter.XYs)
for ccID, dStats := range cfg.StatsMonthly {
ships[ccID] = make(plotter.XYs, 0)
for dStr, stat := range dStats {
d, err := time.Parse("20060102", dStr)
logErrorDebug(err, "botGraphShips : 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.Ships),
}
ships[ccID] = append(ships[ccID], pt)
pt = plotter.XY{
X: dateFloat,
Y: float64(stat.Harbours),
}
harbours[ccID] = append(harbours[ccID], pt)
}
sort.Slice(ships[ccID], func(i, j int) bool { return ships[ccID][i].X < ships[ccID][j].X })
sort.Slice(harbours[ccID], func(i, j int) bool { return harbours[ccID][i].X < harbours[ccID][j].X })
}
p := plot.New()
p.Title.Text = "Ships summary"
p.X.Label.Text = "Year"
p.Y.Label.Text = "Ships"
p.Y.Min = 0
i := 0
for ccID, xys := range ships {
cc := cfg.Clients[ccID]
l, s, err := plotter.NewLinePoints(xys)
logErrorDebug(err, "botGraphShips : plotter.NewLinePoints")
if err != nil {
bot.SendChat(m.Chat.ID, fmt.Sprintf("plotter.NewLinePoints : %s", err))
return
}
l.Color = cfg.GetClientColor(ccID)
l.Dashes = plotutil.Dashes(2)
s.Color = cfg.GetClientColor(ccID)
s.Shape = plotutil.Shape(0)
p.Add(l)
p.Add(s)
p.Legend.Add(cc.Username, l, s)
i++
}
err := p.Save(12*vg.Inch, 8*vg.Inch, "/app/data/points.png")
logErrorDebug(err, "botGraphShips : 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
}