Skip to content

Instantly share code, notes, and snippets.

@doceazedo
Last active November 22, 2022 14:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save doceazedo/568cbe00090af5110b5c41e5eaac394e to your computer and use it in GitHub Desktop.
Save doceazedo/568cbe00090af5110b5c41e5eaac394e to your computer and use it in GitHub Desktop.
[Datawrapper Weekly Chart] Visualizing my year on music with a calendar heatmap

Visualizing my year on music with a calendar heatmap

Hi! Just a quick disclaimer. This script was made to fit my needs and with the only purpose of generating my chart data, that means it is quite hardcoded and you may need to do some adjustments if you're planning to use it. For example, you might want to take a look at the albumCovers and badwords variables.

If you just want the 2022 calendar date positions to build your own calendar heatmap, take a look at the calendar.csv file.

You'll need a Last.fm API key and a Spotify access token.

After running the script, look for the file out/dataset.csv on the same directory of the script.

import fs from 'fs';
import { Parser } from 'json2csv';
import { calendar } from './calendar';
const lastfmApiKey = "";
const spotifyToken = "";
const lastfmUsername = "doceazedo911";
const lastfmBaseUrl = `https://ws.audioscrobbler.com/2.0/?user=${lastfmUsername}&api_key=${lastfmApiKey}&format=json&method=`;
let dataset = calendar;
const main = async () => {
await Promise.all(Array(12).fill(null).map((_, i) => getMonthTracks(i + 1)));
getDailyTopTracks();
getIntensity();
redactBadwords();
fixDates();
await getAlbumCovers();
saveDataset();
const scrobbles = dataset.map(day => day.scrobbles).reduce((partial, a) => partial + a, 0);
console.log(`Done! ${scrobbles} scrobbles processed.`);
}
const saveDataset = () => {
const parser = new Parser();
const csv = parser.parse(dataset);
if (!fs.existsSync('out')) fs.mkdirSync('out');
fs.writeFileSync('out/dataset.json', JSON.stringify(dataset, null, 2));
fs.writeFileSync('out/dataset.csv', csv);
}
const getMonthTracks = async (month, year = 2022) => {
const days = new Date(year, month, 0).getDate();
const tracksByDay = await Promise.all(Array(days).fill(null).map(async (_, i) => {
const from = Math.floor(new Date(year, month - 1, i + 1).getTime() / 1000);
const to = Math.floor(new Date(year, month - 1, i + 1, 23, 59, 59).getTime() / 1000);
const resp = await fetch(`${lastfmBaseUrl}user.getrecenttracks&from=${from}&to=${to}&limit=200`);
const data = await resp.json();
let tracks = data.recenttracks.track || [];
if (!Array.isArray(tracks)) tracks = [];
const datasetIndex = dayOfYear(new Date(year, month - 1, i + 1)) - 1;
dataset[datasetIndex] = {
...dataset[datasetIndex],
scrobbles: tracks.length,
tracks
}
return tracks;
}));
return tracksByDay;
}
const getDailyTopTracks = () => {
dataset = dataset.map(day => {
let tracks = [];
day.tracks.map(track => {
const trackKey = `${track.artist['#text']} - ${track.name}`;
if (!tracks.find(track => track.key == trackKey)) tracks.push({
key: trackKey,
value: 0
});
const trackIndex = tracks.findIndex(track => track.key == trackKey);
tracks[trackIndex].value = tracks[trackIndex].value + 1;
});
const topTrack = tracks.length ? tracks.reduce((prev, current) => prev.value > current.value ? prev : current) : null;
let artists = [];
day.tracks.map(track => {
const artistKey = track.artist['#text'];
if (!artists.find(artist => artist.key == artistKey)) artists.push({
key: artistKey,
value: 0
});
const artistIndex = artists.findIndex(artist => artist.key == artistKey);
artists[artistIndex].value = artists[artistIndex].value + 1;
});
const topArtist = artists.length ? artists.reduce((prev, current) => prev.value > current.value ? prev : current) : null;
return {
date: day.date,
x: day.x,
y: day.y,
scrobbles: day.scrobbles,
topTrack: topTrack?.key || '-',
topArtist: topArtist?.key || '-',
}
});
}
const getIntensity = () => {
const maxScrobbles = Math.max(...dataset.map(day => day.scrobbles));
dataset = dataset.map(day => ({
...day,
intensity: intensity(day.scrobbles, maxScrobbles),
}));
}
let albumCovers = {
'Aly & AJ - Potential Breakup Song': 'https://i.scdn.co/image/ab67616d000048519642e82608c68ebc941755de',
'Danny Bond - Traz o B': 'https://i.scdn.co/image/ab67616d00004851b97ac37ba0850227ab63c015',
'Charli XCX - Good Ones': 'https://i.scdn.co/image/ab67616d00004851f629eb64fd8ef76a97b154f5',
'Charli XCX - Used to Know Me': 'https://i.scdn.co/image/ab67616d00004851f629eb64fd8ef76a97b154f5',
'Charli XCX - Yuck': 'https://i.scdn.co/image/ab67616d00004851f629eb64fd8ef76a97b154f5',
'Ghast - pon pon': 'https://i.scdn.co/image/ab67616d00004851589f2529b55c74d718c2e5b4',
'Aly & AJ - Am I Alright': 'https://i.scdn.co/image/ab67616d00004851e4ddc53edc9d5bc840987aa8',
'Lorde - Homemade Dynamite': 'https://i.scdn.co/image/ab67616d00004851f8553e18a11209d4becd0336',
'Kim Petras - Hit It From The Back': 'https://lastfm.freetls.fastly.net/i/u/770x0/a17e38062dc6bd0dec758454b717ba2d.jpg',
'Kim Petras - Problématique': 'https://lastfm.freetls.fastly.net/i/u/770x0/a17e38062dc6bd0dec758454b717ba2d.jpg',
};
const getAlbumCovers = async () => {
dataset = await Promise.all(dataset.map(async (day) => {
let cover = albumCovers?.[day.topTrack];
if (day.scrobbles == 0) cover = '';
if (cover == null) {
const resp = await fetch(`https://api.spotify.com/v1/search?type=track&limit=1&query=${day.topTrack}`, {
headers: {
Authorization: `Bearer ${spotifyToken}`,
"Content-Type": "application/json"
}
});
const data = await resp.json();
cover = data?.tracks?.items?.[0]?.album?.images?.[2]?.url || 'https://i.imgur.com/uSkLYQP.png';
albumCovers[day.topTrack] = cover;
}
return {
...day,
cover
}
}));
}
const badwords = {
Throat: 'Thr**t',
Slut: 'Sl*t',
Fuck: 'F*ck',
Bitch: 'B*tch'
};
const redactBadwords = () => {
dataset = dataset.map(day => {
const topTrack = day.topTrack.split(' ').map(word => badwords?.[word] || word).join(' ');
return {
...day,
topTrack
}
});
}
const fixDates = () => {
dataset = dataset.map(day => ({
...day,
date: `${day.date}${getOrdinalSuffix(parseInt(day.date.replace(/\D/g, '')))}`
}));
}
const dayOfYear = (date) =>
Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24);
const intensity = (partialValue, totalValue) =>
Math.ceil((5 * partialValue) / totalValue);
// Source: https://stackoverflow.com/a/13627586
const getOrdinalSuffix = (i) => {
let j = i % 10,
k = i % 100;
if (j == 1 && k != 11) {
return "st";
}
if (j == 2 && k != 12) {
return "nd";
}
if (j == 3 && k != 13) {
return "rd";
}
return "th";
}
main();
export const calendar = [
// JANUARY
{ date: "January 1", x: 7, y: 0 },
{ date: "January 2", x: 1, y: 1 },
{ date: "January 3", x: 2, y: 1 },
{ date: "January 4", x: 3, y: 1 },
{ date: "January 5", x: 4, y: 1 },
{ date: "January 6", x: 5, y: 1 },
{ date: "January 7", x: 6, y: 1 },
{ date: "January 8", x: 7, y: 1 },
{ date: "January 9", x: 1, y: 2 },
{ date: "January 10", x: 2, y: 2 },
{ date: "January 11", x: 3, y: 2 },
{ date: "January 12", x: 4, y: 2 },
{ date: "January 13", x: 5, y: 2 },
{ date: "January 14", x: 6, y: 2 },
{ date: "January 15", x: 7, y: 2 },
{ date: "January 16", x: 1, y: 3 },
{ date: "January 17", x: 2, y: 3 },
{ date: "January 18", x: 3, y: 3 },
{ date: "January 19", x: 4, y: 3 },
{ date: "January 20", x: 5, y: 3 },
{ date: "January 21", x: 6, y: 3 },
{ date: "January 22", x: 7, y: 3 },
{ date: "January 23", x: 1, y: 4 },
{ date: "January 24", x: 2, y: 4 },
{ date: "January 25", x: 3, y: 4 },
{ date: "January 26", x: 4, y: 4 },
{ date: "January 27", x: 5, y: 4 },
{ date: "January 28", x: 6, y: 4 },
{ date: "January 29", x: 7, y: 4 },
{ date: "January 30", x: 1, y: 5 },
{ date: "January 31", x: 2, y: 5 },
// FEBRUARY
{ date: "February 1", x: 11, y: 0 },
{ date: "February 2", x: 12, y: 0 },
{ date: "February 3", x: 13, y: 0 },
{ date: "February 4", x: 14, y: 0 },
{ date: "February 5", x: 15, y: 0 },
{ date: "February 6", x: 9, y: 1 },
{ date: "February 7", x: 10, y: 1 },
{ date: "February 8", x: 11, y: 1 },
{ date: "February 9", x: 12, y: 1 },
{ date: "February 10", x: 13, y: 1 },
{ date: "February 11", x: 14, y: 1 },
{ date: "February 12", x: 15, y: 1 },
{ date: "February 13", x: 9, y: 2 },
{ date: "February 14", x: 10, y: 2 },
{ date: "February 15", x: 11, y: 2 },
{ date: "February 16", x: 12, y: 2 },
{ date: "February 17", x: 13, y: 2 },
{ date: "February 18", x: 14, y: 2 },
{ date: "February 19", x: 15, y: 2 },
{ date: "February 20", x: 9, y: 3 },
{ date: "February 21", x: 10, y: 3 },
{ date: "February 22", x: 11, y: 3 },
{ date: "February 23", x: 12, y: 3 },
{ date: "February 24", x: 13, y: 3 },
{ date: "February 25", x: 14, y: 3 },
{ date: "February 26", x: 15, y: 3 },
{ date: "February 27", x: 9, y: 4 },
{ date: "February 28", x: 10, y: 4 },
// MARCH
{ date: "March 1", x: 19, y: 0 },
{ date: "March 2", x: 20, y: 0 },
{ date: "March 3", x: 21, y: 0 },
{ date: "March 4", x: 22, y: 0 },
{ date: "March 5", x: 23, y: 0 },
{ date: "March 6", x: 17, y: 1 },
{ date: "March 7", x: 18, y: 1 },
{ date: "March 8", x: 19, y: 1 },
{ date: "March 9", x: 20, y: 1 },
{ date: "March 10", x: 21, y: 1 },
{ date: "March 11", x: 22, y: 1 },
{ date: "March 12", x: 23, y: 1 },
{ date: "March 13", x: 17, y: 2 },
{ date: "March 14", x: 18, y: 2 },
{ date: "March 15", x: 19, y: 2 },
{ date: "March 16", x: 20, y: 2 },
{ date: "March 17", x: 21, y: 2 },
{ date: "March 18", x: 22, y: 2 },
{ date: "March 19", x: 23, y: 2 },
{ date: "March 20", x: 17, y: 3 },
{ date: "March 21", x: 18, y: 3 },
{ date: "March 22", x: 19, y: 3 },
{ date: "March 23", x: 20, y: 3 },
{ date: "March 24", x: 21, y: 3 },
{ date: "March 25", x: 22, y: 3 },
{ date: "March 26", x: 23, y: 3 },
{ date: "March 27", x: 17, y: 4 },
{ date: "March 28", x: 18, y: 4 },
{ date: "March 29", x: 19, y: 4 },
{ date: "March 30", x: 20, y: 4 },
{ date: "March 31", x: 21, y: 4 },
// APRIL
{ date: "April 1", x: 30, y: 0 },
{ date: "April 2", x: 31, y: 0 },
{ date: "April 3", x: 25, y: 1 },
{ date: "April 4", x: 26, y: 1 },
{ date: "April 5", x: 27, y: 1 },
{ date: "April 6", x: 28, y: 1 },
{ date: "April 7", x: 29, y: 1 },
{ date: "April 8", x: 30, y: 1 },
{ date: "April 9", x: 31, y: 1 },
{ date: "April 10", x: 25, y: 2 },
{ date: "April 11", x: 26, y: 2 },
{ date: "April 12", x: 27, y: 2 },
{ date: "April 13", x: 28, y: 2 },
{ date: "April 14", x: 29, y: 2 },
{ date: "April 15", x: 30, y: 2 },
{ date: "April 16", x: 31, y: 2 },
{ date: "April 17", x: 25, y: 3 },
{ date: "April 18", x: 26, y: 3 },
{ date: "April 19", x: 27, y: 3 },
{ date: "April 20", x: 28, y: 3 },
{ date: "April 21", x: 29, y: 3 },
{ date: "April 22", x: 30, y: 3 },
{ date: "April 23", x: 31, y: 3 },
{ date: "April 24", x: 25, y: 4 },
{ date: "April 25", x: 26, y: 4 },
{ date: "April 26", x: 27, y: 4 },
{ date: "April 27", x: 28, y: 4 },
{ date: "April 28", x: 29, y: 4 },
{ date: "April 29", x: 30, y: 4 },
{ date: "April 30", x: 31, y: 4},
// MAY
{ date: "May 1", x: 1, y: 7},
{ date: "May 2", x: 2, y: 7},
{ date: "May 3", x: 3, y: 7},
{ date: "May 4", x: 4, y: 7},
{ date: "May 5", x: 5, y: 7},
{ date: "May 6", x: 6, y: 7},
{ date: "May 7", x: 7, y: 7},
{ date: "May 8", x: 1, y: 8},
{ date: "May 9", x: 2, y: 8},
{ date: "May 10", x: 3, y: 8},
{ date: "May 11", x: 4, y: 8},
{ date: "May 12", x: 5, y: 8},
{ date: "May 13", x: 6, y: 8},
{ date: "May 14", x: 7, y: 8},
{ date: "May 15", x: 1, y: 9},
{ date: "May 16", x: 2, y: 9},
{ date: "May 17", x: 3, y: 9},
{ date: "May 18", x: 4, y: 9},
{ date: "May 19", x: 5, y: 9},
{ date: "May 20", x: 6, y: 9},
{ date: "May 21", x: 7, y: 9},
{ date: "May 22", x: 1, y: 10},
{ date: "May 23", x: 2, y: 10},
{ date: "May 24", x: 3, y: 10},
{ date: "May 25", x: 4, y: 10},
{ date: "May 26", x: 5, y: 10},
{ date: "May 27", x: 6, y: 10},
{ date: "May 28", x: 7, y: 10},
{ date: "May 29", x: 1, y: 11},
{ date: "May 30", x: 2, y: 11},
{ date: "May 31", x: 3, y: 11},
// JUNE
{ date: "June 1", x: 12, y: 7},
{ date: "June 2", x: 13, y: 7},
{ date: "June 3", x: 14, y: 7},
{ date: "June 4", x: 15, y: 7},
{ date: "June 5", x: 9, y: 8},
{ date: "June 6", x: 10, y: 8},
{ date: "June 7", x: 11, y: 8},
{ date: "June 8", x: 12, y: 8},
{ date: "June 9", x: 13, y: 8},
{ date: "June 10", x: 14, y: 8},
{ date: "June 11", x: 15, y: 8},
{ date: "June 12", x: 9, y: 9},
{ date: "June 13", x: 10, y: 9},
{ date: "June 14", x: 11, y: 9},
{ date: "June 15", x: 12, y: 9},
{ date: "June 16", x: 13, y: 9},
{ date: "June 17", x: 14, y: 9},
{ date: "June 18", x: 15, y: 9},
{ date: "June 19", x: 9, y: 10},
{ date: "June 20", x: 10, y: 10},
{ date: "June 21", x: 11, y: 10},
{ date: "June 22", x: 12, y: 10},
{ date: "June 23", x: 13, y: 10},
{ date: "June 24", x: 14, y: 10},
{ date: "June 25", x: 15, y: 10},
{ date: "June 26", x: 9, y: 11},
{ date: "June 27", x: 10, y: 11},
{ date: "June 28", x: 11, y: 11},
{ date: "June 29", x: 12, y: 11},
{ date: "June 30", x: 13, y: 11},
// JULY
{ date: "July 1", x: 22, y: 7},
{ date: "July 2", x: 23, y: 7},
{ date: "July 3", x: 17, y: 8},
{ date: "July 4", x: 18, y: 8},
{ date: "July 5", x: 19, y: 8},
{ date: "July 6", x: 20, y: 8},
{ date: "July 7", x: 21, y: 8},
{ date: "July 8", x: 22, y: 8},
{ date: "July 9", x: 23, y: 8},
{ date: "July 10", x: 17, y: 9},
{ date: "July 11", x: 18, y: 9},
{ date: "July 12", x: 19, y: 9},
{ date: "July 13", x: 20, y: 9},
{ date: "July 14", x: 21, y: 9},
{ date: "July 15", x: 22, y: 9},
{ date: "July 16", x: 23, y: 9},
{ date: "July 17", x: 17, y: 10},
{ date: "July 18", x: 18, y: 10},
{ date: "July 19", x: 19, y: 10},
{ date: "July 20", x: 20, y: 10},
{ date: "July 21", x: 21, y: 10},
{ date: "July 22", x: 22, y: 10},
{ date: "July 23", x: 23, y: 10},
{ date: "July 24", x: 17, y: 11},
{ date: "July 25", x: 18, y: 11},
{ date: "July 26", x: 19, y: 11},
{ date: "July 27", x: 20, y: 11},
{ date: "July 28", x: 21, y: 11},
{ date: "July 29", x: 22, y: 11},
{ date: "July 30", x: 23, y: 11},
{ date: "July 31", x: 17, y: 12},
// AUGUST
{ date: "August 1", x: 26, y: 7},
{ date: "August 2", x: 27, y: 7},
{ date: "August 3", x: 28, y: 7},
{ date: "August 4", x: 29, y: 7},
{ date: "August 5", x: 30, y: 7},
{ date: "August 6", x: 31, y: 7},
{ date: "August 7", x: 25, y: 8},
{ date: "August 8", x: 26, y: 8},
{ date: "August 9", x: 27, y: 8},
{ date: "August 10", x: 28, y: 8},
{ date: "August 11", x: 29, y: 8},
{ date: "August 12", x: 30, y: 8},
{ date: "August 13", x: 31, y: 8},
{ date: "August 14", x: 25, y: 9},
{ date: "August 15", x: 26, y: 9},
{ date: "August 16", x: 27, y: 9},
{ date: "August 17", x: 28, y: 9},
{ date: "August 18", x: 29, y: 9},
{ date: "August 19", x: 30, y: 9},
{ date: "August 20", x: 31, y: 9},
{ date: "August 21", x: 25, y: 10},
{ date: "August 22", x: 26, y: 10},
{ date: "August 23", x: 27, y: 10},
{ date: "August 24", x: 28, y: 10},
{ date: "August 25", x: 29, y: 10},
{ date: "August 26", x: 30, y: 10},
{ date: "August 27", x: 31, y: 10},
{ date: "August 28", x: 25, y: 11},
{ date: "August 29", x: 26, y: 11},
{ date: "August 30", x: 27, y: 11},
{ date: "August 31", x: 28, y: 11},
// SEPTEMBER
{ date: "September 1", x: 5, y: 14},
{ date: "September 2", x: 6, y: 14},
{ date: "September 3", x: 7, y: 14},
{ date: "September 4", x: 1, y: 15},
{ date: "September 5", x: 2, y: 15},
{ date: "September 6", x: 3, y: 15},
{ date: "September 7", x: 4, y: 15},
{ date: "September 8", x: 5, y: 15},
{ date: "September 9", x: 6, y: 15},
{ date: "September 10", x: 7, y: 15},
{ date: "September 11", x: 1, y: 16},
{ date: "September 12", x: 2, y: 16},
{ date: "September 13", x: 3, y: 16},
{ date: "September 14", x: 4, y: 16},
{ date: "September 15", x: 5, y: 16},
{ date: "September 16", x: 6, y: 16},
{ date: "September 17", x: 7, y: 16},
{ date: "September 18", x: 1, y: 17},
{ date: "September 19", x: 2, y: 17},
{ date: "September 20", x: 3, y: 17},
{ date: "September 21", x: 4, y: 17},
{ date: "September 22", x: 5, y: 17},
{ date: "September 23", x: 6, y: 17},
{ date: "September 24", x: 7, y: 17},
{ date: "September 25", x: 1, y: 18},
{ date: "September 26", x: 2, y: 18},
{ date: "September 27", x: 3, y: 18},
{ date: "September 28", x: 4, y: 18},
{ date: "September 29", x: 5, y: 18},
{ date: "September 30", x: 6, y: 18},
// OCTOBER
{ date: "October 1", x: 15, y: 14},
{ date: "October 2", x: 9, y: 15},
{ date: "October 3", x: 10, y: 15},
{ date: "October 4", x: 11, y: 15},
{ date: "October 5", x: 12, y: 15},
{ date: "October 6", x: 13, y: 15},
{ date: "October 7", x: 14, y: 15},
{ date: "October 8", x: 15, y: 15},
{ date: "October 9", x: 9, y: 16},
{ date: "October 10", x: 10, y: 16},
{ date: "October 11", x: 11, y: 16},
{ date: "October 12", x: 12, y: 16},
{ date: "October 13", x: 13, y: 16},
{ date: "October 14", x: 14, y: 16},
{ date: "October 15", x: 15, y: 16},
{ date: "October 16", x: 9, y: 17},
{ date: "October 17", x: 10, y: 17},
{ date: "October 18", x: 11, y: 17},
{ date: "October 19", x: 12, y: 17},
{ date: "October 20", x: 13, y: 17},
{ date: "October 21", x: 14, y: 17},
{ date: "October 22", x: 15, y: 17},
{ date: "October 23", x: 9, y: 18},
{ date: "October 24", x: 10, y: 18},
{ date: "October 25", x: 11, y: 18},
{ date: "October 26", x: 12, y: 18},
{ date: "October 27", x: 13, y: 18},
{ date: "October 28", x: 14, y: 18},
{ date: "October 29", x: 15, y: 18},
{ date: "October 30", x: 9, y: 19},
{ date: "October 31", x: 10, y: 19},
// NOVEMBER
{ date: "November 1", x: 19, y: 14},
{ date: "November 2", x: 20, y: 14},
{ date: "November 3", x: 21, y: 14},
{ date: "November 4", x: 22, y: 14},
{ date: "November 5", x: 23, y: 14},
{ date: "November 6", x: 17, y: 15},
{ date: "November 7", x: 18, y: 15},
{ date: "November 8", x: 19, y: 15},
{ date: "November 9", x: 20, y: 15},
{ date: "November 10", x: 21, y: 15},
{ date: "November 11", x: 22, y: 15},
{ date: "November 12", x: 23, y: 15},
{ date: "November 13", x: 17, y: 16},
{ date: "November 14", x: 18, y: 16},
{ date: "November 15", x: 19, y: 16},
{ date: "November 16", x: 20, y: 16},
{ date: "November 17", x: 21, y: 16},
{ date: "November 18", x: 22, y: 16},
{ date: "November 19", x: 23, y: 16},
{ date: "November 20", x: 17, y: 17},
{ date: "November 21", x: 18, y: 17},
{ date: "November 22", x: 19, y: 17},
{ date: "November 23", x: 20, y: 17},
{ date: "November 24", x: 21, y: 17},
{ date: "November 25", x: 22, y: 17},
{ date: "November 26", x: 23, y: 17},
{ date: "November 27", x: 17, y: 18},
{ date: "November 28", x: 18, y: 18},
{ date: "November 29", x: 19, y: 18},
{ date: "November 30", x: 20, y: 18},
// DECEMBER
{ date: "December 1", x: 29, y: 14},
{ date: "December 2", x: 30, y: 14},
{ date: "December 3", x: 31, y: 14},
{ date: "December 4", x: 25, y: 15},
{ date: "December 5", x: 26, y: 15},
{ date: "December 6", x: 27, y: 15},
{ date: "December 7", x: 28, y: 15},
{ date: "December 8", x: 29, y: 15},
{ date: "December 9", x: 30, y: 15},
{ date: "December 10", x: 31, y: 15},
{ date: "December 11", x: 25, y: 16},
{ date: "December 12", x: 26, y: 16},
{ date: "December 13", x: 27, y: 16},
{ date: "December 14", x: 28, y: 16},
{ date: "December 15", x: 29, y: 16},
{ date: "December 16", x: 30, y: 16},
{ date: "December 17", x: 31, y: 16},
{ date: "December 18", x: 25, y: 17},
{ date: "December 19", x: 26, y: 17},
{ date: "December 20", x: 27, y: 17},
{ date: "December 21", x: 28, y: 17},
{ date: "December 22", x: 29, y: 17},
{ date: "December 23", x: 30, y: 17},
{ date: "December 24", x: 31, y: 17},
{ date: "December 25", x: 25, y: 18},
{ date: "December 26", x: 26, y: 18},
{ date: "December 27", x: 27, y: 18},
{ date: "December 28", x: 28, y: 18},
{ date: "December 29", x: 29, y: 18},
{ date: "December 30", x: 30, y: 18},
{ date: "December 31", x: 31, y: 18},
];
date x y
January 1 7 0
January 2 1 1
January 3 2 1
January 4 3 1
January 5 4 1
January 6 5 1
January 7 6 1
January 8 7 1
January 9 1 2
January 10 2 2
January 11 3 2
January 12 4 2
January 13 5 2
January 14 6 2
January 15 7 2
January 16 1 3
January 17 2 3
January 18 3 3
January 19 4 3
January 20 5 3
January 21 6 3
January 22 7 3
January 23 1 4
January 24 2 4
January 25 3 4
January 26 4 4
January 27 5 4
January 28 6 4
January 29 7 4
January 30 1 5
January 31 2 5
February 1 11 0
February 2 12 0
February 3 13 0
February 4 14 0
February 5 15 0
February 6 9 1
February 7 10 1
February 8 11 1
February 9 12 1
February 10 13 1
February 11 14 1
February 12 15 1
February 13 9 2
February 14 10 2
February 15 11 2
February 16 12 2
February 17 13 2
February 18 14 2
February 19 15 2
February 20 9 3
February 21 10 3
February 22 11 3
February 23 12 3
February 24 13 3
February 25 14 3
February 26 15 3
February 27 9 4
February 28 10 4
March 1 19 0
March 2 20 0
March 3 21 0
March 4 22 0
March 5 23 0
March 6 17 1
March 7 18 1
March 8 19 1
March 9 20 1
March 10 21 1
March 11 22 1
March 12 23 1
March 13 17 2
March 14 18 2
March 15 19 2
March 16 20 2
March 17 21 2
March 18 22 2
March 19 23 2
March 20 17 3
March 21 18 3
March 22 19 3
March 23 20 3
March 24 21 3
March 25 22 3
March 26 23 3
March 27 17 4
March 28 18 4
March 29 19 4
March 30 20 4
March 31 21 4
April 1 30 0
April 2 31 0
April 3 25 1
April 4 26 1
April 5 27 1
April 6 28 1
April 7 29 1
April 8 30 1
April 9 31 1
April 10 25 2
April 11 26 2
April 12 27 2
April 13 28 2
April 14 29 2
April 15 30 2
April 16 31 2
April 17 25 3
April 18 26 3
April 19 27 3
April 20 28 3
April 21 29 3
April 22 30 3
April 23 31 3
April 24 25 4
April 25 26 4
April 26 27 4
April 27 28 4
April 28 29 4
April 29 30 4
April 30 31 4
May 1 1 7
May 2 2 7
May 3 3 7
May 4 4 7
May 5 5 7
May 6 6 7
May 7 7 7
May 8 1 8
May 9 2 8
May 10 3 8
May 11 4 8
May 12 5 8
May 13 6 8
May 14 7 8
May 15 1 9
May 16 2 9
May 17 3 9
May 18 4 9
May 19 5 9
May 20 6 9
May 21 7 9
May 22 1 10
May 23 2 10
May 24 3 10
May 25 4 10
May 26 5 10
May 27 6 10
May 28 7 10
May 29 1 11
May 30 2 11
May 31 3 11
June 1 12 7
June 2 13 7
June 3 14 7
June 4 15 7
June 5 9 8
June 6 10 8
June 7 11 8
June 8 12 8
June 9 13 8
June 10 14 8
June 11 15 8
June 12 9 9
June 13 10 9
June 14 11 9
June 15 12 9
June 16 13 9
June 17 14 9
June 18 15 9
June 19 9 10
June 20 10 10
June 21 11 10
June 22 12 10
June 23 13 10
June 24 14 10
June 25 15 10
June 26 9 11
June 27 10 11
June 28 11 11
June 29 12 11
June 30 13 11
July 1 22 7
July 2 23 7
July 3 17 8
July 4 18 8
July 5 19 8
July 6 20 8
July 7 21 8
July 8 22 8
July 9 23 8
July 10 17 9
July 11 18 9
July 12 19 9
July 13 20 9
July 14 21 9
July 15 22 9
July 16 23 9
July 17 17 10
July 18 18 10
July 19 19 10
July 20 20 10
July 21 21 10
July 22 22 10
July 23 23 10
July 24 17 11
July 25 18 11
July 26 19 11
July 27 20 11
July 28 21 11
July 29 22 11
July 30 23 11
July 31 17 12
August 1 26 7
August 2 27 7
August 3 28 7
August 4 29 7
August 5 30 7
August 6 31 7
August 7 25 8
August 8 26 8
August 9 27 8
August 10 28 8
August 11 29 8
August 12 30 8
August 13 31 8
August 14 25 9
August 15 26 9
August 16 27 9
August 17 28 9
August 18 29 9
August 19 30 9
August 20 31 9
August 21 25 10
August 22 26 10
August 23 27 10
August 24 28 10
August 25 29 10
August 26 30 10
August 27 31 10
August 28 25 11
August 29 26 11
August 30 27 11
August 31 28 11
September 1 5 14
September 2 6 14
September 3 7 14
September 4 1 15
September 5 2 15
September 6 3 15
September 7 4 15
September 8 5 15
September 9 6 15
September 10 7 15
September 11 1 16
September 12 2 16
September 13 3 16
September 14 4 16
September 15 5 16
September 16 6 16
September 17 7 16
September 18 1 17
September 19 2 17
September 20 3 17
September 21 4 17
September 22 5 17
September 23 6 17
September 24 7 17
September 25 1 18
September 26 2 18
September 27 3 18
September 28 4 18
September 29 5 18
September 30 6 18
October 1 15 14
October 2 9 15
October 3 10 15
October 4 11 15
October 5 12 15
October 6 13 15
October 7 14 15
October 8 15 15
October 9 9 16
October 10 10 16
October 11 11 16
October 12 12 16
October 13 13 16
October 14 14 16
October 15 15 16
October 16 9 17
October 17 10 17
October 18 11 17
October 19 12 17
October 20 13 17
October 21 14 17
October 22 15 17
October 23 9 18
October 24 10 18
October 25 11 18
October 26 12 18
October 27 13 18
October 28 14 18
October 29 15 18
October 30 9 19
October 31 10 19
November 1 19 14
November 2 20 14
November 3 21 14
November 4 22 14
November 5 23 14
November 6 17 15
November 7 18 15
November 8 19 15
November 9 20 15
November 10 21 15
November 11 22 15
November 12 23 15
November 13 17 16
November 14 18 16
November 15 19 16
November 16 20 16
November 17 21 16
November 18 22 16
November 19 23 16
November 20 17 17
November 21 18 17
November 22 19 17
November 23 20 17
November 24 21 17
November 25 22 17
November 26 23 17
November 27 17 18
November 28 18 18
November 29 19 18
November 30 20 18
December 1 29 14
December 2 30 14
December 3 31 14
December 4 25 15
December 5 26 15
December 6 27 15
December 7 28 15
December 8 29 15
December 9 30 15
December 10 31 15
December 11 25 16
December 12 26 16
December 13 27 16
December 14 28 16
December 15 29 16
December 16 30 16
December 17 31 16
December 18 25 17
December 19 26 17
December 20 27 17
December 21 28 17
December 22 29 17
December 23 30 17
December 24 31 17
December 25 25 18
December 26 26 18
December 27 27 18
December 28 28 18
December 29 29 18
December 30 30 18
December 31 31 18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment