set colors
This commit is contained in:
parent
bd6a5422cb
commit
f21a8e5736
922
bot.go
922
bot.go
@ -5,16 +5,10 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"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"
|
tb "gopkg.in/tucnak/telebot.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -938,922 +932,6 @@ func botRegister(m *tb.Message) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = 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(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 = 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(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 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 = 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(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 = 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(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 = 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(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 = 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(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 = 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(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 = 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(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 = 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(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 = 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(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 = 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(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
|
|
||||||
}
|
|
||||||
|
|
||||||
func PrintText(m *tb.Message) {
|
func PrintText(m *tb.Message) {
|
||||||
logInfoDebug("[%d] %s(%d) | %s(%d) : %s\n", m.ID, m.Chat.Title, m.Chat.ID, m.Sender.Username, m.Sender.ID, m.Text)
|
logInfoDebug("[%d] %s(%d) | %s(%d) : %s\n", m.ID, m.Chat.Title, m.Chat.ID, m.Sender.Username, m.Sender.ID, m.Text)
|
||||||
return
|
return
|
||||||
|
930
bot_graph.go
Normal file
930
bot_graph.go
Normal file
@ -0,0 +1,930 @@
|
|||||||
|
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 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
|
||||||
|
}
|
44
config.go
44
config.go
@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"image/color"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -128,3 +129,46 @@ func (c *Config) GetCompanyClient(id uint8) *ClientConfig {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Config) GetClientColor(id int) color.Color {
|
||||||
|
cc, ok := c.Clients[id]
|
||||||
|
if !ok {
|
||||||
|
return color.RGBA{0, 0, 0, 255} // Black
|
||||||
|
}
|
||||||
|
switch cc.Color {
|
||||||
|
case "Dark Blue":
|
||||||
|
return color.RGBA{28, 68, 140, 255}
|
||||||
|
case "Pale Green":
|
||||||
|
return color.RGBA{76, 116, 88, 255}
|
||||||
|
case "Pink":
|
||||||
|
return color.RGBA{188, 84, 108, 255}
|
||||||
|
case "Yellow":
|
||||||
|
return color.RGBA{212, 156, 32, 255}
|
||||||
|
case "Red":
|
||||||
|
return color.RGBA{196, 0, 0, 255}
|
||||||
|
case "Light Blue":
|
||||||
|
return color.RGBA{52, 112, 132, 255}
|
||||||
|
case "Green":
|
||||||
|
return color.RGBA{84, 132, 20, 255}
|
||||||
|
case "Dark Green":
|
||||||
|
return color.RGBA{80, 104, 60, 255}
|
||||||
|
case "Blue":
|
||||||
|
return color.RGBA{24, 120, 220, 255}
|
||||||
|
case "Cream":
|
||||||
|
return color.RGBA{184, 112, 80, 255}
|
||||||
|
case "Mauve":
|
||||||
|
return color.RGBA{80, 80, 116, 255}
|
||||||
|
case "Purple":
|
||||||
|
return color.RGBA{104, 76, 196, 255}
|
||||||
|
case "Orange":
|
||||||
|
return color.RGBA{252, 156, 0, 255}
|
||||||
|
case "Brown":
|
||||||
|
return color.RGBA{124, 104, 72, 255}
|
||||||
|
case "Gray":
|
||||||
|
return color.RGBA{116, 116, 116, 255}
|
||||||
|
case "White":
|
||||||
|
return color.RGBA{184, 184, 184, 255}
|
||||||
|
default:
|
||||||
|
return color.RGBA{0, 0, 0, 255} // Black
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -15,5 +15,6 @@
|
|||||||
"threshold":600000000000,
|
"threshold":600000000000,
|
||||||
"start_date":"2021-11-01T17:22:28+02:00"
|
"start_date":"2021-11-01T17:22:28+02:00"
|
||||||
},
|
},
|
||||||
"stats":null
|
"stats_monthly":null,
|
||||||
|
"stats_daily":null
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
// Code generated by version.sh (@generated) DO NOT EDIT.
|
// Code generated by version.sh (@generated) DO NOT EDIT.
|
||||||
package main
|
package main
|
||||||
var githash = "eec4d75"
|
var githash = "bd6a542"
|
||||||
var buildstamp = "2021-12-11_02:53:36"
|
var buildstamp = "2021-12-11_03:50:14"
|
||||||
var commits = "255"
|
var commits = "256"
|
||||||
var version = "eec4d75-b255 - 2021-12-11_02:53:36"
|
var version = "bd6a542-b256 - 2021-12-11_03:50:14"
|
||||||
|
Loading…
Reference in New Issue
Block a user