1
0
mirror of https://github.com/nikolaydubina/calendarheatmap.git synced 2024-12-04 03:39:18 +02:00

cleanup assets

This commit is contained in:
Nikolay 2021-02-27 15:38:13 +00:00 committed by GitHub
parent 48908052dc
commit 513db54b64
27 changed files with 802 additions and 196 deletions

18
Makefile Normal file
View File

@ -0,0 +1,18 @@
build:
go build
test:
go test ./...
docs: build
cat charts/testdata/basic.json | ./calendarheatmap > docs/basic.png
cat charts/testdata/basic.json | ./calendarheatmap -colorscale=purple-blue-9.csv > docs/colorscale-1.png
cat charts/testdata/basic.json | ./calendarheatmap -colorscale=green-blue-9.csv > docs/colorscale-2.png
cat charts/testdata/basic.json | ./calendarheatmap -colorscale=yellow-green-9.csv > docs/colorscale-3.png
cat charts/testdata/basic.json | ./calendarheatmap -locale=ko_KR > docs/korean.png
cat charts/testdata/basic.json | ./calendarheatmap -locale=ko_KR -output=svg > docs/korean.svg
cat charts/testdata/basic.json | ./calendarheatmap -labels=false > docs/nolabels.png
cat charts/testdata/basic.json | ./calendarheatmap -monthsep=false > docs/noseparator.png
cat charts/testdata/basic.json | ./calendarheatmap -labels=false -monthsep=false > docs/noseparator_nolabels.png
.PHONY: build test docs

View File

@ -18,27 +18,27 @@ $ echo '{
Basic
![basic](charts/testdata/basic.png)
![basic](docs/basic.png)
Colorscales
![col1](charts/testdata/colorscale_1.png)
![col2](charts/testdata/colorscale_2.png)
![col1](docs/colorscale-1.png)
![col2](docs/colorscale-2.png)
![col2](docs/colorscale-3.png)
UTF-8
![col1](charts/testdata/korean.png)
![col1](docs/korean.png)
SVG
![svg](charts/testdata/korean.svg)
![svg](docs/korean.svg)
Without month separator
![nosep](charts/testdata/noseparator.png)
![nosep](docs/noseparator.png)
Without labels
![nolab](charts/testdata/nolabels.png)
![nolab](docs/nolabels.png)
Without labels, without separator
![nosep_nolab](charts/testdata/noseparator_nolabels.png)
![nosep_nolab](docs/noseparator_nolabels.png)
## GitHub stars over time

View File

@ -0,0 +1,10 @@
R,G,B
247,252,240
224,243,219
204,235,197
168,221,181
123,204,196
78,179,211
43,140,190
8,104,172
8,64,129
1 R G B
2 247 252 240
3 224 243 219
4 204 235 197
5 168 221 181
6 123 204 196
7 78 179 211
8 43 140 190
9 8 104 172
10 8 64 129

View File

@ -0,0 +1,10 @@
R,G,B
255,247,251
236,231,242
208,209,230
166,189,219
116,169,207
54,144,192
5,112,176
4,90,141
2,56,88
1 R G B
2 255 247 251
3 236 231 242
4 208 209 230
5 166 189 219
6 116 169 207
7 54 144 192
8 5 112 176
9 4 90 141
10 2 56 88

View File

@ -0,0 +1,10 @@
R,G,B
255,255,229
247,252,185
217,240,163
173,221,142
120,198,121
65,171,93
35,132,67
0,104,55
0,69,41
1 R G B
2 255 255 229
3 247 252 185
4 217 240 163
5 173 221 142
6 120 198 121
7 65 171 93
8 35 132 67
9 0 104 55
10 0 69 41

BIN
calendarheatmap Executable file

Binary file not shown.

View File

