Skip to content

Instantly share code, notes, and snippets.

@nickolasb
Created October 14, 2020 13:11
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save nickolasb/f929ef006107f9c474e66ccedd9bacc7 to your computer and use it in GitHub Desktop.
Save nickolasb/f929ef006107f9c474e66ccedd9bacc7 to your computer and use it in GitHub Desktop.
// Examples of Parameters:
// { "areaType" : "ltla" , "areaName" : "Westminster" , "cases" : "newCasesBySpecimenDate" , "accentColor" : "#99ff99" }
// { "areaType" : "utla" , "areaName" : "Hackney and City of London" , "cases" : "newCasesBySpecimenDate" , "accentColor" : "#33cc33" }
// { "areaType" : "region" , "areaName" : "South East" , "cases" : "newCasesByPublishDate" , "accentColor" : "#009900" }
// { "areaType" : "nation" , "areaName" : "England" , "cases" : "newCasesByPublishDate" , "accentColor" : "#009900" }
// USER DEFINITIONS
const lineWeight = 2
const vertLineWeight = .5
// Widget Params, default values for debugging
const widgetParams = JSON.parse((args.widgetParameter != null) ? args.widgetParameter : '{ "areaType" : "utla" , "areaName" : "Hackney and City of London" , "cases" : "newCasesBySpecimenDate" , "accentColor" : "#33cc33" }')
// DON'T CHANGE THE VALUES BELOW
const widgetHeight = 338
const widgetWidth = 720
const areaType = widgetParams.areaType
const areaName = widgetParams.areaName
const cases = widgetParams.cases
const accentColor1 = new Color(widgetParams.accentColor, 1)
const accentColor2 = Color.lightGray()
// Number of days to show
const daysToShow = 15
// space in pixels between the days
const spaceBetweenDays = 44.5
// POSITION AND SIZE
// All coordinates make reference to the top-left of the element.
// Title Name
const titleFontSize = 20
const titleFont = Font.systemFont(titleFontSize)
const titlePos = new Point(25, 15)
// Location Name
const areaNameFontSize = 36
const areaNameFont = Font.semiboldSystemFont(areaNameFontSize)
const areaNameCoords = new Point(25, 38)
// Cases
const casesFontSize = 22
const casesFont = Font.systemFont(casesFontSize)
// Hour
const dayFontSize = 22
const dayFont = Font.systemFont(dayFontSize)
// Supported widget sized: medium
let drawContext = new DrawContext();
drawContext.size = new Size(widgetWidth, widgetHeight)
drawContext.opaque = false
// Retrieve data
let url = "https://api.coronavirus.data.gov.uk/v1/data?filters=areaType=" + areaType + ";areaName=" + areaName + "&structure={\"date\":\"date\",\"cases\":\"" + cases + "\"}"
url = encodeURI(url)
let req = new Request(url)
let json = await req.loadJSON()
let data = json.data
// Create widget
let widget = new ListWidget();
widget.setPadding(0, 0, 0, 0);
// Title
drawTextP("COVID-19 Cases", titlePos, Color.white(), titleFont);
// Location
drawContext.setTextAlignedLeft()
drawTextP(capitalize(areaName), areaNameCoords, accentColor1, areaNameFont);
// Find min, max
let min, max, diff;
for(let i = 0; i < daysToShow; i++) {
let aux = data[i].cases
min = (aux < min || min == undefined ? aux : min)
max = (aux > max || max == undefined ? aux : max)
}
diff = max - min;
const graphLow = 280
const graphHeight = 160
// FOR EACH DAY
drawContext.setTextAlignedCenter()
for (let i = (daysToShow - 1), j = 0; i >= 0; i--, j++) {
let day = (new Date(data[i].date)).getDate()
let dayOfWeek = (new Date(data[i].date)).getDay()
let cases = data[i].cases
let delta = (cases - min) / diff
if (i > 0) {
let nextCases = data[i - 1].cases
let nextDelta = (nextCases - min) / diff
let point1 = new Point(spaceBetweenDays * j + 50, graphLow - (graphHeight * delta))
let point2 = new Point(spaceBetweenDays * (j+1) + 50, graphLow - (graphHeight * nextDelta))
drawLine(point1, point2, lineWeight, accentColor1)
}
// Vertical Line
let point1 = new Point(spaceBetweenDays * j + 50, graphLow - (graphHeight * delta))
let point2 = new Point(spaceBetweenDays * j + 50, graphLow)
drawLine(point1, point2, vertLineWeight, accentColor2)
let dayColor
if (dayOfWeek == 0 || dayOfWeek == 6) {
dayColor = accentColor2
} else {
dayColor = Color.white()
}
// Cases
let casesRect = new Rect(spaceBetweenDays * j + 20, (graphLow - 40) - (graphHeight * delta), 60, casesFontSize + 1)
drawTextR(roundIfNeeded(cases), casesRect, dayColor, casesFont)
// Day
let dayRect = new Rect(spaceBetweenDays * j + 27, graphLow + 10, 50, dayFontSize + 1)
drawTextR(day, dayRect, dayColor, dayFont)
}
// Background
widget.backgroundColor = new Color("#444444", 1)
// Present
widget.backgroundImage = (drawContext.getImage())
widget.presentMedium()
// FUNCTIONS
function roundIfNeeded(n) {
if (Math.floor(n / 1000) > 0) {
return (Math.round(n / 100) / 10) + "k"
}
return n
}
function capitalize(string) {
return string.replace(/\b\w/g, l=>l.toUpperCase())
}
function drawTextP(text, point, color, font) {
drawContext.setFont(font)
drawContext.setTextColor(color)
drawContext.drawText(new String(text).toString(), point)
}
function drawTextR(text, rect, color, font) {
drawContext.setFont(font)
drawContext.setTextColor(color)
drawContext.drawTextInRect(new String(text).toString(), rect)
}
// function drawImage(image, x, y){
// drawContext.drawImageAtPoint(image, new Point(x, y))
// }
function drawLine(point1, point2, width, color){
const path = new Path()
path.move(point1)
path.addLine(point2)
drawContext.addPath(path)
drawContext.setStrokeColor(color)
drawContext.setLineWidth(width)
drawContext.strokePath()
}
Script.complete()
@CarePackageUK
Copy link

Hey thank you for making this, how does one change the location? Mine says Hackney and London.

@nickolasb
Copy link
Author

Hi,
When you add the widget there are 3 fields to configure: “Script”, “When interacting”, “Parameter”.
In “Parameter” you need to pass the region you want to see (If you don’t pass an argument a default value is used to ensure some data is shown). This way it’s possible to have multiple widgets showing different regions.
There are four examples on lines 2-5 of the script showing how to select the lower and upper authorities, region and nation. You probably know the name of the local authorities where you live. If you don’t, please send a message your post code and I’ll reply to you.
Thanks

@nickolasb
Copy link
Author

I think it’s possible to improve the script to gather your location info too... maybe I’ll do it :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment