1
0
mirror of https://github.com/nikolaydubina/calendarheatmap.git synced 2025-02-08 11:47:59 +02:00
calendarheatmap/main.go

111 lines
2.9 KiB
Go
Raw Normal View History

2020-07-03 10:12:28 +08:00
// This is example on how to read data, calculate statistics
// and draw it with this module.
2020-07-02 02:48:34 +08:00
package main
import (
"bufio"
"flag"
"fmt"
2020-07-03 09:44:39 +08:00
"image/color"
2020-07-11 17:29:14 +08:00
"image/gif"
"image/jpeg"
2020-07-02 02:48:34 +08:00
"image/png"
"log"
"os"
"strings"
"time"
2020-07-02 17:58:02 +08:00
"github.com/nikolaydubina/calendarheatmap/charts"
"github.com/nikolaydubina/calendarheatmap/colorscales"
2020-07-02 02:48:34 +08:00
)
2020-07-02 03:00:58 +08:00
// Row represents single row data in input file
2020-07-02 02:48:34 +08:00
type Row struct {
Date time.Time
Count int
}
func loadRows(filename string) ([]Row, error) {
file, err := os.Open(filename)
if err != nil {
return nil, fmt.Errorf("cant not open file: %w", err)
}
defer file.Close()
rows := make([]Row, 0)
scanner := bufio.NewScanner(file)
for scanner.Scan() {
items := strings.Split(scanner.Text(), " ")
if len(items) != 3 {
return nil, fmt.Errorf("number of items in row is not 3")
}
timeString, countString := items[0]+" "+items[1], items[2]
date, err := time.Parse("2006-01-02 15:04", timeString)
if err != nil {
return nil, fmt.Errorf("can not parse time: %w", err)
}
count := strings.Count(countString, "P")
rows = append(rows, Row{Date: date, Count: count})
}
if err := scanner.Err(); err != nil {
return nil, fmt.Errorf("scanner got error: %w", err)
}
return rows, nil
}
func main() {
filenameLogs := flag.String("input", "input.txt", "file should contain lines in format: 2020-05-16 20:43 PPPP")
2020-07-04 12:20:49 +08:00
filenameChart := flag.String("output", "chart.png", "output filename, will export as PNG")
2020-07-02 20:07:08 +08:00
monthSep := flag.Bool("monthsep", true, "render month separator")
2020-07-02 02:48:34 +08:00
colorScale := flag.String("colorscale", "PuBu9", "refer to colorscales for examples")
2020-07-02 20:07:08 +08:00
labels := flag.Bool("labels", true, "labels for weekday and months")
2020-07-11 17:29:14 +08:00
outputFormat := flag.String("output-format", "png", "output format (png, jpeg, gif)")
2020-07-02 02:48:34 +08:00
flag.Parse()
rows, err := loadRows(*filenameLogs)
if err != nil {
log.Fatal(err)
}
year := rows[0].Date.Year()
countByDay := make(map[int]int, 366)
for _, row := range rows {
countByDay[row.Date.YearDay()] += row.Count
}
2020-07-02 20:07:08 +08:00
img := charts.NewHeatmap(charts.HeatmapConfig{
Year: year,
CountByDay: countByDay,
ColorScale: colorscales.LoadColorScale(*colorScale),
DrawMonthSeparator: *monthSep,
DrawLabels: *labels,
2020-07-03 09:44:39 +08:00
Margin: 3,
BoxSize: 15,
TextWidthLeft: 35,
2020-07-11 17:31:58 +08:00
TextHeightTop: 20,
2020-07-03 09:44:39 +08:00
TextColor: color.RGBA{100, 100, 100, 255},
BorderColor: color.RGBA{200, 200, 200, 255},
2020-07-02 20:07:08 +08:00
})
2020-07-02 02:48:34 +08:00
f, err := os.Create(*filenameChart)
if err != nil {
log.Fatal(fmt.Errorf("can not create file: %w", err))
}
defer f.Close()
2020-07-11 17:29:14 +08:00
switch *outputFormat {
case "png":
if err := png.Encode(f, img); err != nil {
log.Fatal(fmt.Errorf("can not encode png: %w", err))
}
case "jpeg":
if err := jpeg.Encode(f, img, nil); err != nil {
log.Fatal(fmt.Errorf("can not encode jpeg: %w", err))
}
case "gif":
if err := gif.Encode(f, img, nil); err != nil {
log.Fatal(fmt.Errorf("can not encode gifg: %w", err))
}
2020-07-02 02:48:34 +08:00
}
}