Skip to content

Commit 8ea2e4b

Browse files
committed
Improve checks for incomplete data
1 parent c616d15 commit 8ea2e4b

File tree

2 files changed

+34
-12
lines changed

2 files changed

+34
-12
lines changed

app.js

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ async function fetchPopulationData() {
200200

201201
for (let element of document.getElementsByClassName("country-item")) {
202202
const population = Object.values(regions(populationData.countries[element.dataset.code])).reduce((a, b) => a + b, 0);
203-
registerTooptip(element, `<span class="tooltip-title">${(population / 1e6).toFixed(1)} ${i18n.mioResidents}</span>\n`);
203+
registerTooptip(element, `<span class="tooltip-title">${formatPopulation(population)}</span>\n`);
204204
}
205205

206206
}
@@ -293,18 +293,19 @@ function calculateDayStatistics(fromDate, toDate) {
293293
let holidayPopulationTotal = 0;
294294
let nationwideHolidayAnyCountry = false;
295295
let incompleteData = new Set();
296+
let incompleteDataPopulation = 0;
296297
const tooltip = [];
297298

298299
for (const country of selectedCountries) {
299300
const {holidays, schoolHolidays} = cachedData[d.getFullYear()][country];
301+
const countryName = countries.find(c => c.code === country)?.name;
300302
const regionNames = cachedData.Regions[country].reduce((d, e) => (d[e.code] = e.name?.[0]?.text, d), {});
301303
const relevant = [];
302304

303305
// --- Feiertage ---
304306
for (const h of holidays) {
305307
if (inDateRange(d, h.startDate, h.endDate)) relevant.push({...h, type: i18n.publicHoliday});
306308
}
307-
if (holidays.length === 0) incompleteData.add(country);
308309

309310
// --- Ferien ---
310311
for (const f of schoolHolidays) {
@@ -313,7 +314,6 @@ function calculateDayStatistics(fromDate, toDate) {
313314
type: i18n.schoolHoliday
314315
});
315316
}
316-
if (schoolHolidays.length === 0 || maxDate(schoolHolidays.map(f => f.endDate)) < d) incompleteData.add(country);
317317

318318
// Count population on holiday
319319
const population = regions(populationData.countries[country]);
@@ -355,11 +355,28 @@ function calculateDayStatistics(fromDate, toDate) {
355355
holidayPopulationTotal += holidayPopulation;
356356
nationwideHolidayAnyCountry |= nationwideHoliday;
357357

358+
359+
// Check for incomplete data
360+
if (holidays.length === 0 || schoolHolidays.length === 0 || maxDate(schoolHolidays.map(f => f.endDate)) < d) {
361+
incompleteData.add(countryName);
362+
incompleteDataPopulation += countryPopTotal;
363+
} else {
364+
// Also check if school holidays are missing completely for any region
365+
let missing = Object.keys(regions(populationData.countries[country])).filter(region => {
366+
const regionHolidays = schoolHolidays.filter(h => h.nationwide || regions(h)?.map(s => s.code.split("-").slice(0, 2).join("-")).includes(region));
367+
return regionHolidays.length === 0 || maxDate(regionHolidays.map(f => f.endDate)) < d;
368+
});
369+
if (missing.length > 0) {
370+
incompleteData.add(countryName + " (" + missing.map(r => regionNames[r]).join(", ") + ")")
371+
incompleteDataPopulation += missing.map(r => population[r]).reduce((a, b) => a + b, 0);
372+
}
373+
}
374+
358375
// infos for tooltip
359376
if (holidayPopulation > 0) {
360377
const c = countries.find(c => c.code === country);
361378
if (selectedCountries.length > 1) {
362-
tooltip.push(`\n<span class="tooltip-country">${c.name}: ${(holidayPopulation / 1e6).toFixed(1)} ${i18n.mioResidents} (${(100 * holidayPopulation / countryPopTotal).toFixed(0)}%)</span>`);
379+
tooltip.push(`\n<span class="tooltip-country">${c.name}: ${formatPopulation(holidayPopulation, countryPopTotal)}</span>`);
363380
}
364381
for (const [label, info] of Object.entries(infos)) {
365382
if (info.All || info.Regions.size > 0) {
@@ -375,23 +392,20 @@ function calculateDayStatistics(fromDate, toDate) {
375392
// Build tooltip text
376393
let tooltipText = "";
377394
if (holidayPopulationTotal > 0){
378-
const summary = `<span class="tooltip-title">${(holidayPopulationTotal / 1e6).toFixed(1)} ${i18n.mioResidents} (${(100 * holidayPopulationTotal / totalPop).toFixed(0)}%)</span>\n`;
395+
const summary = `<span class="tooltip-title">${formatPopulation(holidayPopulationTotal, totalPop)}</span>\n`;
379396
tooltipText += summary + tooltip.join("\n");
380397
} else {
381398
tooltipText += `<span class="tooltip-title">${i18n.noHoliday}</span>`;
382399
}
383400
if (incompleteData.size > 0) {
384-
tooltipText += `\n\n<span class="warning">` + i18n.incompleteData
385-
if (selectedCountries.length > 1){
386-
tooltipText += ": " + [...incompleteData].map(code => countries.find(c => c.code === code).name).join(", ")
387-
}
388-
tooltipText += `</span>`;
401+
tooltipText += `\n\n<span class="warning warning-title">${i18n.incompleteData}: ${formatPopulation(incompleteDataPopulation, totalPop)}</span>`
402+
tooltipText += `\n<span class="warning">${[...incompleteData].join(", ")}</span>`;
389403
}
390404

391405
stats[m][key].tooltip = tooltipText;
392406
stats[m][key].off = nationwideHolidayAnyCountry || d.getDay() === 0; // Sunday
393407
stats[m][key].share = holidayPopulationTotal / totalPop;
394-
stats[m][key].incompleteData = incompleteData.size > 0;
408+
stats[m][key].incompleteData = incompleteDataPopulation / totalPop >= 0.05; // Highlight if error above 5%
395409

396410
}
397411

@@ -491,6 +505,12 @@ function regions(data){
491505
return { ...data.subdivisions, ...data.groups };
492506
}
493507

508+
function formatPopulation(number, total=undefined){
509+
let result = `${(number / 1e6).toFixed(1)} ${i18n.mioResidents}`
510+
if (total !== undefined) result += ` (${(100 * number / total).toFixed(0)}%)`;
511+
return result;
512+
}
513+
494514
function inDateRange(date, startDate, endDate, orAdjacentWeekend = false) {
495515
const start = new Date(startDate);
496516
const end = new Date(endDate);

styles.css

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,9 +207,11 @@ td[data-code]:hover {
207207
}
208208

209209
.warning {
210-
font-weight: bold;
211210
color: #ffc60c;
212211
}
212+
.warning-title {
213+
font-weight: bold;
214+
}
213215

214216
footer {
215217
text-align: center;

0 commit comments

Comments
 (0)