@ -11,9 +11,14 @@ import (
"io"
"time"
"github.com/nikolaydubina/calendarheatmap/colorscales"
"golang.org/x/image/font"
)
// ColorScale is interface for extracting color based on value from 0 to 1
type ColorScale interface {
GetColor(val float64) color.RGBA
}
var weekdayOrder = [7]time.Weekday{
time.Monday,
time.Tuesday,
@ -32,7 +37,7 @@ const (
// HeatmapConfig contains config of calendar heatmap image
type HeatmapConfig struct {
Counts map[string]int
ColorScale colorscales.ColorScale
ColorScale ColorScale
DrawMonthSeparator bool
DrawLabels bool
BoxSize int
@ -43,6 +48,7 @@ type HeatmapConfig struct {
BorderColor color.RGBA
Locale string
Format string
FontFace font.Face
}
// WriteHeatmap writes image with heatmap and additional elements
@ -84,7 +90,7 @@ func WriteHeatmap(conf HeatmapConfig, w io.Writer) error {
labelsProvider := NewLabelsProvider(locale)
if conf.DrawLabels {
visitors = append(visitors, &MonthLabelsVisitor{Img: img, YOffset: 50, Color: conf.TextColor, LabelsProvider: labelsProvider})
visitors = append(visitors, &MonthLabelsVisitor{FontFace: conf.FontFace, Img: img, YOffset: 50, Color: conf.TextColor, LabelsProvider: labelsProvider})
}
for iter := NewDayIterator(conf.Counts, offset, conf.BoxSize, conf.Margin); !iter.Done(); iter.Next() {
@ -95,6 +101,7 @@ func WriteHeatmap(conf HeatmapConfig, w io.Writer) error {
if conf.DrawLabels {
drawWeekdayLabels(
conf.FontFace,
img,
offset,
map[time.Weekday]bool{
@ -137,7 +144,7 @@ type DayVisitor interface {
// DayBoxVisitor draws signle heatbox
type DayBoxVisitor struct {
Img *image.RGBA
ColorScale colorscales.ColorScale
ColorScale ColorScale
BoxSize int
}
@ -214,6 +221,7 @@ type MonthLabelsVisitor struct {
YOffset int
Color color.RGBA
LabelsProvider LabelsProvider
FontFace font.Face
}
// Visit on every iteration
@ -223,6 +231,7 @@ func (d *MonthLabelsVisitor) Visit(iter *DayIterator) {
if iter.Row == 0 && day.Day() <= 7 {
p := iter.Point()
drawText(
d.FontFace,
d.Img,
image.Point{X: p.X, Y: p.Y - d.YOffset},
d.LabelsProvider.GetMonth(day.Month()),
@ -234,13 +243,13 @@ func (d *MonthLabelsVisitor) Visit(iter *DayIterator) {
// drawWeekdayLabel draws column of same width labels for weekdays
// All weekday labels assumed to have same width, which really depends on font.
// offset argument is top right corner of where to insert column of weekday labels.
func drawWeekdayLabels(img *image.RGBA, offset image.Point, weekdays map[time.Weekday]bool, boxSize int, margin int, color color.RGBA, lp LabelsProvider) {
func drawWeekdayLabels(fontFace font.Face, img *image.RGBA, offset image.Point, weekdays map[time.Weekday]bool, boxSize int, margin int, color color.RGBA, lp LabelsProvider) {
width := 250
height := 100
y := offset.Y + height
for _, w := range weekdayOrder {
if weekdays[w] {
drawText(img, image.Point{X: offset.X - width, Y: y}, lp.GetWeekday(w), color)
drawText(fontFace, img, image.Point{X: offset.X - width, Y: y}, lp.GetWeekday(w), color)
}
y += boxSize + margin
}

View File

@ -6,7 +6,6 @@ import (
"testing"
"github.com/nikolaydubina/calendarheatmap/charts"
"github.com/nikolaydubina/calendarheatmap/colorscales"
)
var counts map[string]int = map[string]int{
@ -67,10 +66,22 @@ func save(t *testing.T, conf charts.HeatmapConfig, filename string) {
func TestBasicData(t *testing.T) {
os.Setenv("CALENDAR_HEATMAP_ASSETS_PATH", "assets")
var colorscale = charts.BasicColorScale{
color.RGBA{247, 252, 240, 255},
color.RGBA{224, 243, 219, 255},
color.RGBA{204, 235, 197, 255},
color.RGBA{168, 221, 181, 255},
color.RGBA{123, 204, 196, 255},
color.RGBA{78, 179, 211, 255},
color.RGBA{43, 140, 190, 255},
color.RGBA{8, 104, 172, 255},
color.RGBA{8, 64, 129, 255},
}
t.Run("basic", func(t *testing.T) {
conf := charts.HeatmapConfig{
Counts: counts,
ColorScale: colorscales.PuBu9,
ColorScale: colorscale,
DrawMonthSeparator: true,
DrawLabels: true,
Margin: 30,
@ -84,44 +95,10 @@ func TestBasicData(t *testing.T) {
save(t, conf, "testdata/basic.png")
})
t.Run("colorscale_1", func(t *testing.T) {
conf := charts.HeatmapConfig{
Counts: counts,
ColorScale: colorscales.GnBu9,
DrawMonthSeparator: true,
DrawLabels: true,
Margin: 30,
BoxSize: 150,
TextWidthLeft: 350,
TextHeightTop: 200,
TextColor: color.RGBA{100, 100, 100, 255},
BorderColor: color.RGBA{200, 200, 200, 255},
Format: "png",
}
save(t, conf, "testdata/colorscale_1.png")
})
t.Run("colorscale_2", func(t *testing.T) {
conf := charts.HeatmapConfig{
Counts: counts,
ColorScale: colorscales.YlGn9,
DrawMonthSeparator: true,
DrawLabels: true,
Margin: 30,
BoxSize: 150,
TextWidthLeft: 350,
TextHeightTop: 200,
TextColor: color.RGBA{100, 100, 100, 255},
BorderColor: color.RGBA{200, 200, 200, 255},
Format: "png",
}
save(t, conf, "testdata/colorscale_2.png")
})
t.Run("korean", func(t *testing.T) {
conf := charts.HeatmapConfig{
Counts: counts,
ColorScale: colorscales.PuBu9,
ColorScale: colorscale,
DrawMonthSeparator: true,
DrawLabels: true,
Margin: 30,
@ -139,7 +116,7 @@ func TestBasicData(t *testing.T) {
t.Run("no separator", func(t *testing.T) {
conf := charts.HeatmapConfig{
Counts: counts,
ColorScale: colorscales.PuBu9,
ColorScale: colorscale,
DrawMonthSeparator: false,
DrawLabels: true,
Margin: 30,
@ -156,7 +133,7 @@ func TestBasicData(t *testing.T) {
t.Run("no labels", func(t *testing.T) {
conf := charts.HeatmapConfig{
Counts: counts,
ColorScale: colorscales.PuBu9,
ColorScale: colorscale,
DrawMonthSeparator: true,
DrawLabels: false,
Margin: 30,
@ -173,7 +150,7 @@ func TestBasicData(t *testing.T) {
t.Run("no separator, no labels", func(t *testing.T) {
conf := charts.HeatmapConfig{
Counts: counts,
ColorScale: colorscales.PuBu9,
ColorScale: colorscale,
DrawMonthSeparator: false,
DrawLabels: false,
Margin: 30,
@ -190,7 +167,7 @@ func TestBasicData(t *testing.T) {
t.Run("empty data", func(t *testing.T) {
conf := charts.HeatmapConfig{
Counts: counts,
ColorScale: colorscales.PuBu9,
ColorScale: colorscale,
DrawMonthSeparator: true,
DrawLabels: false,
Margin: 30,
@ -207,7 +184,7 @@ func TestBasicData(t *testing.T) {
t.Run("nil data", func(t *testing.T) {
conf := charts.HeatmapConfig{
Counts: counts,
ColorScale: colorscales.PuBu9,
ColorScale: colorscale,
DrawMonthSeparator: true,
DrawLabels: false,
Margin: 30,

68
charts/colorscale.go Normal file
View File

@ -0,0 +1,68 @@
package charts
import (
"encoding/csv"
"errors"
"fmt"
"image/color"
"math"
"os"
"strconv"
)
// BasicColorScale is color scale with variable number of colors
type BasicColorScale []color.RGBA
// GetColor returns color based on float value from 0 to 1
func (c BasicColorScale) GetColor(val float64) color.RGBA {
maxIdx := len(c) - 1
idx := int(math.Round(float64(maxIdx) * val))
return c[idx]
}
// NewBasicColorscaleFromCSVFile loads basic colorscale from CSV file
func NewBasicColorscaleFromCSVFile(path string) (BasicColorScale, error) {
colorscaleReader, err := os.Open(path)
if err != nil {
return nil, fmt.Errorf("can not open file: %w", err)
}
rows, err := csv.NewReader(colorscaleReader).ReadAll()
if err != nil {
return nil, fmt.Errorf("can not read CSV: %w", err)
}
if len(rows) == 0 {
return nil, errors.New("empty colorscales file")
}
colmap := make(map[string]int, 3)
for i, name := range rows[0] {
colmap[name] = i
}
if _, ok := colmap["R"]; !ok {
return nil, errors.New("missing R column")
}
if _, ok := colmap["G"]; !ok {
return nil, errors.New("missing G column")
}
if _, ok := colmap["B"]; !ok {
return nil, errors.New("missing B column")
}
colorscale := make(BasicColorScale, 0)
for _, vals := range rows[1:] {
r, err := strconv.Atoi(vals[colmap["R"]])
if err != nil {
return nil, errors.New("bad value for color")
}
g, err := strconv.Atoi(vals[colmap["G"]])
if err != nil {
return nil, errors.New("bad value for color")
}
b, err := strconv.Atoi(vals[colmap["B"]])
if err != nil {
return nil, errors.New("bad value for color")
}
colorscale = append(colorscale, color.RGBA{R: uint8(r), G: uint8(g), B: uint8(b), A: 255})
}
return colorscale, nil
}

View File

@ -5,14 +5,25 @@ import (
"testing"
"github.com/nikolaydubina/calendarheatmap/charts"
"github.com/nikolaydubina/calendarheatmap/colorscales"
)
func TestBasicDataSVG(t *testing.T) {
var colorscale = charts.BasicColorScale{
color.RGBA{247, 252, 240, 255},
color.RGBA{224, 243, 219, 255},
color.RGBA{204, 235, 197, 255},
color.RGBA{168, 221, 181, 255},
color.RGBA{123, 204, 196, 255},
color.RGBA{78, 179, 211, 255},
color.RGBA{43, 140, 190, 255},
color.RGBA{8, 104, 172, 255},
color.RGBA{8, 64, 129, 255},
}
t.Run("basic", func(t *testing.T) {
conf := charts.HeatmapConfig{
Counts: counts,
ColorScale: colorscales.PuBu9,
ColorScale: colorscale,
DrawMonthSeparator: true,
DrawLabels: true,
TextColor: color.RGBA{100, 100, 100, 255},
@ -25,7 +36,7 @@ func TestBasicDataSVG(t *testing.T) {
t.Run("korean", func(t *testing.T) {
conf := charts.HeatmapConfig{
Counts: counts,
ColorScale: colorscales.PuBu9,
ColorScale: colorscale,
DrawMonthSeparator: true,
DrawLabels: true,
TextColor: color.RGBA{100, 100, 100, 255},
@ -39,7 +50,7 @@ func TestBasicDataSVG(t *testing.T) {
t.Run("empty data", func(t *testing.T) {
conf := charts.HeatmapConfig{
Counts: map[string]int{},
ColorScale: colorscales.PuBu9,
ColorScale: colorscale,
DrawMonthSeparator: true,
DrawLabels: false,
TextColor: color.RGBA{100, 100, 100, 255},
@ -52,7 +63,7 @@ func TestBasicDataSVG(t *testing.T) {
t.Run("nil data", func(t *testing.T) {
conf := charts.HeatmapConfig{
Counts: nil,
ColorScale: colorscales.PuBu9,
ColorScale: colorscale,
DrawMonthSeparator: true,
DrawLabels: false,
TextColor: color.RGBA{100, 100, 100, 255},

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 0 B

47
charts/text.go Normal file
View File

@ -0,0 +1,47 @@
package charts
import (
"fmt"
"image"
"image/color"
"io/ioutil"
"golang.org/x/image/font"
"golang.org/x/image/font/opentype"
"golang.org/x/image/math/fixed"
)
// LoadFontFaceFromFile loads font face from file
func LoadFontFaceFromFile(fontPath string) (font.Face, error) {
fontBytes, err := ioutil.ReadFile(fontPath)
if err != nil {
return nil, fmt.Errorf("can not open font file with error: %w", err)
}
f, err := opentype.Parse(fontBytes)
if err != nil {
return nil, fmt.Errorf("can not parse font file: %w", err)
}
face, err := opentype.NewFace(f, &opentype.FaceOptions{
Size: 26,
DPI: 280,
Hinting: font.HintingNone,
})
if err != nil {
return nil, fmt.Errorf("can not create font face: %w", err)
}
return face, nil
}
// drawText inserts text into provided image at bottom left coordinate
func drawText(fontFace font.Face, img *image.RGBA, offset image.Point, text string, color color.RGBA) {
d := &font.Drawer{
Dst: img,
Src: image.NewUniform(color),
Face: fontFace,
Dot: fixed.Point26_6{
X: fixed.Int26_6(offset.X * 64),
Y: fixed.Int26_6(offset.Y * 64),
},
}
d.DrawString(text)
}

View File

@ -1,50 +0,0 @@
package charts
import (
"fmt"
"image"
"image/color"
"io/ioutil"
"log"
"os"
"golang.org/x/image/font"
"golang.org/x/image/font/opentype"
"golang.org/x/image/math/fixed"
)
// drawText inserts text into provided image at bottom left coordinate
func drawText(img *image.RGBA, offset image.Point, text string, color color.RGBA) {
assetsPath := os.Getenv("CALENDAR_HEATMAP_ASSETS_PATH")
if assetsPath == "" {
log.Fatalf("assets path is not set")
}
fontBytes, err := ioutil.ReadFile(fmt.Sprintf("%s/fonts/Sunflower-Medium.ttf", assetsPath))
if err != nil {
log.Fatalf("can not open font file with error: %#v", err)
}
f, err := opentype.Parse(fontBytes)
if err != nil {
log.Fatalf("can not parse font file: %v", err)
}
face, err := opentype.NewFace(f, &opentype.FaceOptions{
Size: 26,
DPI: 280,
Hinting: font.HintingNone,
})
if err != nil {
log.Fatalf("can not create font face: %v", err)
}
point := fixed.Point26_6{
X: fixed.Int26_6(offset.X * 64),
Y: fixed.Int26_6(offset.Y * 64),
}
d := &font.Drawer{
Dst: img,
Src: image.NewUniform(color),
Face: face,
Dot: point,
}
d.DrawString(text)
}

View File

@ -1,24 +0,0 @@
package colorscales
import (
"image/color"
)
// ColorScale is interface for extracting color from float
type ColorScale interface {
GetColor(val float64) color.RGBA
}
// LoadColorScale loads colorscale struct based on associated string name
func LoadColorScale(name string) ColorScale {
switch name {
case "PuBu9":
return PuBu9
case "GnBu9":
return GnBu9
case "YlGn9":
return YlGn9
default:
panic("unknown colorscale " + name)
}
}

View File

@ -1,55 +0,0 @@
package colorscales
import (
"image/color"
"math"
)
// ColorScale9 is color scale with 9 colors
type ColorScale9 [9]color.RGBA
// GetColor returns color based on float value from 0 to 1
func (c ColorScale9) GetColor(val float64) color.RGBA {
maxIdx := 8
idx := int(math.Round(float64(maxIdx) * val))
return c[idx]
}
// PuBu9 is Purple-Blue colorscale 9 colors
var PuBu9 = ColorScale9{
color.RGBA{255, 247, 251, 255},
color.RGBA{236, 231, 242, 255},
color.RGBA{208, 209, 230, 255},
color.RGBA{166, 189, 219, 255},
color.RGBA{116, 169, 207, 255},
color.RGBA{54, 144, 192, 255},
color.RGBA{5, 112, 176, 255},
color.RGBA{4, 90, 141, 255},
color.RGBA{2, 56, 88, 255},
}
// GnBu9 is Green-Blue colorscale 9 colors
var GnBu9 = ColorScale9{
color.RGBA{247, 252, 240, 255},
color.RGBA{224, 243, 219, 255},
color.RGBA{204, 235, 197, 255},
color.RGBA{168, 221, 181, 255},
color.RGBA{123, 204, 196, 255},
color.RGBA{78, 179, 211, 255},
color.RGBA{43, 140, 190, 255},
color.RGBA{8, 104, 172, 255},
color.RGBA{8, 64, 129, 255},
}
// YlGn9 is Yellow-Green colorscale 9 colors
var YlGn9 = ColorScale9{
color.RGBA{255, 255, 229, 255},
color.RGBA{247, 252, 185, 255},
color.RGBA{217, 240, 163, 255},
color.RGBA{173, 221, 142, 255},
color.RGBA{120, 198, 121, 255},
color.RGBA{65, 171, 93, 255},
color.RGBA{35, 132, 67, 255},
color.RGBA{0, 104, 55, 255},
color.RGBA{0, 69, 41, 255},
}

BIN
docs/basic.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
docs/colorscale-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
docs/colorscale-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
docs/colorscale-3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
docs/korean.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

557
docs/korean.svg Normal file
View File

@ -0,0 +1,557 @@
<svg width="722" height="112" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink">
<g transform="translate(10, 20)">
<g transform="translate(0, 0)">
<rect class="day" width="10" height="10" x="14" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-01"></rect>
<rect class="day" width="10" height="10" x="14" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-02"></rect>
<rect class="day" width="10" height="10" x="14" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-03"></rect>
<rect class="day" width="10" height="10" x="14" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-04"></rect>
<rect class="day" width="10" height="10" x="14" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-05"></rect>
</g>
<g transform="translate(14, 0)">
<rect class="day" width="10" height="10" x="13" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-06"></rect>
<rect class="day" width="10" height="10" x="13" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-07"></rect>
<rect class="day" width="10" height="10" x="13" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-08"></rect>
<rect class="day" width="10" height="10" x="13" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-09"></rect>
<rect class="day" width="10" height="10" x="13" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-10"></rect>
<rect class="day" width="10" height="10" x="13" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-11"></rect>
<rect class="day" width="10" height="10" x="13" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-12"></rect>
</g>
<g transform="translate(28, 0)">
<rect class="day" width="10" height="10" x="12" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-13"></rect>
<rect class="day" width="10" height="10" x="12" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-14"></rect>
<rect class="day" width="10" height="10" x="12" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-15"></rect>
<rect class="day" width="10" height="10" x="12" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-16"></rect>
<rect class="day" width="10" height="10" x="12" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-17"></rect>
<rect class="day" width="10" height="10" x="12" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-18"></rect>
<rect class="day" width="10" height="10" x="12" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-19"></rect>
</g>
<g transform="translate(42, 0)">
<rect class="day" width="10" height="10" x="11" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-20"></rect>
<rect class="day" width="10" height="10" x="11" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-21"></rect>
<rect class="day" width="10" height="10" x="11" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-22"></rect>
<rect class="day" width="10" height="10" x="11" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-23"></rect>
<rect class="day" width="10" height="10" x="11" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-24"></rect>
<rect class="day" width="10" height="10" x="11" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-25"></rect>
<rect class="day" width="10" height="10" x="11" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-26"></rect>
</g>
<g transform="translate(56, 0)">
<rect class="day" width="10" height="10" x="10" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-27"></rect>
<rect class="day" width="10" height="10" x="10" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-28"></rect>
<rect class="day" width="10" height="10" x="10" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-29"></rect>
<rect class="day" width="10" height="10" x="10" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-30"></rect>
<rect class="day" width="10" height="10" x="10" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-01-31"></rect>
<rect class="day" width="10" height="10" x="10" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-01"></rect>
<rect class="day" width="10" height="10" x="10" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-02"></rect>
</g>
<g transform="translate(70, 0)">
<rect class="day" width="10" height="10" x="9" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-03"></rect>
<rect class="day" width="10" height="10" x="9" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-04"></rect>
<rect class="day" width="10" height="10" x="9" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-05"></rect>
<rect class="day" width="10" height="10" x="9" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-06"></rect>
<rect class="day" width="10" height="10" x="9" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-07"></rect>
<rect class="day" width="10" height="10" x="9" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-08"></rect>
<rect class="day" width="10" height="10" x="9" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-09"></rect>
</g>
<g transform="translate(84, 0)">
<rect class="day" width="10" height="10" x="8" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-10"></rect>
<rect class="day" width="10" height="10" x="8" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-11"></rect>
<rect class="day" width="10" height="10" x="8" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-12"></rect>
<rect class="day" width="10" height="10" x="8" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-13"></rect>
<rect class="day" width="10" height="10" x="8" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-14"></rect>
<rect class="day" width="10" height="10" x="8" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-15"></rect>
<rect class="day" width="10" height="10" x="8" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-16"></rect>
</g>
<g transform="translate(98, 0)">
<rect class="day" width="10" height="10" x="7" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-17"></rect>
<rect class="day" width="10" height="10" x="7" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-18"></rect>
<rect class="day" width="10" height="10" x="7" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-19"></rect>
<rect class="day" width="10" height="10" x="7" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-20"></rect>
<rect class="day" width="10" height="10" x="7" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-21"></rect>
<rect class="day" width="10" height="10" x="7" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-22"></rect>
<rect class="day" width="10" height="10" x="7" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-23"></rect>
</g>
<g transform="translate(112, 0)">
<rect class="day" width="10" height="10" x="6" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-24"></rect>
<rect class="day" width="10" height="10" x="6" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-25"></rect>
<rect class="day" width="10" height="10" x="6" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-26"></rect>
<rect class="day" width="10" height="10" x="6" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-27"></rect>
<rect class="day" width="10" height="10" x="6" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-28"></rect>
<rect class="day" width="10" height="10" x="6" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-02-29"></rect>
<rect class="day" width="10" height="10" x="6" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-01"></rect>
</g>
<g transform="translate(126, 0)">
<rect class="day" width="10" height="10" x="5" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-02"></rect>
<rect class="day" width="10" height="10" x="5" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-03"></rect>
<rect class="day" width="10" height="10" x="5" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-04"></rect>
<rect class="day" width="10" height="10" x="5" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-05"></rect>
<rect class="day" width="10" height="10" x="5" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-06"></rect>
<rect class="day" width="10" height="10" x="5" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-07"></rect>
<rect class="day" width="10" height="10" x="5" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-08"></rect>
</g>
<g transform="translate(140, 0)">
<rect class="day" width="10" height="10" x="4" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-09"></rect>
<rect class="day" width="10" height="10" x="4" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-10"></rect>
<rect class="day" width="10" height="10" x="4" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-11"></rect>
<rect class="day" width="10" height="10" x="4" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-12"></rect>
<rect class="day" width="10" height="10" x="4" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-13"></rect>
<rect class="day" width="10" height="10" x="4" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-14"></rect>
<rect class="day" width="10" height="10" x="4" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-15"></rect>
</g>
<g transform="translate(154, 0)">
<rect class="day" width="10" height="10" x="3" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-16"></rect>
<rect class="day" width="10" height="10" x="3" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-17"></rect>
<rect class="day" width="10" height="10" x="3" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-18"></rect>
<rect class="day" width="10" height="10" x="3" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-19"></rect>
<rect class="day" width="10" height="10" x="3" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-20"></rect>
<rect class="day" width="10" height="10" x="3" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-21"></rect>
<rect class="day" width="10" height="10" x="3" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-22"></rect>
</g>
<g transform="translate(168, 0)">
<rect class="day" width="10" height="10" x="2" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-23"></rect>
<rect class="day" width="10" height="10" x="2" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-24"></rect>
<rect class="day" width="10" height="10" x="2" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-25"></rect>
<rect class="day" width="10" height="10" x="2" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-26"></rect>
<rect class="day" width="10" height="10" x="2" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-27"></rect>
<rect class="day" width="10" height="10" x="2" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-28"></rect>
<rect class="day" width="10" height="10" x="2" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-29"></rect>
</g>
<g transform="translate(182, 0)">
<rect class="day" width="10" height="10" x="1" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-30"></rect>
<rect class="day" width="10" height="10" x="1" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-03-31"></rect>
<rect class="day" width="10" height="10" x="1" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-01"></rect>
<rect class="day" width="10" height="10" x="1" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-02"></rect>
<rect class="day" width="10" height="10" x="1" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-03"></rect>
<rect class="day" width="10" height="10" x="1" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-04"></rect>
<rect class="day" width="10" height="10" x="1" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-05"></rect>
</g>
<g transform="translate(196, 0)">
<rect class="day" width="10" height="10" x="0" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-06"></rect>
<rect class="day" width="10" height="10" x="0" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-07"></rect>
<rect class="day" width="10" height="10" x="0" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-08"></rect>
<rect class="day" width="10" height="10" x="0" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-09"></rect>
<rect class="day" width="10" height="10" x="0" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-10"></rect>
<rect class="day" width="10" height="10" x="0" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-11"></rect>
<rect class="day" width="10" height="10" x="0" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-12"></rect>
</g>
<g transform="translate(210, 0)">
<rect class="day" width="10" height="10" x="-1" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-13"></rect>
<rect class="day" width="10" height="10" x="-1" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-14"></rect>
<rect class="day" width="10" height="10" x="-1" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-15"></rect>
<rect class="day" width="10" height="10" x="-1" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-16"></rect>
<rect class="day" width="10" height="10" x="-1" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-17"></rect>
<rect class="day" width="10" height="10" x="-1" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-18"></rect>
<rect class="day" width="10" height="10" x="-1" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-19"></rect>
</g>
<g transform="translate(224, 0)">
<rect class="day" width="10" height="10" x="-2" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-20"></rect>
<rect class="day" width="10" height="10" x="-2" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-21"></rect>
<rect class="day" width="10" height="10" x="-2" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-22"></rect>
<rect class="day" width="10" height="10" x="-2" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-23"></rect>
<rect class="day" width="10" height="10" x="-2" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-24"></rect>
<rect class="day" width="10" height="10" x="-2" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-25"></rect>
<rect class="day" width="10" height="10" x="-2" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-26"></rect>
</g>
<g transform="translate(238, 0)">
<rect class="day" width="10" height="10" x="-3" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-27"></rect>
<rect class="day" width="10" height="10" x="-3" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-28"></rect>
<rect class="day" width="10" height="10" x="-3" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-29"></rect>
<rect class="day" width="10" height="10" x="-3" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-04-30"></rect>
<rect class="day" width="10" height="10" x="-3" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-05-01"></rect>
<rect class="day" width="10" height="10" x="-3" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-05-02"></rect>
<rect class="day" width="10" height="10" x="-3" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-05-03"></rect>
</g>
<g transform="translate(252, 0)">
<rect class="day" width="10" height="10" x="-4" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-05-04"></rect>
<rect class="day" width="10" height="10" x="-4" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-05-05"></rect>
<rect class="day" width="10" height="10" x="-4" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-05-06"></rect>
<rect class="day" width="10" height="10" x="-4" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-05-07"></rect>
<rect class="day" width="10" height="10" x="-4" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-05-08"></rect>
<rect class="day" width="10" height="10" x="-4" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-05-09"></rect>
<rect class="day" width="10" height="10" x="-4" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-05-10"></rect>
</g>
<g transform="translate(266, 0)">
<rect class="day" width="10" height="10" x="-5" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-05-11"></rect>
<rect class="day" width="10" height="10" x="-5" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-05-12"></rect>
<rect class="day" width="10" height="10" x="-5" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-05-13"></rect>
<rect class="day" width="10" height="10" x="-5" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-05-14"></rect>
<rect class="day" width="10" height="10" x="-5" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-05-15"></rect>
<rect class="day" width="10" height="10" x="-5" y="65" fill="rgb(78,179,211)" data-count="8" data-date="2020-05-16"></rect>
<rect class="day" width="10" height="10" x="-5" y="78" fill="rgb(8,64,129)" data-count="13" data-date="2020-05-17"></rect>
</g>
<g transform="translate(280, 0)">
<rect class="day" width="10" height="10" x="-6" y="0" fill="rgb(168,221,181)" data-count="5" data-date="2020-05-18"></rect>
<rect class="day" width="10" height="10" x="-6" y="13" fill="rgb(78,179,211)" data-count="8" data-date="2020-05-19"></rect>
<rect class="day" width="10" height="10" x="-6" y="26" fill="rgb(168,221,181)" data-count="5" data-date="2020-05-20"></rect>
<rect class="day" width="10" height="10" x="-6" y="39" fill="rgb(168,221,181)" data-count="5" data-date="2020-05-21"></rect>
<rect class="day" width="10" height="10" x="-6" y="52" fill="rgb(204,235,197)" data-count="3" data-date="2020-05-22"></rect>
<rect class="day" width="10" height="10" x="-6" y="65" fill="rgb(168,221,181)" data-count="5" data-date="2020-05-23"></rect>
<rect class="day" width="10" height="10" x="-6" y="78" fill="rgb(123,204,196)" data-count="6" data-date="2020-05-24"></rect>
</g>
<g transform="translate(294, 0)">
<rect class="day" width="10" height="10" x="-7" y="0" fill="rgb(204,235,197)" data-count="3" data-date="2020-05-25"></rect>
<rect class="day" width="10" height="10" x="-7" y="13" fill="rgb(168,221,181)" data-count="5" data-date="2020-05-26"></rect>
<rect class="day" width="10" height="10" x="-7" y="26" fill="rgb(78,179,211)" data-count="8" data-date="2020-05-27"></rect>
<rect class="day" width="10" height="10" x="-7" y="39" fill="rgb(224,243,219)" data-count="2" data-date="2020-05-28"></rect>
<rect class="day" width="10" height="10" x="-7" y="52" fill="rgb(224,243,219)" data-count="2" data-date="2020-05-29"></rect>
<rect class="day" width="10" height="10" x="-7" y="65" fill="rgb(78,179,211)" data-count="8" data-date="2020-05-30"></rect>
<rect class="day" width="10" height="10" x="-7" y="78" fill="rgb(168,221,181)" data-count="5" data-date="2020-05-31"></rect>
</g>
<g transform="translate(308, 0)">
<rect class="day" width="10" height="10" x="-8" y="0" fill="rgb(224,243,219)" data-count="1" data-date="2020-06-01"></rect>
<rect class="day" width="10" height="10" x="-8" y="13" fill="rgb(204,235,197)" data-count="3" data-date="2020-06-02"></rect>
<rect class="day" width="10" height="10" x="-8" y="26" fill="rgb(224,243,219)" data-count="1" data-date="2020-06-03"></rect>
<rect class="day" width="10" height="10" x="-8" y="39" fill="rgb(204,235,197)" data-count="3" data-date="2020-06-04"></rect>
<rect class="day" width="10" height="10" x="-8" y="52" fill="rgb(224,243,219)" data-count="1" data-date="2020-06-05"></rect>
<rect class="day" width="10" height="10" x="-8" y="65" fill="rgb(204,235,197)" data-count="3" data-date="2020-06-06"></rect>
<rect class="day" width="10" height="10" x="-8" y="78" fill="rgb(168,221,181)" data-count="5" data-date="2020-06-07"></rect>
</g>
<g transform="translate(322, 0)">
<rect class="day" width="10" height="10" x="-9" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-06-08"></rect>
<rect class="day" width="10" height="10" x="-9" y="13" fill="rgb(224,243,219)" data-count="1" data-date="2020-06-09"></rect>
<rect class="day" width="10" height="10" x="-9" y="26" fill="rgb(224,243,219)" data-count="2" data-date="2020-06-10"></rect>
<rect class="day" width="10" height="10" x="-9" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-06-11"></rect>
<rect class="day" width="10" height="10" x="-9" y="52" fill="rgb(43,140,190)" data-count="9" data-date="2020-06-12"></rect>
<rect class="day" width="10" height="10" x="-9" y="65" fill="rgb(123,204,196)" data-count="7" data-date="2020-06-13"></rect>
<rect class="day" width="10" height="10" x="-9" y="78" fill="rgb(204,235,197)" data-count="4" data-date="2020-06-14"></rect>
</g>
<g transform="translate(336, 0)">
<rect class="day" width="10" height="10" x="-10" y="0" fill="rgb(224,243,219)" data-count="1" data-date="2020-06-15"></rect>
<rect class="day" width="10" height="10" x="-10" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-06-16"></rect>
<rect class="day" width="10" height="10" x="-10" y="26" fill="rgb(224,243,219)" data-count="1" data-date="2020-06-17"></rect>
<rect class="day" width="10" height="10" x="-10" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-06-18"></rect>
<rect class="day" width="10" height="10" x="-10" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-06-19"></rect>
<rect class="day" width="10" height="10" x="-10" y="65" fill="rgb(224,243,219)" data-count="2" data-date="2020-06-20"></rect>
<rect class="day" width="10" height="10" x="-10" y="78" fill="rgb(224,243,219)" data-count="1" data-date="2020-06-21"></rect>
</g>
<g transform="translate(350, 0)">
<rect class="day" width="10" height="10" x="-11" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-06-22"></rect>
<rect class="day" width="10" height="10" x="-11" y="13" fill="rgb(224,243,219)" data-count="2" data-date="2020-06-23"></rect>
<rect class="day" width="10" height="10" x="-11" y="26" fill="rgb(224,243,219)" data-count="2" data-date="2020-06-24"></rect>
<rect class="day" width="10" height="10" x="-11" y="39" fill="rgb(204,235,197)" data-count="3" data-date="2020-06-25"></rect>
<rect class="day" width="10" height="10" x="-11" y="52" fill="rgb(204,235,197)" data-count="3" data-date="2020-06-26"></rect>
<rect class="day" width="10" height="10" x="-11" y="65" fill="rgb(224,243,219)" data-count="2" data-date="2020-06-27"></rect>
<rect class="day" width="10" height="10" x="-11" y="78" fill="rgb(224,243,219)" data-count="1" data-date="2020-06-28"></rect>
</g>
<g transform="translate(364, 0)">
<rect class="day" width="10" height="10" x="-12" y="0" fill="rgb(224,243,219)" data-count="1" data-date="2020-06-29"></rect>
<rect class="day" width="10" height="10" x="-12" y="13" fill="rgb(224,243,219)" data-count="2" data-date="2020-06-30"></rect>
<rect class="day" width="10" height="10" x="-12" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-01"></rect>
<rect class="day" width="10" height="10" x="-12" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-02"></rect>
<rect class="day" width="10" height="10" x="-12" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-03"></rect>
<rect class="day" width="10" height="10" x="-12" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-04"></rect>
<rect class="day" width="10" height="10" x="-12" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-05"></rect>
</g>
<g transform="translate(378, 0)">
<rect class="day" width="10" height="10" x="-13" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-06"></rect>
<rect class="day" width="10" height="10" x="-13" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-07"></rect>
<rect class="day" width="10" height="10" x="-13" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-08"></rect>
<rect class="day" width="10" height="10" x="-13" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-09"></rect>
<rect class="day" width="10" height="10" x="-13" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-10"></rect>
<rect class="day" width="10" height="10" x="-13" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-11"></rect>
<rect class="day" width="10" height="10" x="-13" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-12"></rect>
</g>
<g transform="translate(392, 0)">
<rect class="day" width="10" height="10" x="-14" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-13"></rect>
<rect class="day" width="10" height="10" x="-14" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-14"></rect>
<rect class="day" width="10" height="10" x="-14" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-15"></rect>
<rect class="day" width="10" height="10" x="-14" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-16"></rect>
<rect class="day" width="10" height="10" x="-14" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-17"></rect>
<rect class="day" width="10" height="10" x="-14" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-18"></rect>
<rect class="day" width="10" height="10" x="-14" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-19"></rect>
</g>
<g transform="translate(406, 0)">
<rect class="day" width="10" height="10" x="-15" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-20"></rect>
<rect class="day" width="10" height="10" x="-15" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-21"></rect>
<rect class="day" width="10" height="10" x="-15" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-22"></rect>
<rect class="day" width="10" height="10" x="-15" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-23"></rect>
<rect class="day" width="10" height="10" x="-15" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-24"></rect>
<rect class="day" width="10" height="10" x="-15" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-25"></rect>
<rect class="day" width="10" height="10" x="-15" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-26"></rect>
</g>
<g transform="translate(420, 0)">
<rect class="day" width="10" height="10" x="-16" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-27"></rect>
<rect class="day" width="10" height="10" x="-16" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-28"></rect>
<rect class="day" width="10" height="10" x="-16" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-29"></rect>
<rect class="day" width="10" height="10" x="-16" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-30"></rect>
<rect class="day" width="10" height="10" x="-16" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-07-31"></rect>
<rect class="day" width="10" height="10" x="-16" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-01"></rect>
<rect class="day" width="10" height="10" x="-16" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-02"></rect>
</g>
<g transform="translate(434, 0)">
<rect class="day" width="10" height="10" x="-17" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-03"></rect>
<rect class="day" width="10" height="10" x="-17" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-04"></rect>
<rect class="day" width="10" height="10" x="-17" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-05"></rect>
<rect class="day" width="10" height="10" x="-17" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-06"></rect>
<rect class="day" width="10" height="10" x="-17" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-07"></rect>
<rect class="day" width="10" height="10" x="-17" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-08"></rect>
<rect class="day" width="10" height="10" x="-17" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-09"></rect>
</g>
<g transform="translate(448, 0)">
<rect class="day" width="10" height="10" x="-18" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-10"></rect>
<rect class="day" width="10" height="10" x="-18" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-11"></rect>
<rect class="day" width="10" height="10" x="-18" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-12"></rect>
<rect class="day" width="10" height="10" x="-18" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-13"></rect>
<rect class="day" width="10" height="10" x="-18" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-14"></rect>
<rect class="day" width="10" height="10" x="-18" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-15"></rect>
<rect class="day" width="10" height="10" x="-18" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-16"></rect>
</g>
<g transform="translate(462, 0)">
<rect class="day" width="10" height="10" x="-19" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-17"></rect>
<rect class="day" width="10" height="10" x="-19" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-18"></rect>
<rect class="day" width="10" height="10" x="-19" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-19"></rect>
<rect class="day" width="10" height="10" x="-19" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-20"></rect>
<rect class="day" width="10" height="10" x="-19" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-21"></rect>
<rect class="day" width="10" height="10" x="-19" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-22"></rect>
<rect class="day" width="10" height="10" x="-19" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-23"></rect>
</g>
<g transform="translate(476, 0)">
<rect class="day" width="10" height="10" x="-20" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-24"></rect>
<rect class="day" width="10" height="10" x="-20" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-25"></rect>
<rect class="day" width="10" height="10" x="-20" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-26"></rect>
<rect class="day" width="10" height="10" x="-20" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-27"></rect>
<rect class="day" width="10" height="10" x="-20" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-28"></rect>
<rect class="day" width="10" height="10" x="-20" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-29"></rect>
<rect class="day" width="10" height="10" x="-20" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-30"></rect>
</g>
<g transform="translate(490, 0)">
<rect class="day" width="10" height="10" x="-21" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-08-31"></rect>
<rect class="day" width="10" height="10" x="-21" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-01"></rect>
<rect class="day" width="10" height="10" x="-21" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-02"></rect>
<rect class="day" width="10" height="10" x="-21" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-03"></rect>
<rect class="day" width="10" height="10" x="-21" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-04"></rect>
<rect class="day" width="10" height="10" x="-21" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-05"></rect>
<rect class="day" width="10" height="10" x="-21" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-06"></rect>
</g>
<g transform="translate(504, 0)">
<rect class="day" width="10" height="10" x="-22" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-07"></rect>
<rect class="day" width="10" height="10" x="-22" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-08"></rect>
<rect class="day" width="10" height="10" x="-22" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-09"></rect>
<rect class="day" width="10" height="10" x="-22" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-10"></rect>
<rect class="day" width="10" height="10" x="-22" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-11"></rect>
<rect class="day" width="10" height="10" x="-22" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-12"></rect>
<rect class="day" width="10" height="10" x="-22" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-13"></rect>
</g>
<g transform="translate(518, 0)">
<rect class="day" width="10" height="10" x="-23" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-14"></rect>
<rect class="day" width="10" height="10" x="-23" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-15"></rect>
<rect class="day" width="10" height="10" x="-23" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-16"></rect>
<rect class="day" width="10" height="10" x="-23" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-17"></rect>
<rect class="day" width="10" height="10" x="-23" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-18"></rect>
<rect class="day" width="10" height="10" x="-23" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-19"></rect>
<rect class="day" width="10" height="10" x="-23" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-20"></rect>
</g>
<g transform="translate(532, 0)">
<rect class="day" width="10" height="10" x="-24" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-21"></rect>
<rect class="day" width="10" height="10" x="-24" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-22"></rect>
<rect class="day" width="10" height="10" x="-24" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-23"></rect>
<rect class="day" width="10" height="10" x="-24" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-24"></rect>
<rect class="day" width="10" height="10" x="-24" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-25"></rect>
<rect class="day" width="10" height="10" x="-24" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-26"></rect>
<rect class="day" width="10" height="10" x="-24" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-27"></rect>
</g>
<g transform="translate(546, 0)">
<rect class="day" width="10" height="10" x="-25" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-28"></rect>
<rect class="day" width="10" height="10" x="-25" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-29"></rect>
<rect class="day" width="10" height="10" x="-25" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-09-30"></rect>
<rect class="day" width="10" height="10" x="-25" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-01"></rect>
<rect class="day" width="10" height="10" x="-25" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-02"></rect>
<rect class="day" width="10" height="10" x="-25" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-03"></rect>
<rect class="day" width="10" height="10" x="-25" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-04"></rect>
</g>
<g transform="translate(560, 0)">
<rect class="day" width="10" height="10" x="-26" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-05"></rect>
<rect class="day" width="10" height="10" x="-26" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-06"></rect>
<rect class="day" width="10" height="10" x="-26" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-07"></rect>
<rect class="day" width="10" height="10" x="-26" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-08"></rect>
<rect class="day" width="10" height="10" x="-26" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-09"></rect>
<rect class="day" width="10" height="10" x="-26" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-10"></rect>
<rect class="day" width="10" height="10" x="-26" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-11"></rect>
</g>
<g transform="translate(574, 0)">
<rect class="day" width="10" height="10" x="-27" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-12"></rect>
<rect class="day" width="10" height="10" x="-27" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-13"></rect>
<rect class="day" width="10" height="10" x="-27" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-14"></rect>
<rect class="day" width="10" height="10" x="-27" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-15"></rect>
<rect class="day" width="10" height="10" x="-27" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-16"></rect>
<rect class="day" width="10" height="10" x="-27" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-17"></rect>
<rect class="day" width="10" height="10" x="-27" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-18"></rect>
</g>
<g transform="translate(588, 0)">
<rect class="day" width="10" height="10" x="-28" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-19"></rect>
<rect class="day" width="10" height="10" x="-28" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-20"></rect>
<rect class="day" width="10" height="10" x="-28" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-21"></rect>
<rect class="day" width="10" height="10" x="-28" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-22"></rect>
<rect class="day" width="10" height="10" x="-28" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-23"></rect>
<rect class="day" width="10" height="10" x="-28" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-24"></rect>
<rect class="day" width="10" height="10" x="-28" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-25"></rect>
</g>
<g transform="translate(602, 0)">
<rect class="day" width="10" height="10" x="-29" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-26"></rect>
<rect class="day" width="10" height="10" x="-29" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-27"></rect>
<rect class="day" width="10" height="10" x="-29" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-28"></rect>
<rect class="day" width="10" height="10" x="-29" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-29"></rect>
<rect class="day" width="10" height="10" x="-29" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-30"></rect>
<rect class="day" width="10" height="10" x="-29" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-10-31"></rect>
<rect class="day" width="10" height="10" x="-29" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-01"></rect>
</g>
<g transform="translate(616, 0)">
<rect class="day" width="10" height="10" x="-30" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-02"></rect>
<rect class="day" width="10" height="10" x="-30" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-03"></rect>
<rect class="day" width="10" height="10" x="-30" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-04"></rect>
<rect class="day" width="10" height="10" x="-30" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-05"></rect>
<rect class="day" width="10" height="10" x="-30" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-06"></rect>
<rect class="day" width="10" height="10" x="-30" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-07"></rect>
<rect class="day" width="10" height="10" x="-30" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-08"></rect>
</g>
<g transform="translate(630, 0)">
<rect class="day" width="10" height="10" x="-31" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-09"></rect>
<rect class="day" width="10" height="10" x="-31" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-10"></rect>
<rect class="day" width="10" height="10" x="-31" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-11"></rect>
<rect class="day" width="10" height="10" x="-31" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-12"></rect>
<rect class="day" width="10" height="10" x="-31" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-13"></rect>
<rect class="day" width="10" height="10" x="-31" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-14"></rect>
<rect class="day" width="10" height="10" x="-31" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-15"></rect>
</g>
<g transform="translate(644, 0)">
<rect class="day" width="10" height="10" x="-32" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-16"></rect>
<rect class="day" width="10" height="10" x="-32" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-17"></rect>
<rect class="day" width="10" height="10" x="-32" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-18"></rect>
<rect class="day" width="10" height="10" x="-32" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-19"></rect>
<rect class="day" width="10" height="10" x="-32" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-20"></rect>
<rect class="day" width="10" height="10" x="-32" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-21"></rect>
<rect class="day" width="10" height="10" x="-32" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-22"></rect>
</g>
<g transform="translate(658, 0)">
<rect class="day" width="10" height="10" x="-33" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-23"></rect>
<rect class="day" width="10" height="10" x="-33" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-24"></rect>
<rect class="day" width="10" height="10" x="-33" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-25"></rect>
<rect class="day" width="10" height="10" x="-33" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-26"></rect>
<rect class="day" width="10" height="10" x="-33" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-27"></rect>
<rect class="day" width="10" height="10" x="-33" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-28"></rect>
<rect class="day" width="10" height="10" x="-33" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-29"></rect>
</g>
<g transform="translate(672, 0)">
<rect class="day" width="10" height="10" x="-34" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-11-30"></rect>
<rect class="day" width="10" height="10" x="-34" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-01"></rect>
<rect class="day" width="10" height="10" x="-34" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-02"></rect>
<rect class="day" width="10" height="10" x="-34" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-03"></rect>
<rect class="day" width="10" height="10" x="-34" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-04"></rect>
<rect class="day" width="10" height="10" x="-34" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-05"></rect>
<rect class="day" width="10" height="10" x="-34" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-06"></rect>
</g>
<g transform="translate(686, 0)">
<rect class="day" width="10" height="10" x="-35" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-07"></rect>
<rect class="day" width="10" height="10" x="-35" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-08"></rect>
<rect class="day" width="10" height="10" x="-35" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-09"></rect>
<rect class="day" width="10" height="10" x="-35" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-10"></rect>
<rect class="day" width="10" height="10" x="-35" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-11"></rect>
<rect class="day" width="10" height="10" x="-35" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-12"></rect>
<rect class="day" width="10" height="10" x="-35" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-13"></rect>
</g>
<g transform="translate(700, 0)">
<rect class="day" width="10" height="10" x="-36" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-14"></rect>
<rect class="day" width="10" height="10" x="-36" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-15"></rect>
<rect class="day" width="10" height="10" x="-36" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-16"></rect>
<rect class="day" width="10" height="10" x="-36" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-17"></rect>
<rect class="day" width="10" height="10" x="-36" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-18"></rect>
<rect class="day" width="10" height="10" x="-36" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-19"></rect>
<rect class="day" width="10" height="10" x="-36" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-20"></rect>
</g>
<g transform="translate(714, 0)">
<rect class="day" width="10" height="10" x="-37" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-21"></rect>
<rect class="day" width="10" height="10" x="-37" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-22"></rect>
<rect class="day" width="10" height="10" x="-37" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-23"></rect>
<rect class="day" width="10" height="10" x="-37" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-24"></rect>
<rect class="day" width="10" height="10" x="-37" y="52" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-25"></rect>
<rect class="day" width="10" height="10" x="-37" y="65" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-26"></rect>
<rect class="day" width="10" height="10" x="-37" y="78" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-27"></rect>
</g>
<g transform="translate(728, 0)">
<rect class="day" width="10" height="10" x="-38" y="0" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-28"></rect>
<rect class="day" width="10" height="10" x="-38" y="13" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-29"></rect>
<rect class="day" width="10" height="10" x="-38" y="26" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-30"></rect>
<rect class="day" width="10" height="10" x="-38" y="39" fill="rgb(247,252,240)" data-count="0" data-date="2020-12-31"></rect>
</g>
<text x="14" y="-7" font-size="10px" fill="rgb(100,100,100)">1월</text>
<text x="66" y="-7" font-size="10px" fill="rgb(100,100,100)">2월</text>
<text x="118" y="-7" font-size="10px" fill="rgb(100,100,100)">3월</text>
<text x="170" y="-7" font-size="10px" fill="rgb(100,100,100)">4월</text>
<text x="222" y="-7" font-size="10px" fill="rgb(100,100,100)">5월</text>
<text x="274" y="-7" font-size="10px" fill="rgb(100,100,100)">6월</text>
<text x="326" y="-7" font-size="10px" fill="rgb(100,100,100)">7월</text>
<text x="378" y="-7" font-size="10px" fill="rgb(100,100,100)">8월</text>
<text x="430" y="-7" font-size="10px" fill="rgb(100,100,100)">9월</text>
<text x="482" y="-7" font-size="10px" fill="rgb(100,100,100)">10월</text>
<text x="534" y="-7" font-size="10px" fill="rgb(100,100,100)">11월</text>
<text x="586" y="-7" font-size="10px" fill="rgb(100,100,100)">12월</text>
<text text-anchor="start" font-size="9px" dx="-10" dy="8" fill="rgb(100,100,100)" ></text>
<text text-anchor="start" font-size="9px" dx="-10" dy="21" fill="rgb(100,100,100)" ></text>
<text text-anchor="start" font-size="9px" dx="-10" dy="34" fill="rgb(100,100,100)" ></text>
<text text-anchor="start" font-size="9px" dx="-10" dy="47" fill="rgb(100,100,100)" ></text>
<text text-anchor="start" font-size="9px" dx="-10" dy="60" fill="rgb(100,100,100)" ></text>
<text text-anchor="start" font-size="9px" dx="-10" dy="73" fill="rgb(100,100,100)" ></text>
<text text-anchor="start" font-size="9px" dx="-10" dy="86" fill="rgb(100,100,100)" ></text>
</g></svg>

After

Width:  |  Height:  |  Size: 50 KiB

BIN
docs/nolabels.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

BIN
docs/noseparator.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

28
main.go
View File

@ -7,29 +7,36 @@ import (
"io/ioutil"
"log"
"os"
"path"
"github.com/nikolaydubina/calendarheatmap/charts"
"github.com/nikolaydubina/calendarheatmap/colorscales"
)
func main() {
os.Setenv("CALENDAR_HEATMAP_ASSETS_PATH", "charts/assets")
var (
colorScale string
labels bool
locale string
monthSep bool
outputFormat string
assetsPath string
)
flag.BoolVar(&labels, "labels", true, "labels for weekday and months")
flag.BoolVar(&monthSep, "monthsep", true, "render month separator")
flag.StringVar(&colorScale, "colorscale", "PuBu9", "refer to colorscales for examples")
flag.StringVar(&colorScale, "colorscale", "green-blue-9.csv", "filename of colorscale")
flag.StringVar(&locale, "locale", "en_US", "locale of labels (en_US, ko_KR)")
flag.StringVar(&outputFormat, "output", "png", "output format (png, jpeg, gif, svg)")
flag.StringVar(&assetsPath, "assetspath", "", "absolute path, or relative path for executable, of calendarheatmap repo assets, if not set will try CALENDARHEATMAP_ASSETS env variable, if not will try 'assets'")
flag.Parse()
if assetsPath == "" {
assetsPath = os.Getenv("CALENDAR_HEATMAP_ASSETS_PATH")
if assetsPath == "" {
assetsPath = "assets"
}
}
data, err := ioutil.ReadAll(os.Stdin)
if err != nil {
log.Fatal(err)
@ -40,9 +47,19 @@ func main() {
log.Fatal(err)
}
colorscale, err := charts.NewBasicColorscaleFromCSVFile(path.Join(assetsPath, "colorscales", colorScale))
if err != nil {
log.Fatal(err)
}
fontFace, err := charts.LoadFontFaceFromFile(path.Join(assetsPath, "fonts", "Sunflower-Medium.ttf"))
if err != nil {
log.Fatal(err)
}
conf := charts.HeatmapConfig{
Counts: counts,
ColorScale: colorscales.LoadColorScale(colorScale),
ColorScale: colorscale,
DrawMonthSeparator: monthSep,
DrawLabels: labels,
Margin: 30,
@ -53,6 +70,7 @@ func main() {
BorderColor: color.RGBA{200, 200, 200, 255},
Locale: locale,
Format: outputFormat,
FontFace: fontFace,
}
charts.WriteHeatmap(conf, os.Stdout)
}