This repository was archived by the owner on Oct 2, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 60
/
Copy pathgenerate-svg.js
113 lines (101 loc) · 3.26 KB
/
generate-svg.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// Generates SVG file from `public/calendar.json`
const fs = require('fs')
const data = JSON.parse(fs.readFileSync('public/calendar.json', 'utf8'))
const totalWidth = 200
const totalHeight = 185
const hPadding = 10
const cellWidth = (totalWidth - 2 * hPadding) / 7
const calendarStartY = 36
const cellHeight = 24
const occupiedCells = {}
const occupationKey = date =>
`${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`
for (const event of data) {
const startDate = new Date(
event.start.year,
event.start.month - 1,
event.start.date
)
const endDate = event.end
? new Date(event.end.year, event.end.month - 1, event.end.date)
: null
const date = new Date(+startDate)
do {
const key = occupationKey(date)
occupiedCells[key] = (occupiedCells[key] || 0) + 1
date.setDate(date.getDate() + 1)
} while (date.valueOf() <= endDate.valueOf())
}
const monthName = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
]
function generateSVG(year, month) {
const firstDay = new Date(year, month, 1, 0, 0, 0).getDay()
const lastDate = new Date(year, month + 1, 0, 0, 0, 0).getDate()
const svg = `<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" width="${totalWidth}" height="${totalHeight}" viewBox="0 0 ${totalWidth} ${totalHeight}">
<text x="${totalWidth /
2}" y="${24}" font-weight="bold" font-family="Helvetica, Arial, sans-serif" font-size="14" text-anchor="middle" fill="#333">${
monthName[month]
} ${year}</text>
${renderCells()}
</svg>`
return svg
function getPosition(date) {
const day = (firstDay + (date - 1)) % 7
const row = Math.floor((firstDay + (date - 1)) / 7)
const x = hPadding + day * cellWidth
const y = calendarStartY + row * cellHeight
return { x, y }
}
function getCellColor(count) {
if (count <= 0) return '#eee'
if (count <= 1) return '#c6e48b'
if (count <= 2) return '#7bc96f'
if (count <= 3) return '#239a3b'
return '#196127'
}
function renderCells() {
return Array(lastDate)
.fill()
.map((_, i) => i + 1)
.map(date => {
const { x, y } = getPosition(date)
const count =
occupiedCells[occupationKey(new Date(year, month, date))] || 0
const cellColor = getCellColor(count)
return [
`<rect x="${x + 1}" y="${y + 1}" width="${cellWidth -
2}" height="${cellHeight - 2}" fill="${cellColor}" />`,
`<text x="${x + cellWidth / 2}" y="${y +
16}" font-family="Helvetica, Arial, sans-serif" font-size="12" font-weight="${
count > 0 ? 'bold' : 'normal'
}" fill="#333333" text-anchor="middle">${date}</text>`
].join('\n')
})
.join('\n')
}
}
require('mkdirp').sync('public/generated/calendar-images')
for (let year = 2018; year <= 2019; year += 1) {
for (let month = 0; month <= 11; month += 1) {
const svg = generateSVG(year, month)
const path = `public/generated/calendar-images/${year}-${String(
month + 1
).padStart(2, '0')}.svg`
fs.writeFileSync(path, svg)
console.log('* Generated', path)
}
}