@@ -31,12 +31,13 @@ const API_BASE = "https://openholidaysapi.org";
3131let populationData = null ;
3232let cachedData = { Regions : { } } ;
3333let 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+
424452function inDateRange ( date , startDate , endDate , orAdjacentWeekend = false ) {
425453 const start = new Date ( startDate ) ;
426454 const end = new Date ( endDate ) ;
0 commit comments