internal/httpd/activity.go

v1.9.0
gitbay/internal/httpd/activity.go history · blame · raw

57 lines · 1398 bytes

 1package httpd
 2
 3import "time"
 4
 5// activityDay is one cell of the graph; Level buckets Count into the five
 6// intensity classes the stylesheet colors.
 7type activityDay struct {
 8	Date  string
 9	Count int
10	Level int  // 0..4
11	Pad   bool // before the range start / after today
12}
13
14type activityWeek []activityDay // 7 days, Sunday first
15
16// activityGrid lays a day->count map into 53 week columns ending today,
17// GitHub-style: columns are weeks, rows Sunday..Saturday.
18func activityGrid(counts map[string]int) ([]activityWeek, int) {
19	today := time.Now().UTC()
20	// End the grid on the Saturday of the current week.
21	end := today.AddDate(0, 0, int(time.Saturday-today.Weekday()))
22	start := end.AddDate(0, 0, -53*7+1) // a Sunday, 53 columns back
23
24	total := 0
25	var weeks []activityWeek
26	for d := start; !d.After(end); d = d.AddDate(0, 0, 7) {
27		var week activityWeek
28		for i := 0; i < 7; i++ {
29			day := d.AddDate(0, 0, i)
30			key := day.Format("2006-01-02")
31			if day.After(today) {
32				week = append(week, activityDay{Date: key, Pad: true})
33				continue
34			}
35			n := counts[key]
36			total += n
37			week = append(week, activityDay{Date: key, Count: n, Level: activityLevel(n)})
38		}
39		weeks = append(weeks, week)
40	}
41	return weeks, total
42}
43
44func activityLevel(n int) int {
45	switch {
46	case n == 0:
47		return 0
48	case n <= 2:
49		return 1
50	case n <= 5:
51		return 2
52	case n <= 9:
53		return 3
54	default:
55		return 4
56	}
57}