diff --git a/number-of-covild-19-vaccinations/README.md b/number-of-covild-19-vaccinations/README.md index e80e416..cc61c76 100644 --- a/number-of-covild-19-vaccinations/README.md +++ b/number-of-covild-19-vaccinations/README.md @@ -18,10 +18,6 @@ Enter the name of you state in the Widget-Parameter: ![Setup](https://raw.githubusercontent.com/ThisIsBenny/iOS-Widgets/main/number-of-covild-19-vaccinations/setup.jpeg) -If you like to show the total values in million instead of thousand, you can add an additional 1 to the Widget-Parameter, which has to be separated by a comma: `Nordrhein-Westfalen,1`. If you do not want to specify a state, you only have to enter a `1` - -![Setup](https://raw.githubusercontent.com/ThisIsBenny/iOS-Widgets/main/number-of-covild-19-vaccinations/alternative.jpeg) - ## Notice Source of the data is the RKI: https://www.rki.de/DE/Content/InfAZ/N/Neuartiges_Coronavirus/Daten/Impfquoten-Tab.html diff --git a/number-of-covild-19-vaccinations/alternative.jpeg b/number-of-covild-19-vaccinations/alternative.jpeg deleted file mode 100644 index c047659..0000000 Binary files a/number-of-covild-19-vaccinations/alternative.jpeg and /dev/null differ diff --git a/number-of-covild-19-vaccinations/number-of-covild-19-vaccinations.js b/number-of-covild-19-vaccinations/number-of-covild-19-vaccinations.js index 6cd8e1e..b876237 100644 --- a/number-of-covild-19-vaccinations/number-of-covild-19-vaccinations.js +++ b/number-of-covild-19-vaccinations/number-of-covild-19-vaccinations.js @@ -1,14 +1,18 @@ // Variables used by Scriptable. // These must be at the very top of the file. Do not edit. // icon-color: red; icon-glyph: syringe; - /************** -Version 1.2.0 + +Version 2.0.0 Changelog: + v2.0.0 + - Show "at least one" and "fully" vaccination in Medium and small widget + - Upgrade to v2 of the API + - Switch to "Mio." numbers instead of "Tsd. v1.2.0 - Large Widget: write percentage to the bar and show total numbers - - Allow to change sorting my add a field namen into sortBy variable: quote, vaccinated, total + - Allow to change sorting my add a field namen into sortBy variable v1.1.1 - Cache path changed - Allow force Update of the data @@ -22,7 +26,7 @@ Changelog: v1.0.1: - fix sorting issue - + /**************/ //////////////////////////////////////////////////////////////////////////////// @@ -32,9 +36,10 @@ Changelog: // How many minutes should the cache be valid let cacheMinutes = 4 * 60 -// enter the name of the field which shoul be used for sorting in the large widget list. -// e.g. 'quote' or 'vaccinated'. Default: State name +// enter the path of the field which should be used for sorting in the large widget list. +// e.g. 'vaccinatedAtLeastOnce.quote' or 'vaccinatedAtLeastOnce.doses'. Default: State name const sortBy = '' +const sortDirection = '' // asc or desc. Default: asc //////////////////////////////////////////////////////////////////////////////// ////////////////////////// Dev Settings //////////////////////// @@ -48,26 +53,20 @@ config.widgetFamily = config.widgetFamily || 'large' //////////////////////////////////////////////////////////////////////////////// let widgetInputRAW = args.widgetParameter -let widgetInput, selectedState, altUnits +let widgetInput, selectedState if (widgetInputRAW !== null && widgetInputRAW !== "") { - widgetInput = widgetInputRAW.toString().split(",") - if(widgetInput.length === 1 && widgetInput[0].trim() === '1') { - altUnits = true - selectedState = undefined - } else { - selectedState = widgetInput[0].trim() - altUnits = widgetInput[1] ? true : false - } + selectedState = widgetInputRAW.toString() if (/^(Baden-Württemberg|Bayern|Berlin|Brandenburg|Bremen|Hamburg|Hessen|Mecklenburg-Vorpommern|Niedersachsen|Nordrhein-Westfalen|Rheinland-Pfalz|Saarland|Sachsen|Sachsen-Anhalt|Schleswig-Holstein|Thüringen)$/.test(selectedState) === false && selectedState !== '' && selectedState !== undefined) { throw new Error('Kein gültiges Bundesland. Bitte prüfen Sie die Eingabe.') } } - -const maximumFractionDigits = altUnits ? 1 : 0 +const altUnits = true +const maximumFractionDigits = 1 const fontSize = 9 const fontSize2 = 12 +const fontSize3 = 7 const spacing = 5 const width = 100 @@ -86,6 +85,17 @@ if (args.queryParameters.forceUpdate) { //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// +function fetchFromObject(obj, prop) { + if(typeof obj === 'undefined') { + return false; + } + let _index = prop.indexOf('.') + if(_index > -1) { + return fetchFromObject(obj[prop.substring(0, _index)], prop.substr(_index + 1)); + } + return obj[prop]; +} + function creatProgress(percentage) { const context = new DrawContext() context.size = new Size(width, h) @@ -116,16 +126,16 @@ function creatProgress(percentage) { path1.addRect(new Rect(0, 0, path1width, h)) context.addPath(path1) context.fillPath() - + context.setTextAlignedCenter() context.setTextColor(Color.white()) context.setFont(Font.systemFont(fontSize - 1)) - context.drawTextInRect(`${percentage.toLocaleString(Device.language())}%`, backgroundReact) + context.drawTextInRect(`${percentage.toLocaleString(Device.language())}`, backgroundReact) return context.getImage() } -function getDiagram(percentage) { +function getDiagram(percentage, percentage2) { function drawArc(ctr, rad, w, deg) { bgx = ctr.x - rad bgy = ctr.y - rad @@ -162,10 +172,10 @@ function getDiagram(percentage) { } const canvas = new DrawContext() const canvSize = 200 - const canvTextSize = 36 + const canvTextSize = 20 const canvWidth = 10 - const canvRadius = 80 + const canvRadius = 85 canvas.opaque = false canvas.size = new Size(canvSize, canvSize) @@ -177,6 +187,12 @@ function getDiagram(percentage) { canvWidth, Math.floor(percentage * 3.6) ) + drawArc( + new Point(canvSize / 2, canvSize / 2), + canvRadius - 15, + canvWidth, + Math.floor(percentage2 * 3.6) + ) const canvTextRect = new Rect( 0, @@ -187,7 +203,7 @@ function getDiagram(percentage) { canvas.setTextAlignedCenter() canvas.setTextColor(Color.gray()) canvas.setFont(Font.boldSystemFont(canvTextSize)) - canvas.drawTextInRect(`${percentage.toLocaleString(Device.language())}%`, canvTextRect) + canvas.drawTextInRect(`${Math.round(percentage).toLocaleString(Device.language())}% / ${Math.round(percentage2).toLocaleString(Device.language())}%`, canvTextRect) return canvas.getImage() } @@ -198,7 +214,7 @@ var today = new Date() const files = FileManager.local() // Set up cache -const cachePath = files.joinPath(files.cacheDirectory(), "widget-vaccination") +const cachePath = files.joinPath(files.cacheDirectory(), "widget-vaccination-v2") const cacheExists = files.fileExists(cachePath) const cacheDate = cacheExists ? files.modificationDate(cachePath) : 0 @@ -213,7 +229,7 @@ try { lastUpdate = cacheDate } else { console.log("Get from API") - const req = new Request('https://rki-vaccination-data.vercel.app/api') + const req = new Request('https://rki-vaccination-data.vercel.app/api/v2') result = await req.loadJSON() lastUpdate = today console.log("Write Data to Cache") @@ -234,6 +250,8 @@ try { console.log("No fallback to cache possible. Due to missing cache.") } } +const germany = result.data.find((e) => e.name === "Deutschland") +const states = result.data.filter((e) => e.isState) if (debug) { console.log(JSON.stringify(result, null, 2)) @@ -269,27 +287,33 @@ if (config.widgetFamily === 'large') { stack.layoutVertically() stack.spacing = spacing - const list = Object.entries(result.states).sort((a, b) => { - if(sortBy && a[1][sortBy] !== undefined && b[1][sortBy] !== undefined) { - return a[1][sortBy] > b[1][sortBy] + const list = states.sort((a, b) => { + const aValue = fetchFromObject(a, sortBy) + const bValue = fetchFromObject(b, sortBy) + if(sortBy && aValue !== undefined && bValue !== undefined) { + if (sortDirection === "" || sortDirection === "asc") { + return aValue > bValue + } else { + return aValue < bValue + } } else { - return a[0].localeCompare(b[0]) + return a.name.localeCompare(b.name) } }) - for (const [key, value] of list) { + for (const value of list) { const row = stack.addStack() row.layoutHorizontally() - const stateText = row.addText(key) + const stateText = row.addText(value.name) stateText.font = Font.mediumSystemFont(fontSize) stateText.lineLimit = 1 row.addSpacer() - const quoteText = row.addText(`${parseInt(value.vaccinated).toLocaleString(Device.language())}`) + const quoteText = row.addText(`${parseInt(value.vaccinatedAtLeastOnce.doses).toLocaleString(Device.language())}`) quoteText.font = Font.systemFont(fontSize) row.addSpacer(4) - const progressBar = row.addImage(creatProgress(value.quote)) + const progressBar = row.addImage(creatProgress(value.vaccinatedAtLeastOnce.quote)) progressBar.imageSize = new Size(width, h) } @@ -301,11 +325,11 @@ if (config.widgetFamily === 'large') { stateText.font = Font.boldSystemFont(fontSize + 1) row.addSpacer() - const quoteText = row.addText(`${parseInt(result.vaccinated).toLocaleString(Device.language())}`) + const quoteText = row.addText(`${parseInt(germany.vaccinatedAtLeastOnce.doses).toLocaleString(Device.language())}`) quoteText.font = Font.boldSystemFont(fontSize + 1) row.addSpacer(4) - const progressBar = row.addImage(creatProgress(result.quote)) + const progressBar = row.addImage(creatProgress(germany.vaccinatedAtLeastOnce.quote)) progressBar.imageSize = new Size(width, h) widget.addSpacer(0) @@ -313,64 +337,81 @@ if (config.widgetFamily === 'large') { const row = widget.addStack() row.layoutHorizontally() - if (selectedState) { + const state = states.find((e) => e.name === selectedState) const column = row.addStack() column.layoutVertically() + //column.addSpacer(2) column.centerAlignContent() const imageStack1 = column.addStack() imageStack1.layoutHorizontally() imageStack1.addSpacer() - imageStack1.addImage(getDiagram(result.states[selectedState].quote)); + imageStack1.addImage(getDiagram(state.vaccinatedAtLeastOnce.quote, state.fullyVaccinated.quote)); imageStack1.addSpacer() - column.addSpacer(2) + column.addSpacer(5) - // Total Numbers - let total1 = result.states[selectedState].total / 1000 - let total1unit = altUnits ? " Tsd." : "t" + // Total Numbers + let total1 = state.inhabitants / 1000 + let total1unit = " Tsd." // if total is a million or more, format as millions and not thousands - if ( altUnits && result.states[selectedState].total > 999999 ){ - total1 = result.states[selectedState].total / 1000000 + if ( altUnits && state.inhabitants > 999999 ){ + total1 = state.inhabitants / 1000000 total1unit = " Mio." } /////////////////////////////////////////////////////////////////// // vaccinated nunbers let vaccinated1 - let vaccinated1unit = altUnits ? " Tsd." : "t" + let vaccinated1unit = " Tsd." - if ( altUnits && result.states[selectedState].vaccinated > 999999){ - vaccinated1 = result.states[selectedState].vaccinated / 1000000 + if (altUnits && state.vaccinatedAtLeastOnce.doses > 999999){ + vaccinated1 = state.vaccinatedAtLeastOnce.doses / 1000000 vaccinated1unit = " Mio." } - else if ( result.states[selectedState].vaccinated > 999 ) { - vaccinated1 = result.states[selectedState].vaccinated / 1000 + else if (state.vaccinatedAtLeastOnce.doses > 999 ) { + vaccinated1 = state.vaccinatedAtLeastOnce.doses / 1000 } else { - vaccinated1 = result.states[selectedState].vaccinated + vaccinated1 = state.vaccinatedAtLeastOnce.doses vaccinated1unit = '' } + let vaccinated1b + let vaccinated1bunit = " Tsd." + + if (altUnits && state.fullyVaccinated.doses > 999999){ + vaccinated1b = state.fullyVaccinated.doses / 1000000 + vaccinated1bunit = " Mio." + } + else if ( state.fullyVaccinated.doses > 999 ) { + vaccinated1b = state.fullyVaccinated.doses / 1000 + } else { + vaccinated1b = state.fullyVaccinated.doses + vaccinated1bunit = '' + } /////////////////////////////////////////////////////////////////// if (maximumFractionDigits === 0) { total1 = parseInt(total1) vaccinated1 = parseInt(vaccinated1) + vaccinated1b = parseInt(vaccinated1b) } - const numbersText1Stack = column.addStack() numbersText1Stack.layoutHorizontally() numbersText1Stack.addSpacer() - const textString1 = `${ parseFloat(vaccinated1) .toLocaleString(Device.language(), {maximumFractionDigits: maximumFractionDigits}) - }${vaccinated1unit} von ${ + }${vaccinated1unit} / ${ + parseFloat(vaccinated1b) + .toLocaleString(Device.language(), {maximumFractionDigits: maximumFractionDigits}) + }${vaccinated1bunit} von ${ parseFloat(total1) .toLocaleString(Device.language(), {maximumFractionDigits: maximumFractionDigits}) }${total1unit}` const numbersText1 = numbersText1Stack.addText(textString1) - numbersText1.font = Font.systemFont(fontSize2) + numbersText1.font = Font.systemFont(fontSize3) + numbersText1.centerAlignText() numbersText1Stack.addSpacer() const stateText1Stack = column.addStack() @@ -386,36 +427,45 @@ if (config.widgetFamily === 'large') { if (!selectedState || config.widgetFamily == 'medium') { const column2 = row.addStack() column2.layoutVertically() + //column2.addSpacer(2) column2.centerAlignContent() const imageStack2 = column2.addStack() imageStack2.layoutHorizontally() imageStack2.addSpacer() - imageStack2.addImage(getDiagram(result.quote)); + imageStack2.addImage(getDiagram(germany.vaccinatedAtLeastOnce.quote, germany.fullyVaccinated.quote)); imageStack2.addSpacer() + column2.addSpacer(5) // Total numbers - let total2 = (result.total / 1000).toFixed(0) - let total2unit = altUnits ? " Tsd." : "t" + let total2 = (germany.inhabitants / 1000).toFixed(0) + let total2unit = " Tsd." // if total is a million or more, format as millions and not thousands - if ( altUnits && result.total > 999999 ){ - total2 = result.total / 1000000 + if (altUnits && germany.inhabitants > 999999 ){ + total2 = germany.inhabitants / 1000000 total2unit = " Mio." } /////////////////////////////////////////////////////////////////// // vaccinated numbers - let vaccinated2 = result.vaccinated / 1000 - let vaccinated2unit = altUnits ? " Tsd." : "t" - if ( altUnits && result.vaccinated > 999999 ){ - vaccinated2 = result.vaccinated / 1000000 + let vaccinated2 = germany.vaccinatedAtLeastOnce.doses / 1000 + let vaccinated2unit = " Tsd." + if ( altUnits && germany.vaccinatedAtLeastOnce.doses > 999999 ){ + vaccinated2 = germany.vaccinatedAtLeastOnce.doses / 1000000 vaccinated2unit = " Mio." } + let vaccinated2b = germany.fullyVaccinated.doses / 1000 + let vaccinated2bunit = " Tsd." + if (altUnits && germany.fullyVaccinated.doses > 999999 ){ + vaccinated2b = germany.fullyVaccinated.doses / 1000000 + vaccinated2bunit = " Mio." + } /////////////////////////////////////////////////////////////////// if (maximumFractionDigits === 0) { total2 = parseInt(total2) vaccinated2 = parseInt(vaccinated2) + vaccinated2b = parseInt(vaccinated2b) } const numbersText2Stack = column2.addStack() @@ -426,13 +476,16 @@ if (config.widgetFamily === 'large') { const textString2 = `${ parseFloat(vaccinated2) .toLocaleString(Device.language(), {maximumFractionDigits: maximumFractionDigits}) - }${vaccinated2unit} von ${ + }${vaccinated2unit} / ${ + parseFloat(vaccinated2b) + .toLocaleString(Device.language(), {maximumFractionDigits: maximumFractionDigits}) + }${vaccinated2bunit} von ${ parseFloat(total2) .toLocaleString(Device.language(), {maximumFractionDigits: maximumFractionDigits}) }${total2unit}` const numbersText2 = numbersText2Stack.addText(textString2) - numbersText2.font = Font.systemFont(fontSize2) + numbersText2.font = Font.systemFont(fontSize3) numbersText2Stack.addSpacer() const stateText2Stack = column2.addStack() diff --git a/number-of-covild-19-vaccinations/previewDark.jpeg b/number-of-covild-19-vaccinations/previewDark.jpeg index de8f544..0862a70 100644 Binary files a/number-of-covild-19-vaccinations/previewDark.jpeg and b/number-of-covild-19-vaccinations/previewDark.jpeg differ diff --git a/number-of-covild-19-vaccinations/previewDark2.jpeg b/number-of-covild-19-vaccinations/previewDark2.jpeg index 024c0ee..f0c89ee 100644 Binary files a/number-of-covild-19-vaccinations/previewDark2.jpeg and b/number-of-covild-19-vaccinations/previewDark2.jpeg differ diff --git a/number-of-covild-19-vaccinations/previewLight.jpeg b/number-of-covild-19-vaccinations/previewLight.jpeg index df08617..8dbbcc3 100644 Binary files a/number-of-covild-19-vaccinations/previewLight.jpeg and b/number-of-covild-19-vaccinations/previewLight.jpeg differ diff --git a/number-of-covild-19-vaccinations/previewLight2.jpeg b/number-of-covild-19-vaccinations/previewLight2.jpeg index 0bb9fb0..e91fca9 100644 Binary files a/number-of-covild-19-vaccinations/previewLight2.jpeg and b/number-of-covild-19-vaccinations/previewLight2.jpeg differ