Skip to content

Commit 834cb7f

Browse files
committed
Indicate incomplete data
1 parent dcb7484 commit 834cb7f

File tree

3 files changed

+40
-6
lines changed

3 files changed

+40
-6
lines changed

app.js

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@ const API_BASE = "https://openholidaysapi.org";
3131
let populationData = null;
3232
let cachedData = {Regions: {}};
3333
let i18n = {
34-
publicHoliday: "Feiertag in",
35-
schoolHoliday: "Ferien in",
34+
publicHoliday: "Feiertag",
35+
schoolHoliday: "Ferien",
3636
noHoliday: "Keine Ferien/Feiertage",
3737
in: "in",
3838
nationwide: "landesweit",
3939
mioResidents: "Mio. Einwohner",
40+
incompleteData: "Unvollständige Datenbasis",
4041
dataSources: "Datenquellen"
4142
};
4243

@@ -252,10 +253,11 @@ function calculateDayStatistics(fromDate, toDate) {
252253
d.setHours(0, 0, 0, 0);
253254
const [m, key] = dateKey(d);
254255
if (!stats[m]) stats[m] = {};
255-
stats[m][key] = {share: 0, off: false, tooltip: []};
256+
stats[m][key] = {share: 0, off: false, tooltip: [], incompleteData: false};
256257

257258
let holidayPopulationTotal = 0;
258259
let nationwideHolidayAnyCountry = false;
260+
let incompleteData = new Set();
259261
const tooltip = [];
260262

261263
for (const country of selectedCountries) {
@@ -267,6 +269,7 @@ function calculateDayStatistics(fromDate, toDate) {
267269
for (const h of holidays) {
268270
if (inDateRange(d, h.startDate, h.endDate)) relevant.push({...h, type: i18n.publicHoliday});
269271
}
272+
if (holidays.length === 0) incompleteData.add(country);
270273

271274
// --- Ferien ---
272275
for (const f of schoolHolidays) {
@@ -275,6 +278,7 @@ function calculateDayStatistics(fromDate, toDate) {
275278
type: i18n.schoolHoliday
276279
});
277280
}
281+
if (schoolHolidays.length === 0 || maxDate(schoolHolidays.map(f => f.endDate)) < d) incompleteData.add(country);
278282

279283
// Count population on holiday
280284
const countryPop = populationData.countries[country].subdivisions;
@@ -334,11 +338,27 @@ function calculateDayStatistics(fromDate, toDate) {
334338
}
335339

336340
}
337-
const summary = `<span class="tooltip-title">${(holidayPopulationTotal / 1e6).toFixed(1)} ${i18n.mioResidents} (${(100 * holidayPopulationTotal / totalPop).toFixed(0)}%)</span>\n`;
338-
stats[m][key].tooltip = holidayPopulationTotal > 0 ? summary + tooltip.join("\n") : `<span class="tooltip-title">${i18n.noHoliday}</span>`;
339341

342+
// Build tooltip text
343+
let tooltipText = "";
344+
if (holidayPopulationTotal > 0){
345+
const summary = `<span class="tooltip-title">${(holidayPopulationTotal / 1e6).toFixed(1)} ${i18n.mioResidents} (${(100 * holidayPopulationTotal / totalPop).toFixed(0)}%)</span>\n`;
346+
tooltipText += summary + tooltip.join("\n");
347+
} else {
348+
tooltipText += `<span class="tooltip-title">${i18n.noHoliday}</span>`;
349+
}
350+
if (incompleteData.size > 0) {
351+
tooltipText += `\n\n<span class="warning">` + i18n.incompleteData
352+
if (selectedCountries.length > 1){
353+
tooltipText += ": " + [...incompleteData].map(code => countries.find(c => c.code === code).name).join(", ")
354+
}
355+
tooltipText += `</span>`;
356+
}
357+
358+
stats[m][key].tooltip = tooltipText;
340359
stats[m][key].off = nationwideHolidayAnyCountry || d.getDay() === 0; // Sunday
341360
stats[m][key].share = holidayPopulationTotal / totalPop;
361+
stats[m][key].incompleteData = incompleteData.size > 0;
342362

343363
}
344364

@@ -392,7 +412,11 @@ function renderCalendar(stats) {
392412

393413
if (dayStat) {
394414
const share = dayStat.share || 0;
395-
cell.style.backgroundColor = densityColor(share);
415+
cell.style.background = densityColor(share);
416+
if (dayStat.incompleteData) {
417+
cell.style.background = `repeating-linear-gradient(-45deg, ${cell.style.background}, ${cell.style.background} 8px, transparent 8px, transparent 10px)`;
418+
cell.style.opacity = 0.8;
419+
}
396420
cell.style.fontWeight = dayStat.off ? "bold" : "regular";
397421

398422
// tooltip
@@ -421,6 +445,10 @@ function dateKey(date) {
421445
return [key.slice(0, 7), key]
422446
}
423447

448+
function maxDate(dates){
449+
return new Date(Math.max(...dates.map(s => new Date(s).getTime())));
450+
}
451+
424452
function inDateRange(date, startDate, endDate, orAdjacentWeekend = false) {
425453
const start = new Date(startDate);
426454
const end = new Date(endDate);

i18n/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@
88
"in": "in",
99
"nationwide": "national",
1010
"mioResidents": "M people",
11+
"incompleteData": "Incomplete data",
1112
"dataSources": "Data sources"
1213
}

styles.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,11 @@ td[data-code]:hover {
189189
font-weight: bold;
190190
}
191191

192+
.warning {
193+
font-weight: bold;
194+
color: #ffc60c;
195+
}
196+
192197
footer {
193198
text-align: center;
194199
padding: 1rem;

0 commit comments

Comments
 (0)