Last active
January 29, 2021 16:59
-
-
Save notjosh/cafab62e427a5d6bc12aa99d732bb02c to your computer and use it in GitHub Desktop.
COVID vaccination progress in Germany
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const CONFIG = { | |
dataURL: 'https://rki-vaccination-data.vercel.app/api', | |
alsoDrawState: undefined, | |
}; | |
const fetchJSON = async (url) => { | |
const request = new Request(url); | |
const data = await request.loadJSON() | |
return data; | |
}; | |
const drawError = (message) => { | |
const widget = new ListWidget(); | |
let text = widget.addText(message); | |
text.font = Font.mediumSystemFont(16); | |
return widget; | |
}; | |
const drawRegion = ( | |
view, | |
title, | |
{ difference_to_the_previous_day: delta, vaccinated, total: population }, | |
) => { | |
const percent = population > 0 ? vaccinated / population : 0; | |
const stack = view.addStack(); | |
stack.layoutVertically(); | |
stack.spacing = 4; | |
const titleWidget = stack.addText(title) | |
titleWidget.minimumScaleFactor = 0.5; | |
const row = stack.addStack(); | |
row.layoutHorizontally(); | |
row.centerAlignContent(); | |
if (delta !== 0) { | |
row.addText(delta >= 0 ? '+' : '-'); | |
} | |
const deltaWidget = row.addText(delta.toString(10)) | |
deltaWidget.minimumScaleFactor = 0.8; | |
const ctx = new DrawContext(); | |
const size = new Size(58, 4); | |
ctx.size = size; | |
ctx.opaque = false; | |
ctx.respectScreenScale = true; | |
const backgroundColourHex = Device.isUsingDarkAppearance() ? '#666666' : '#dddddd'; | |
ctx.setFillColor(new Color(backgroundColourHex, 0.4)); | |
ctx.fillRect(new Rect(0, 0, size.width, size.height)); | |
ctx.setFillColor(Color.green()); | |
ctx.fillRect(new Rect(0, 0, size.width * percent, size.height)); | |
const image = ctx.getImage(); | |
const imageWidget = stack.addImage(image); | |
imageWidget.cornerRadius = size.height; | |
return stack; | |
} | |
const extractData = (data, state) => { | |
let node; | |
if (state != null) { | |
node = data.states[state]; | |
} else { | |
node = data; | |
} | |
// quick validation | |
const fields = [ | |
'difference_to_the_previous_day', | |
'vaccinated', | |
'total', | |
]; | |
if (node == null) { | |
throw new Error(`missing node${state != null ? ' for state: ' + state : ''}`); | |
} | |
for (const field of fields) { | |
if (node[field] == null) { | |
throw new Error(`missing data: ${field}`); | |
} | |
} | |
return node; | |
}; | |
const drawData = (data) => { | |
const widget = new ListWidget(); | |
const padding = 16; | |
widget.setPadding(padding, padding, padding, padding); | |
drawRegion(widget, '🇩🇪 Germany', extractData(data)); | |
if (CONFIG.alsoDrawState != null) { | |
widget.addSpacer(); | |
const state = CONFIG.alsoDrawState; | |
drawRegion(widget, state, extractData(data, state)); | |
} | |
return widget; | |
} | |
const run = async () => { | |
if (args.widgetParameter != null) { | |
CONFIG.alsoDrawState = args.widgetParameter; | |
} | |
try { | |
const url = `${CONFIG.dataURL}?nocache=${(new Date()).getTime()}`; | |
const data = await fetchJSON(url); | |
return drawData(data); | |
} catch (error) { | |
return drawError(error.message || 'Gasp! An unknown error!'); | |
} | |
}; | |
// for testing: | |
if (config.runsInApp) { | |
//* | |
args = { | |
widgetParameter: 'Brandenburg', | |
...args, | |
} | |
/**/ | |
} | |
const widget = await run(); | |
Script.setWidget(widget); | |
Script.complete(); | |
if (!config.runsInWidget) { | |
widget.presentSmall(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment