diff --git a/server/stats.go b/server/stats.go index 5cfb9f4..d55f3af 100644 --- a/server/stats.go +++ b/server/stats.go @@ -8,6 +8,7 @@ import ( "log/slog" "net/http" "strings" + "time" "git.lastassault.de/speatzle/morffix/constants" "github.com/go-echarts/go-echarts/v2/charts" @@ -194,6 +195,66 @@ func generateStats(ctx context.Context) ([]ChartData, error) { } data = append(data, generatePie("Task Status", res)) + type BarTaskRowValue struct { + Date time.Time + Status constants.TaskStatus + Count int + } + + rows, err = db.Query(ctx, + `SELECT date_trunc('day', updated_at) date, status, COUNT(*) AS count + FROM tasks + WHERE status = $1 OR status = $2 + GROUP BY 1,2;`, constants.TASK_STATUS_SUCCESS, constants.TASK_STATUS_FAILED) + if err != nil { + return nil, fmt.Errorf("Query Task Status Day: %w", err) + } + + taskStatusDayCounts, err := pgx.CollectRows(rows, pgx.RowToStructByName[BarTaskRowValue]) + if err != nil { + return nil, fmt.Errorf("Collect Task Status Day Data: %w", err) + } + + days := []string{} + successBarData := []opts.BarData{} + failedBarData := []opts.BarData{} + for _, v := range taskStatusDayCounts { + days = append(days, v.Date.Format(time.DateOnly)) + if v.Status == constants.TASK_STATUS_SUCCESS { + successBarData = append(successBarData, opts.BarData{ + Value: v.Count, + }) + } else if v.Status == constants.TASK_STATUS_FAILED { + failedBarData = append(failedBarData, opts.BarData{ + Value: v.Count, + }) + } + + } + bar := charts.NewBar() + bar.SetGlobalOptions( + charts.WithInitializationOpts(opts.Initialization{ + Theme: "dark", + BackgroundColor: "#111", + }), + charts.WithTitleOpts(opts.Title{ + Title: "Task Success/Failed Per Day", + }), + ) + bar.SetXAxis(days). + AddSeries("Success", successBarData). + AddSeries("Failed", failedBarData). + SetSeriesOptions(charts.WithBarChartOpts(opts.BarChart{ + Stack: "stackA", + })) + + snippet := bar.RenderSnippet() + + data = append(data, ChartData{ + Element: template.HTML(snippet.Element), + Script: template.HTML(snippet.Script), + }) + return data, nil }