PageSourceSearch

https://meteologix.com/js/compact.js?v3.52

js meteologix.com collected 2026-09-24 18:11:32 UTC 450,248 bytes, 11,087 lines download raw bytes

1var default_lang_settings = {
2    loading: 'Wird geladen...',
3    months: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
4    weekdays: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
5    shortMonths: ['Jan', 'Feb', 'Mrz', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'],
6};
7
8var simpleTransContainer = {
9    "de": {
10        partialData: "Daten anteilig"
11    },
12    "en" : {
13        partialData: "Partial data"
14    }
15};
16
17var simpleTrans = function (key) {
18    return simpleTransContainer[displayLanguage().toLowerCase()][key];
19}
20
21function cssVar(name, fallback) {
22    const darkBody = document.body.classList.contains('dark');
23    if (darkBody) {
24        // Wert aus body.dark holen
25        return getComputedStyle(document.body).getPropertyValue(name).trim()
26            || getComputedStyle(document.documentElement).getPropertyValue(name).trim()
27            || fallback || '';
28    }
29    // Standardwert aus :root holen
30    var value = getComputedStyle(document.documentElement).getPropertyValue(name).trim();
31    //console.log('cssVar',name,value);
32    return value || fallback || '';
33}
34
35
36var getDynDateFormat = function(x) {
37    var date_format = '';
38    if (typeof hccompact_units['date'] !== 'undefined') {
39        date_format = hccompact_units['date'];
40        if(typeof x !== 'undefined' && date_format.search('{day-nth}')){
41            var day = Highcharts.dateFormat("%e", x);
42            date_format=date_format.replace('{day-nth}',day+nth(day));
43        }
44        return date_format;
45    }
46    if(displayLanguage()=="EN"){
47        var day = Highcharts.dateFormat("%e", x);
48        date_format="%A, %b the "+day+nth(day)+" at %H:%M";
49    }
50    else {
51        date_format="%A, den %e. %B, %H:%M Uhr";
52    }
53    return date_format;
54};
55
56var getDynDayLongFormat = function(x) {
57    var date_format = '';
58    if (typeof hccompact_units['date_day_long'] !== 'undefined') {
59        date_format = hccompact_units['date_day_long'];
60        if(typeof x !== 'undefined' && date_format.search('{day-nth}')){
61            var day = Highcharts.dateFormat("%e", x);
62            date_format=date_format.replace('{day-nth}',day+nth(day));
63        }
64        return date_format;
65    }
66    if(displayLanguage()=="EN"){
67        return '<b>%A</b>, %e. %B';
68    }
69    return '<b>%A</b>, %e. %B';
70};
71
72var getDynDayDateFormat = function(x, width) {
73    var date_format = '';
74    if (typeof hccompact_units['date_day_head'] !== 'undefined') {
75        var sprungmarke = 400;
76        if(typeof x !== 'undefined' && date_format.search('{day-nth}')){
77            sprungmarke = 520;
78        }
79        date_format = hccompact_units['date_day_head'];
80        if (typeof width !== 'undefined' && width <= sprungmarke && typeof hccompact_units['date_day_head_short'] !== 'undefined') {
81            date_format = hccompact_units['date_day_head_short'];
82        }
83        if(typeof x !== 'undefined' && date_format.search('{day-nth}')){
84            var day = Highcharts.dateFormat("%e", x);
85            date_format=date_format.replace('{day-nth}',day+nth(day));
86        }
87        return date_format;
88    }
89    if(displayLanguage()=="EN"){
90        return '<b>%a</b>, %e.%b';
91    }
92    return '<b>%a</b>, %e.%b';
93    /*
94        date_format='<b>%a</b>, %b, '+day+nth(day);
95        date_format='<b>%a</b>';
96        date_format='<b>%a</b>, %e. %b';
97        date_format='<b>%a</b>';
98     */
99};
100var getDynDayShortDateFormat = function(x, width) {
101    var date_format = '';
102    if (typeof hccompact_units['date_day_head_short_date'] !== 'undefined') {
103        date_format = hccompact_units['date_day_head_short_date'];
104        var sprungmarke = 400;
105        if(typeof x !== 'undefined' && date_format.search('{day-nth}')){
106            sprungmarke = 520;
107        }
108        if (typeof width !== 'undefined' && width <= sprungmarke && typeof hccompact_units['date_day_head_short'] !== 'undefined') {
109            date_format = hccompact_units['date_day_head_short'];
110        }
111        if(typeof x !== 'undefined' && date_format.search('{day-nth}')){
112            var day = Highcharts.dateFormat("%e", x);
113            date_format=date_format.replace('{day-nth}',day+nth(day));
114        }
115        return date_format;
116    }
117    if(displayLanguage()=="EN"){
118        return '%e.%b';
119    }
120    return '%e.%b';
121    /*
122        date_format='<b>%a</b>, %b, '+day+nth(day);
123        date_format='<b>%a</b>';
124        date_format='<b>%a</b>, %e. %b';
125        date_format='<b>%a</b>';
126     */
127};
128
129var getDynHourDateFormat = function() {
130    if (typeof hccompact_units['date_hour_head'] !== 'undefined') {
131        return hccompact_units['date_hour_head'];
132    }
133    if(displayLanguage()=="EN"){
134        return '%H:%M';
135    }
136    return '%H:%M';
137};
138var xlAlleNumbers=16;
139var xl925Numbers=3;
140var xl850Numbers=7;
141var xl700Numbers=4;
142var xlWbulbNumbers=3;
143
144var getWindSymbol = function(c) {
145    var img='';
146    if (c>=120) {
147        img = 'sym_wind.svg';
148    }
149    else if (c>=90) {
150        img = 'sym_wind.svg';
151    }
152    else if (c>=70) {
153        img = 'sym_wind_red.svg';
154    }
155    else if (c>=50) {
156        img = 'sym_wind_low.svg';
157    }
158    return img;
159};
160
161/**
162 * Haelt den Tooltip seitlich vom gehoverten Punkt frei.
163 *
164 * Der Tooltip haengt am oberen Rand der Zeichenflaeche und weicht dem Punkt
165 * horizontal aus: bevorzugt nach rechts, sonst nach links. Ist der Chart fuer
166 * beide Seiten zu schmal, wird die Seite mit mehr Platz genommen und der
167 * Tooltip an den Rand geschoben - dann bleibt wenigstens die Haelfte der
168 * Kurve frei.
169 *
170 * Freigehalten wird die Spanne zwischen Mauszeiger und gesnaptem Datenpunkt.
171 * Beide fallen nur bei dicht liegenden Punkten zusammen: bei Tagesdaten (z.B.
172 * 14-Tage-Trend) liegen sie bis zu einem halben Punktabstand auseinander, und
173 * ein Tooltip, der nur den Punkt beruecksichtigt, landet dann unter der Maus.
174 */
175var TOOLTIP_POINT_GAP = 24;
176
177// Letzte bekannte Mausposition. Highcharts reicht das Maus-Event nicht an den
178// positioner durch, deshalb wird es hier passiv mitgeschrieben.
179var tooltipLastMouse = null;
180if (typeof document !== 'undefined' && document.addEventListener) {
181    document.addEventListener('mousemove', function (e) {
182        tooltipLastMouse = { x: e.clientX, y: e.clientY };
183    }, true);
184}
185
186/**
187 * Scroll-Container der Zeichenflaeche.
188 *
189 * Bei `chart.scrollablePlotArea` (auf schmalen Screens immer aktiv) liegt das
190 * SVG in einem horizontal scrollbaren DIV, waehrend die Y-Achse in ein
191 * zusaetzliches, FESTES Overlay (`div.highcharts-fixed`) ausgelagert wird.
192 * Dieses Overlay liegt ueber dem gescrollten Inhalt - alles, was im
193 * gescrollten SVG links unter der Achsenspalte landet, verschwindet also
194 * dahinter.
195 *
196 * Highcharts hat den Container mehrfach umbenannt:
197 *   <  v11  chart.scrollingContainer
198 *   >= v11  chart.scrollablePlotArea.scrollingContainer
199 * Da die Bibliothek vom CDN ohne feste Version geladen wird (siehe
200 * layouts/footer_javascript.php), werden beide Varianten geprueft.
201 */
202var chartScrollingContainer = function (chart) {
203    if (!chart) { return null; }
204    if (chart.scrollingContainer) { return chart.scrollingContainer; }
205    if (chart.scrollablePlotArea && chart.scrollablePlotArea.scrollingContainer) {
206        return chart.scrollablePlotArea.scrollingContainer;
207    }
208    return null;
209};
210
211var tooltipPositioner = function (labelWidth, labelHeight, point) {
212    const chart = this.chart;
213    const scroller = chartScrollingContainer(chart);
214    const offset = scroller ? scroller.scrollLeft : 0;
215
216    // Sichtbarer Ausschnitt: `chartWidth` ist die Breite des Sichtfensters,
217    // das SVG selbst ist um `scrollablePixelsX` breiter.
218    const scrollPx = chart.scrollablePixelsX || 0;
219    const viewWidth = chart.chartWidth;
220
221    // Punktposition im sichtbaren Ausschnitt (bei scrollbarer Zeichenflaeche
222    // ist das nicht die Position im SVG).
223    const pointX = point.plotX + chart.plotLeft - offset;
224
225    // Freizuhaltende Spanne: Punkt und - sofern bekannt - Mauszeiger.
226    let keepFrom = pointX;
227    let keepTo = pointX;
228    if (tooltipLastMouse) {
229        // Bezugsrahmen ist der Scroll-Container: dessen Rechteck entspricht
230        // dem Sichtfenster. Das Container-DIV des Charts waere um
231        // `scrollLeft` verschoben und wuerde die Maus falsch verorten.
232        const box = scroller || chart.container;
233        if (box) {
234            const rect = box.getBoundingClientRect();
235            const mouseX = tooltipLastMouse.x - rect.left;
236            // Nur verwenden, wenn die Maus wirklich ueber diesem Chart steht.
237            if (mouseX >= 0 && mouseX <= viewWidth) {
238                keepFrom = Math.min(keepFrom, mouseX);
239                keepTo = Math.max(keepTo, mouseX);
240            }
241        }
242    }
243
244    // Bereich, in dem der Tooltip ungestoert liegen darf. Bei scrollbarer
245    // Zeichenflaeche verdeckt links die fixierte Achsenspalte und rechts die
246    // Abdeckmaske von Highcharts (beide im `div.highcharts-fixed`).
247    const safeLeft = scrollPx ? chart.plotLeft : 0;
248    const safeRight = scrollPx ? (chart.plotLeft + chart.plotWidth - scrollPx) : viewWidth;
249
250    const spaceRight = safeRight - keepTo - TOOLTIP_POINT_GAP;
251    const spaceLeft = keepFrom - safeLeft - TOOLTIP_POINT_GAP;
252
253    let x;
254    if (spaceRight >= labelWidth) {
255        x = keepTo + TOOLTIP_POINT_GAP;
256    } else if (spaceLeft >= labelWidth) {
257        x = keepFrom - labelWidth - TOOLTIP_POINT_GAP;
258    } else {
259        x = spaceRight >= spaceLeft ? safeRight - labelWidth : safeLeft;
260    }
261
262    // Nie in die fixierte Achsenspalte bzw. ueber den Chartrand hinaus. Passt
263    // der Tooltip nicht in den sicheren Bereich, gewinnt der linke Rand -
264    // rechts steht er dann hoechstens ueber dem schmalen Aussenrand.
265    x = Math.min(x, safeRight - labelWidth);
266    x = Math.max(safeLeft, x);
267
268    // Y: Der Tooltip haengt am oberen Rand der Zeichenflaeche. Herausragen
269    // kann er nicht: die Zeichenflaeche der XL-Charts ist praktisch immer
270    // horizontal scrollbar, und der Scroll-Container muss `overflow-y` dann
271    // zwingend auf auto/hidden halten - per CSS ist dagegen nichts zu machen.
272    // Deshalb wird er so weit nach oben geschoben, dass er hineinpasst. Damit
273    // er gar nicht erst zu hoch wird, setzt der Formatter die Modellliste ab
274    // vielen Modellen zweispaltig (siehe XL_TT_COLUMN_THRESHOLD).
275    let y = chart.plotTop;
276    if (scrollPx) {
277        y = Math.max(0, Math.min(y, chart.chartHeight - labelHeight));
278    }
279
280    return {
281        x: x + offset,
282        y: y
283    };
284};
285
286
287var getMinWidth = function (days){
288    var factor = 1;
289    var width = $(window).width();
290    if(width <= 576) {
291        factor = 0.7;
292    } else if(width <= 768) {
293        factor = 0.8;
294    } else if(width <= 992) {
295        factor = 0.9;
296    } else if(width <= 1200) {
297        factor = 0.95;
298    }
299
300    if(typeof hccompact_xmax !== "undefined" && typeof hccompact_xmin !== "undefined") {
301        return ((hccompact_xmax - hccompact_xmin) / (60 * 60) / 1000 * 5) * factor;
302    }
303
304    if (typeof hcMinWidth !== "undefined") {
305        return hcMinWidth * factor;
306    }
307
308    return null;
309};
310
311
312
313
314var tooltip14DaysTrend = {
315    crosshairs: true,
316    shared: true,
317    useHTML: true,
318    positioner: tooltipPositioner,
319    formatter: function() {
320        var s = [];
321        var counter=0;
322        var durchlauf=0;
323        var tmaxmin='';
324        var windtext='';
325        var counter=0;
326        var img = '', rain='',maxminv='';
327        s.push('<div class="tt14d tt14d-overview">');
328        var a=0;
329        $.each(this.points, function(i, p) {
330            a=this.series.data.indexOf( this.point );
331
332            if (counter===0) {
333                //console.log(p);
334                s.push('<div class="tt14d-date">' + p.x + '<br><small>' + hc_data_14days_weekdays[a] + '</small></div>');
335                s.push('<div class="tt14d-icons">');
336                if (typeof hc_data_14days_ssym[a] !== 'undefined' && hc_data_14days_ssym[a]) {
337                        s.push('<img src="/images/layout/icons/trend/cloudcoverage-'+hc_data_14days_ssym[a]+'.svg" alt="" class="tt14d-sun" /> ');
338                }
339                if (typeof hc_data_14days_rtype[a] !== 'undefined' && hc_data_14days_rtype[a] !== null && typeof hc_data_14days_rint[a] !== 'undefined' && hc_data_14days_rint[a]>0) {
340                        s.push('<img src="/images/layout/icons/trend/precipitation-'+hc_data_14days_rtype[a]+hc_data_14days_rint[a]+'.svg" alt="" class="tt14d-rain" /> ');
341                }
342                if (typeof hc_data_14days_tsym[a] !== 'undefined' && hc_data_14days_tsym[a]>0) {
343                        s.push('<img src="/images/layout/icons/trend/thunderstorm-'+hc_data_14days_tsym[a]+'.svg" alt="" class="tt14d-thun
343derstorm" /> ');
344                }
345                if (typeof hc_data_14days_gusts[a] !== 'undefined'
346                    && typeof hc_data_14days_gusts_raw[a] !== 'undefined') {
347                    var b =hc_data_14days_gusts[a];
348                    img = getWindSymbol(hc_data_14days_gusts_raw[a]);
349                    if (img.length>0) {
350                        if (displayFCUnitV() == 'kmh') {
351                            b = Math.round(Math.ceil(b/5)*5);
352                        }
353                        else {
354                            b = Math.round(b);
355                        }
356                        var einheit = $('#w-14days-data').attr('data-gunit');
357                        windtext = $('#w-14days-data').attr('data-gusts')+' '+b+(einheit === 'Bft' ? ' ':'')+einheit+'.';
358                        s.push('<img src="/images/symbole/'+img+'" alt="" class="tt14d-thunderstorm" /> ');
359                    }
360                }
361                s.push('</div>');
362            }
363            counter++;
364        });
365
366        s.push('<div class="tt14d-overview-data">');
367        counter=0;
368        var max_string='', min_string='';
369        $.each(this.points, function(i, p) {
370            if (durchlauf === 0 || durchlauf === 1) {
371                var a=this.series.data.indexOf( this.point );
372                $.each(hc_data_14days_maxmin, function(j,q) {
373                    if (j === 0 || j === 1) {
374                        if (typeof q.data !== 'undefined' && typeof q.data[a] !== 'undefined' && q.data[a] !== null) {
375                            if (j === 0) {
376                                max_string='<strong>'+Highcharts.numberFormat(q.data[a],0)+hccompact_units['temp']+'</strong>';
377                            }
378                            else {
379                                min_string='<strong>'+Highcharts.numberFormat(q.data[a],0)+hccompact_units['temp']+'</strong>';
380                            }
381                        }
382                    }
383                });
384            }
385            var min_max=-999, min_min=1000;
386            if (p.point.low < min_min) { min_min=p.point.low; }
387            if (p.point.high < min_min) { min_min=p.point.high; }
388            if (p.point.low > min_max) { min_max=p.point.low; }
389            if (p.point.high > min_max) { min_max=p.point.high; }
390            if (min_max !== -999 && min_min !== 1000) {
391                if (i === 0) {
392                    s.push('<div class="tt14d-row clearhigh">'+$('#w-14days-data').attr('data-max')+': '+max_string+'<br /><em>('+$('#w-14days-data').attr('data-bandbreite')+' '+$('#w-14days-data').attr('data-from')+' '+Highcharts.numberFormat(min_min,0) +hccompact_units['temp']+' '+$('#w-14days-data').attr('data-to')+' ' +Highcharts.numberFormat(min_max,0) +hccompact_units['temp']+ ')</em></div>');
393                }
394                else if (i === 1) {
395                    s.push('<div class="tt14d-row">'+$('#w-14days-data').attr('data-min')+': '+min_string+'<br /><em>('+$('#w-14days-data').attr('data-bandbreite')+' '+$('#w-14days-data').attr('data-from')+' '+Highcharts.numberFormat(min_min,0) +hccompact_units['temp']+' '+$('#w-14days-data').attr('data-to')+' ' +Highcharts.numberFormat(min_max,0) +hccompact_units['temp']+ ')</em></div>');
396                }
397            }
398            counter++;
399        });
400        s.push('</div>');
401        s.push('<div class="tt14d-prob">');
402        if (typeof hc_data_14days_word[a] !== 'undefined' && hc_data_14days_word[a].length>0) {
403            s.push(hc_data_14days_word[a]);
404        }
405        if (windtext.length>0) {
406            s.push(windtext);
407        }
408        s.push('</div>');
409        s.push('</div>');
410        return '<div class="highcharts-tooltip highcharts-tooltip-14">' + s.join(' ') + '</div>';
411    }
412};
413
414var tooltip14DaysTrendSun = {
415    crosshairs: true,
416    shared: true,
417    useHTML: true,
418    positioner: tooltipPositioner,
419
420    formatter: function() {
421        var s = [];
422        s.push('<div class="tt14d tt14d-sun">');
423        var counter = 0;
424        var a=0;
425        $.each(this.points, function(i, p) {
426            a=this.series.data.indexOf( this.point );
427        });
428
429        if (typeof hc_data_14days_ssym[a] !== 'undefined' && hc_data_14days_ssym[a]) {
430                s.push('<div class="tt14d-sun-detail"><img src="/images/layout/icons/trend/cloudcoverage-'+hc_data_14days_ssym[a]+'.svg" alt="" /></div>');
431        }
432        s.push('<div class="tt14d-date">'+this.x + '<br><small>' + hc_data_14days_weekdays[a] + '</small></div>');
433        $.each(hc_data_14days_sun, function(j,q) {
434            if (j === 0) {
435                s.push('<div class="tt14d-sun-estimated">');
436                if (typeof q.data !== 'undefined' && typeof q.data[a] !== 'undefined' && q.data[a] !== null) {
437                    s.push($('#w-14days-data').attr('data-sunshineduration')+': <strong>'+Highcharts.numberFormat(q.data[a],1)+'&nbsp;'+$('#w-14days-data').attr('data-hours')+'</strong> ');
438                }
439                if(typeof hc_data_14days_sun_rel[a] !== 'undefined' && hc_data_14days_sun_rel[a] !== 'null') {
440                    s.push('<div class="tt14d-astro">('+Highcharts.numberFormat(hc_data_14days_sun_rel[a],0)+'% '+$('#w-14days-data').attr('data-maxsunshine')+')</div>');
441                }
442                s.push('</div>');
443        }
444        });
445        counter=0;
446        $.each(this.points, function(i, p) {
447            if (counter===0) {
448                s.push('<div class="clearfix"></div>');
449            }
450            var min_max=-999, min_min=1000;
451            if (p.point.low < min_min) { min_min=p.point.low; }
452            if (p.point.high < min_min) { min_min=p.point.high; }
453            if (p.point.low > min_max) { min_max=p.point.low; }
454            if (p.point.high > min_max) { min_max=p.point.high; }
455            if (min_max !== -999 && min_min !== 1000) {
456                s.push('<div class="tt14d-sun-range">'+$('#w-14days-data').attr('data-epsrange')+' '+Highcharts.numberFormat(min_min,
4561) +' '+$('#w-14days-data').attr('data-to')+' ' +Highcharts.numberFormat(min_max,1) + '&nbsp;'+$('#w-14days-data').attr('data-hours')+'</div>');
457            }
458            counter++;
459        });
460        s.push('</div>');
461        return '<div class="highcharts-tooltip highcharts-tooltip-14">' + s.join(' ') + '</div>';
462    }
463};
464
465var tooltip14DaysTrendRain = {
466    crosshairs: true,
467    shared: true,
468    useHTML: true,
469    positioner: tooltipPositioner,
470
471    formatter: function() {
472        var s = [];
473        s.push('<div class="tt14d tt14d-rain">');
474        var counter = 0;
475        var a=0;
476        $.each(this.points, function(i, p) {
477            a=this.series.data.indexOf( this.point );
478        });
479
480        if (typeof hc_data_14days_rtype[a] !== 'undefined' && hc_data_14days_rtype[a] !== null && typeof hc_data_14days_rint[a] !== 'undefined' && hc_data_14days_rint[a] !== 'null') {
481                s.push('<div class="tt14d-rain-detail">');
482                if (typeof hc_data_14days_tsym[a] !== 'undefined' && hc_data_14days_tsym[a] !== 'null' && hc_data_14days_tsym[a]>0) {
483                        s.push('<img src="/images/layout/icons/trend/thunderstorm-1.svg" alt="" />');
484                }
485                s.push('<img src="/images/layout/icons/trend/precipitation-'+hc_data_14days_rtype[a]+hc_data_14days_rint[a]+'.svg" alt="" />');
486                s.push('</div>');
487        }
488        s.push('<div class="tt14d-date">'+this.x +'<br><small>' + hc_data_14days_weekdays[a] + '</small></div>');
489        $.each(hc_data_14days_rain, function(j,q) {
490            if (j === 0) {
491                s.push('<div class="tt14d-rain-estimated">');
492                if (typeof q.data !== 'undefined' && typeof q.data[a] !== 'undefined' && q.data[a] !== null) {
493                    s.push($('#w-14days-data').attr('data-ptotal')+': <strong>'+Highcharts.numberFormat(q.data[a],1)+'&nbsp;'+hccompact_units['rain']+'</strong> ');
494                }
495                if(typeof hc_data_14days_prob[a] !== 'undefined' && hc_data_14days_prob[a] !== 'null') {
496                    s.push('<div class="tt14d-rainprob">('+Highcharts.numberFormat(hc_data_14days_prob[a],0)+'% '+$('#w-14days-data').attr('data-pprob')+')</div>');
497                }
498                s.push('</div>');
499        }
500        });
501        counter=0;
502        s.push('<div class="tt14d-rain-range">');
503        $.each(this.points, function(i, p) {
504            if (counter===0) {
505                s.push('<div class="clearfix"></div>');
506            }
507            var min_max=-999, min_min=1000;
508            if (p.point.low < min_min) { min_min=p.point.low; }
509            if (p.point.high < min_min) { min_min=p.point.high; }
510            if (p.point.low > min_max) { min_max=p.point.low; }
511            if (p.point.high > min_max) { min_max=p.point.high; }
512            if (min_max !== -999 && min_min !== 1000) {
513                s.push($('#w-14days-data').attr('data-epsrange')+' '+Highcharts.numberFormat(min_min,1) +'&nbsp;'+hccompact_units['rain']+' '+$('#w-14days-data').attr('data-to')+' ' +Highcharts.numberFormat(min_max,1) + '&nbsp;'+hccompact_units['rain']+'.');
514            }
515            counter++;
516        });
517        
518        s.push('</div>');
519        s.push('</div>');
520        return '<div class="highcharts-tooltip highcharts-tooltip-14">' + s.join(' ') + '</div>';
521    }
522};
523
524var tooltip14DaysTrendGusts = {
525    crosshairs: true,
526    shared: true,
527    useHTML: true,
528    positioner: tooltipPositioner,
529
530    formatter: function() {
531        var s = [];
532        s.push('<div class="tt14d tt14d-gusts">');
533        var counter = 0;
534        var a=0;
535        $.each(this.points, function(i, p) {
536            a=this.series.data.indexOf( this.point );
537        });
538
539        if (typeof hc_data_14days_gusts_raw[a] !== 'undefined') {
540            img = getWindSymbol(hc_data_14days_gusts_raw[a]);
541            if (img.length>0) {
542                s.push('<div class="tt14d-gusts-detail"><img src="/images/symbole/'+img+'" alt="" class="tt14d-thunderstorm" /></div>');
543            }
544        }
545        s.push('<div class="tt14d-date">'+this.x +'<br><small>' + hc_data_14days_weekdays[a] + '</small></div>');
546        $.each(hc_data_14days_wind, function(j,q) {
547            if (j === 0) {
548                s.push('<div class="tt14d-gusts-estimated">');
549                if (typeof q.data !== 'undefined' && typeof q.data[a] !== 'undefined' && q.data[a] !== null) {
550                    s.push($('#w-14days-data').attr('data-estgusts')+': <strong>'+$('#w-14days-data').attr('data-upto')+'&nbsp;'+Highcharts.numberFormat(q.data[a],0)+'&nbsp;'+hccompact_units['wind']+'</strong> ');
551                }
552                s.push('<div class="tt14d-gusts-note">'+$('#w-14days-data').attr('data-gustnote')+'</div>');
553                s.push('</div>');
554        }
555        });
556        counter=0;
557        $.each(this.points, function(i, p) {
558            if (counter===0) {
559                s.push('<div class="clearfix"></div>');
560            }
561            var min_max=-999, min_min=1000;
562            if (p.point.low < min_min) { min_min=p.point.low; }
563            if (p.point.high < min_min) { min_min=p.point.high; }
564            if (p.point.low > min_max) { min_max=p.point.low; }
565            if (p.point.high > min_max) { min_max=p.point.high; }
566            if (min_max !== -999 && min_min !== 1000) {
567                s.push('<div class="tt14d-gusts-range">'+$('#w-14days-data').attr('data-epsrange')+' '+Highcharts.numberFormat(min_min,0) +'&nbsp;'+hccompact_units['wind']+' '+$('#w-14days-data').attr('data-to')+' ' +Highcharts.numberFormat(min_max,0) + '&nbsp;'+hccompact_units['wind']+'</div>');
568            }
569            counter++;
570        });
571        s.push('</div>');
572        return '<div class="highcharts-tooltip highcharts-tooltip-14">' + s.join(' ') + '</div>';
573    }
574};
575
576/* ---------------------------------------------------------------------------
577 * Hoehenbegrenzung der XL-Diagramme auf mobilen Viewports.
578 *
579 * Die Regeln unten arbeiten mit festen Pixelhoehen, die sich an der *Chart-
580 * breite* orientieren. Auf Telefonen fuehrt das dazu, dass ein Diagramm fast
581 * die gesamte Bildschirmhoehe einnimmt, ohne zusaetzliche Information zu
582 * liefern. Deshalb wird die Hoehe hier zusaetzlich an der Viewporthoehe
583 * gedeckelt: im Hochformat auf 40%, im Querformat auf 60%.
584 * Auf Desktopbreiten bleibt alles unveraendert.
585 * ------------------------------------------------------------------------ */
586var XL_MOBILE_MAX_WIDTH   = 767;  // schmaler Viewport: Telefon im Hochformat
587var XL_MOBILE_MAX_HEIGHT  = 500;  // niedriger Viewport: Telefon im Querformat
588var XL_HEIGHT_PORTRAIT    = 0.4;
589var XL_HEIGHT_LANDSCAPE   = 0.6;
590var XL_MIN_CHART_HEIGHT   = 220;  // Untergrenze, damit die Achsen lesbar bleiben
591
592/* Liefert die erlaubte Maximalhoehe oder 0, wenn nicht begrenzt werden soll.
593 *
594 * Die Breite allein reicht zur Erkennung nicht aus: aktuelle Telefone sind im
595 * Querformat breiter als 767px (z.B. 844x390). Deshalb gilt ein Viewport auch
596 * dann als mobil, wenn er sehr niedrig ist. */
597var xlMaxChartHeight = function () {
598    if (typeof window === 'undefined') {
599        return 0;
600    }
601    var vw = window.innerWidth || 0,
602        vh = window.innerHeight || 0;
603    if (!vw || !vh) {
604        return 0;
605    }
606    if (vw > XL_MOBILE_MAX_WIDTH && vh > XL_MOBILE_MAX_HEIGHT) {
607        return 0; // Desktop - unveraendert lassen.
608    }
609    var share = vh >= vw ? XL_HEIGHT_PORTRAIT : XL_HEIGHT_LANDSCAPE;
610    return Math.max(Math.round(vh * share), XL_MIN_CHART_HEIGHT);
611};
612
613/* Deckelt eine Hoehe, vergroessert sie aber nie. */
614var xlCapHeight = function (h) {
615    var max = xlMaxChartHeight();
616    return max ? Math.min(h, max) : h;
617};
618
619/* Zuletzt angewandte Layout-Lage. Bewusst *nicht* der Pixelwert: iOS aendert
620 * window.innerHeight beim Ein- und Ausblenden der Adressleiste waehrend des
621 * Scrollens. Ein Vergleich der Pixelhoehe wuerde dabei staendig alle Diagramme
622 * neu zeichnen. Nur ein echter Wechsel Hoch-/Querformat bzw. mobil/Desktop
623 * loest ein Neuzeichnen aus. */
624var xlHeightCapState = null;
625var xlHeightCapTimer = null;
626
627var xlLayoutKey = function () {
628    if (typeof window === 'undefined') {
629        return 'd';
630    }
631    var vw = window.innerWidth || 0,
632        vh = window.innerHeight || 0;
633    if (!vw || !vh || (vw > XL_MOBILE_MAX_WIDTH && vh > XL_MOBILE_MAX_HEIGHT)) {
634        return 'd';
635    }
636    return vh >= vw ? 'm-portrait' : 'm-landscape';
637};
638
639var xlChartOptions = function (max_modelle) {
640    var height_xs,height_sm, height_md, height_lg;
641    height_xs=600;
642    height_sm=500;
643    height_md=470;
644    height_lg=450;
645    if (parseInt(max_modelle) <=4 ) {
646        height_xs=380;
647        height_sm=340;
648        height_md=360;
649        height_lg=350;
650    }
651    else if (parseInt(max_modelle) <=8 ) {
652        height_xs=420;
653        height_sm=370;
654        height_md=360;
655        height_lg=350;
656    }
657    else if (parseInt(max_modelle) >12 ) {
658        height_xs=610;
659        height_sm=610;
660        height_md=500;
661        height_lg=480;
662    }
663    // Lage merken, damit der Resize-Handler erkennt, ob sich etwas geaendert hat.
664    xlHeightCapState = xlLayoutKey();
665    return {
666        // Kein Highcharts-Option, sondern eine Notiz fuer xlRefreshChartHeights():
667        // damit laesst sich die Regelmenge nach einem Orientierungswechsel mit
668        // derselben Modellzahl neu aufbauen.
669        xlModels: max_modelle,
670        rules: [
671            {
672                chartOptions: {
673                    chart: {height: xlCapHeight(height_xs)},
674                    xAxis: {minorTickInterval: null},
675                    legend: {alignColumns: false}
676                },
677                condition: {maxWidth: 337}
678            },
679            {
680                chartOptions: {
681                    chart: {height: xlCapHeight(height_sm)},
682                    xAxis: {minorTickInterval: null},
683                    legend: {alignColumns: false}
684                },
685                condition: {minWidth: 338,maxWidth: 360}
686            },
687            {
688                chartOptions: {
689                    chart: {height: xlCapHeight(height_sm)},
690                    xAxis: {minorTickInterval: null},
691                    legend: {alignColumns: true}
692                },
693                condition: {minWidth: 360,maxWidth: 488}
694            },
695
696            {
697                chartOptions: {
698                    chart: {height: xlCapHeight(height_md)},
699                    xAxis: {minorTickInterval: 6*36e5},
700                    legend: {alignColumns: true}
701                },
702                condition: {minWidth: 489,maxWidth: 639}
703            },
704
705            {
706                chartOptions: {
707                    chart: {height: xlCapHeight(height_lg)}
708                },
709                condition: {minWidth: 640}
710            }
711
712        ]
713    };
714};
715
716/* Die Hoehen oben werden beim Aufbau des Diagramms berechnet. Dreht der Nutzer
717 * das Geraet, aendert sich die Viewporthoehe - Highcharts kennt dann aber nur
718 * noch die fertigen Pixelwerte. Deshalb werden die Regeln neu erzeugt, sobald
719 * sich die erlaubte Maximalhoehe tatsaechlich aendert. */
720var xlRefreshChartHeights = function () {
721    var next = xlLayoutKey();
722    if (next === xlHeightCapState) {
723        return; // Gleiche Lage - kein teures Neuzeichnen noetig.
724    }
725    if (typeof Highcharts === 'undefined' || !Highcharts.charts) {
726        return;
727    }
728    Highcharts.charts.forEach(function (chart) {
729        if (!chart) {
730            return; // Zerstoerte Diagramme bleiben als undefined im Array.
731        }
732        // Je nach Highcharts-Version liegt die Notiz in userOptions oder in
733        // den gemergten options - beide Wege pruefen.
734        var models;
735        if (chart.userOptions && chart.userOptions.responsive) {
736            models = chart.userOptions.responsive.xlModels;
737        }
738        if (typeof models === 'undefined' && chart.options && chart.options.responsive) {
739            models = chart.options.responsive.xlModels;
740        }
741        if (typeof models === 'undefined') {
742            return; // Kein XL-Diagramm.
743        }
744        chart.update({responsive: xlChartOptions(models)}, true, false, false);
745    });
746    xlHeightCapState = next;
747};
748
749if (typeof window !== 'undefined' && window.addEventListener) {
750    ['resize', 'orientationchange'].forEach(function (evt) {
751        window.addEventListener(evt, function () {
752            clearTimeout(xlHeightCapTimer);
753            xlHeightCapTimer = setTimeout(xlRefreshChartHeights, 200);
754        });
755    });
756}
757
758var xlLegendWithFlag = {
759    enabled: false,
760};
761
762var xlXAxisStandard = {
763    opposite:true,
764    type: 'datetime',
765    tickInterval: 24*36e5,
766    // Tagesgrenze: EINE dezente vertikale Linie - keine dominante dunkle Trennung.
767    gridLineWidth: 1,
768    lineWidth: 0,
769    lineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
770    gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
771    majorGridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
772    gridZIndex: 1,
773    // Stundenraster entfaellt bewusst: es war das dominanteste Grid-Element.
774    minorTickInterval: null,
775    minorGridLineWidth: 0,
776    dateTimeLabelFormats: {
777        hour: getDynHourDateFormat(),
778        day: getDynDayDateFormat()
779    },
780    labels: {
781            useHTML: true,
782            align: 'center',
783            formatter: function () {
784                    var date_format = getDynDayShortDateFormat(this.value, this.chart.plotWidth);
785                    return Highcharts.dateFormat(date_format, this.value);
786            },
787            style: {
788                color: cssVar('--hc-xl-label', '#79838D'),
789                fontSize: '12px'
790            }
791    },
792    tickLength: 0,
793    crosshair: false
794};
795
796var xlYAxisStandard = function (lab, zeroline, allowD, minorTI, emphStep) {
797    var plotL = null;
798    if (typeof allowD === 'undefined') { allowD=false; }
799    if (typeof minorTI === 'undefined') { minorTI=1; }
800    if (typeof zeroline !== 'undefined') {
801        plotL = [{
802            value: zeroline,
803            width: 1,
804            color: cssVar('--hc-xl-zeroline', '#C3CAD1'),
805            zIndex: 2
806        }];
807    }
808    if (emphStep) { xlEnsureGridEmphasis(); }
809    return {
810        title: {
811            text: false
812        },
813        labels: {
814            format: lab,
815            style: {
816                color: cssVar('--hc-xl-label', '#79838D'),
817                fontSize: '12px'
818            }
819        },
820        plotLines: plotL,
821        allowDecimals: allowD,
822        // Betonte Gitterlinien alle `emphStep` Einheiten (siehe
823        // xlApplyGridEmphasis) - ohne Wert bleibt das Raster gleichmaessig.
824        xlEmphasizeStep: emphStep || null,
825        // Nur noch Hauptlinien - Zwischenlinien waren reines Rauschen.
826        minorTickInterval: null,
827        minorGridLineWidth: 0,
828        gridLineWidth: 1,
829        gridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
830        majorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
831        lineWidth: 0,
832        tickPixelInterval: 42,
833        // Damit die Kurven nicht am Panelrand kleben.
834        minPadding: 0.08,
835        maxPadding: 0.08
836    };
837};
838/**
839 * Temperaturachse: wie die Standardachse, zusaetzlich werden die 10er-Linien
840 * (-10, 0, 10, 20 ...) kraeftiger gezeichnet. Betont wird immer der
841 * angezeigte Wert, in °F also 0/10/20 °F usw.
842 */
843var XL_TEMP_GRID_STEP = 10;
844var xlYAxisTemp = function (lab, zeroline) {
845    return xlYAxisStandard(lab, zeroline, false, 1, XL_TEMP_GRID_STEP);
846};
847
848var xlYAxisStandardFormatter = function (lab, zeroline, allowD, minorTI) {
849    var plotL = null;
850    if (typeof allowD === 'undefined') { allowD=false; }
851    if (typeof minorTI === 'undefined') { minorTI=1; }
852    if (typeof zeroline !== 'undefined') {
853        plotL = [{
854            value: zeroline,
855            width: 1,
856            color: cssVar('--hc-xl-zeroline', '#C3CAD1'),
857            zIndex: 2
858        }];
859    }
860    return {
861        title: {
862            text: false
863        },
864        labels: {
865            formatter: lab,
866            style: {
867                color: cssVar('--hc-xl-label', '#79838D'),
868                fontSize: '12px'
869            }
870        },
871        plotLines: plotL,
872        allowDecimals: allowD,
873        minorTickInterval: null,
874        minorGridLineWidth: 0,
875        gridLineWidth: 1,
876        gridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
877        majorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
878        lineWidth: 0,
879        tickPixelInterval: 42,
880        minPadding: 0.08,
881        maxPadding: 0.08
882    };
883};
884
885/* ---------------------------------------------------------------------------
886 *  Betonte Gitterlinien (10er-Schritte)
887 * ---------------------------------------------------------------------------
888 *  In den Temperatur-Charts sollen die "runden" Linien (-10, 0, 10, 20 ...)
889 *  kraeftiger sein als das uebrige Raster - sie dienen als Orientierungsanker.
890 *
891 *  Highcharts kann die Strichstaerke nicht je Tick konfigurieren, deshalb
892 *  werden die bereits gezeichneten Gitterlinien im `render`-Event nachtraeglich
893 *  ueberschrieben. Das ist bewusst KEIN Satz zusaetzlicher plotLines:
894 *  plotLines lassen sich nicht automatisch an die jeweils sichtbare Skala
895 *  anpassen und wuerden bei jedem Redraw neu erzeugt werden muessen.
896 *
897 *  Aktiviert wird das ueber die Achsenoption `xlEmphasizeStep` (siehe
898 *  `xlYAxisStandard`). Die Betonung bezieht sich immer auf die ANGEZEIGTEN
899 *  Werte, funktioniert also in °C, °F und K gleichermassen.
900 * ------------------------------------------------------------------------- */
901var XL_GRID_EMPHASIS_WIDTH = 2;
902var xlGridEmphasisBound = false;
903
904var xlApplyGridEmphasis = function (axis) {
905    var step = axis && axis.options && axis.options.xlEmphasizeStep;
906    if (!step || !axis.ticks) { return; }
907
908    // Fallback bewusst modusabhaengig: solange `--hc-xl-grid-strong` noch
909    // nicht im kompilierten CSS steht, passt die Farbe trotzdem zum Theme.
910    var strongColor = cssVar('--hc-xl-grid-strong', xlIsDark() ? '#363B41' : '#DCE2E8');
911    var normalColor = cssVar('--hc-xl-grid', '#EEF1F4');
912
913    Object.keys(axis.ticks).forEach(function (key) {
914        var tick = axis.ticks[key];
915        if (!tick || !tick.gridLine) { return; }
916
917        var value = parseFloat(key);
918        // Rundung gegen Fliesskomma-Reste (z.B. 10.000000000000002)
919        var strong = isFinite(value) && Math.abs(Math.round(value / step) * step - value) < 1e-6;
920
921        tick.gridLine.attr({
922            'stroke-width': strong ? XL_GRID_EMPHASIS_WIDTH : 1,
923            stroke: strong ? strongColor : normalColor
924        });
925    });
926};
927
928/**
929 * Registriert den globalen `render`-Hook genau einmal. Achsen ohne
930 * `xlEmphasizeStep` werden dabei nicht angefasst.
931 */
932var xlEnsureGridEmphasis = function () {
933    if (xlGridEmphasisBound || typeof Highcharts === 'undefined') { return; }
934    xlGridEmphasisBound = true;
935    Highcharts.addEvent(Highcharts.Chart, 'render', function () {
936        (this.yAxis || []).forEach(xlApplyGridEmphasis);
937    });
938};
939
940var xlPlotOptions = function(ContainerId) {
941    return {
942        series: {
943            events: {
944                legendItemClick: function() {
945                    chartContainerId = $('#'+ContainerId).children().attr('id');
946                    $( '#'+chartContainerId+'.toggle-flags' ).tooltip('destroy');
947                    $( '#'+chartContainerId+'.toggle-flags' ).tooltip({
948                        content: function() {
949                            return "<img src='"+$(this).data('flagfile')+"' /><br /><span style='display: inline-block; color:#555; font-size: 13px; font-weight: bold; margin-top: 7px;'>"+$(this).data('longname')+"</span><br /><span style='color: #555; font-size:11px;'>"+$(this).data('run')+"</span>";
950                        }
951                    });
952                },
953            },
954        },
955        column: {
956            borderColor: cssVar('--hc-bar-stroke-color'),
957        }
958    };
959};
960
961/* ============================================================================
962 *  XL-Multimodell: visuelle Hierarchie (Median / Unsicherheitsband / Modelle)
963 * ============================================================================
964 *  HAUPTINFORMATION  -> Median
965 *  KONTEXT           -> Unsicherheitsband (10.-90. Perzentil)
966 *  DETAILINFORMATION -> die einzelnen Modelllaeufe
967 *
968 *  Die Aggregate werden AUSSCHLIESSLICH aus den bereits vorhandenen
969 *  Modellserien berechnet - keine zusaetzlichen Requests, keine Aenderung an
970 *  den Originaldaten. Die Aggregatserien tragen bewusst KEIN `param`, damit
971 *  die Modellauswahl-Legende (xlSelection) sie niemals anfasst; erkannt
972 *  werden sie ueber `xlRole`.
973 * ------------------------------------------------------------------------- */
974
975/** Ab dieser Anzahl sichtbarer Modelle sind Median/Band statistisch sinnvoll. */
976var XL_MIN_MODELS_FOR_STATS = 3;
977
978/**
979 * Unsicherheitsband (10.-90. Perzentil) global ein-/ausschalten.
980 * TEMPORAER auf false - auf false bleibt die gesamte Band-Logik erhalten,
981 * es wird lediglich keine Flaeche erzeugt. Zum Reaktivieren: true.
982 */
983var XL_SHOW_BAND = false;
984
985/**
986 * Zeitschritt-Punkte auf den Modelllinien.
987 * ------------------------------------------------------------------------
988 * Die Modelle liefern unterschiedlich feine Zeitschritte (1h/3h/6h). Ein
989 * kleiner Punkt je Stuetzstelle macht das direkt im Chart sichtbar.
990 *
991 *   'auto'   Highcharts blendet die Punkte selbst aus, sobald sie zu dicht
992 *            stehen (< XL_STEP_MARKER_RADIUS * enabledThreshold Pixel).
993 *            Folge: grobe Modelle zeigen Punkte, 1h-Modelle bleiben glatt -
994 *            und beim Zoomen tauchen sie dort ebenfalls auf.
995 *   'always' Punkte immer zeichnen (kann bei 1h-Schritten dicht wirken).
996 *   'off'    Bisheriges Verhalten ohne Punkte.
997 */
998var XL_STEP_MARKER_MODE = 'off';
999var XL_STEP_MARKER_RADIUS = 2.2;
1000/** Mindestabstand zweier Punkte in Vielfachen des Radius (nur bei 'auto'). */
1001var XL_STEP_MARKER_THRESHOLD = 2.5;
1002
1003var xlColor = function (name, fallback) {
1004    var v = cssVar(name);
1005    return (v && v.length) ? v : fallback;
1006};
1007
1008/**
1009 * Darkmode-Erkennung fuer die Chartfarben.
1010 *
1011 * Gleiche Quelle wie `cssVar` (body.dark), damit Serienfarben und
1012 * CSS-Variablen nie auseinanderlaufen. Der Wert wird bewusst bei jedem
1013 * Aufruf frisch gelesen statt gecacht - beim Umschalten laedt die Seite
1014 * zwar neu (siehe applyMode in function.js), aber so bleibt die Funktion
1015 * auch ohne Reload korrekt.
1016 */
1017var xlIsDark = function () {
1018    return !!(document.body && document.body.classList.contains('dark'));
1019};
1020
1021/**
1022 * Farbe mit Alpha versehen.
1023 * Highcharts ignoriert `fillOpacity`, sobald ein explizites `fillColor`
1024 * gesetzt ist - die Transparenz muss deshalb in der Farbe selbst stecken.
1025 */
1026var xlAlpha = function (color, alpha) {
1027    if (typeof Highcharts !== 'undefined' && Highcharts.color) {
1028        var rgba = Highcharts.color(color).setOpacity(alpha).get('rgba');
1029        if (rgba && rgba.indexOf('rgba') === 0) { return rgba; }
1030    }
1031    var m = /^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(String(color).trim());
1032    if (m) {
1033        return 'rgba(' + parseInt(m[1], 16) + ',' + parseInt(m[2], 16) + ',' +
1034               parseInt(m[3], 16) + ',' + alpha + ')';
1035    }
1036    return color;
1037};
1038
1039/** Beschriftungen der Aggregatebenen (Server liefert sie via xlLegendI18n). */
1040var xlStatsFallback = {
1041    median: 'Median',
1042    band: '10–90 % Perzentil',
1043    bandhint: 'Unsicherheitsbereich',
1044    models: 'Einzelne Modelle',
1045    range: 'Spannweite',
1046    count: 'Modelle'
1047};
1048
1049var xlStatsT = function (key) {
1050    var i18n = (typeof xlLegendI18n !== 'undefined' && xlLegendI18n) ? xlLegendI18n : {};
1051    var stats = i18n.stats || {};
1052    return stats[key] || xlStatsFallback[key] || key;
1053};
1054
1055/** Quantil mit linearer Interpolation auf einem aufsteigend sortierten Array. */
1056var xlQuantile = function (sorted, q) {
1057    var n = sorted.length;
1058    if (!n) { return null; }
1059    if (n === 1) { return sorted[0]; }
1060    var pos = (n - 1) * q;
1061    var lo = Math.floor(pos);
1062    var hi = Math.ceil(pos);
1063    if (lo === hi) { return sorted[lo]; }
1064    return sorted[lo] + (sorted[hi] - sorted[lo]) * (pos - lo);
1065};
1066
1067/** Rohpunkte einer Serie/eines Serien-Optionsobjekts ([[x,y], ...]). */
1068var xlRawPoints = function (s) {
1069    var o = (s && (s.userOptions || s.options || s)) || {};
1070    return Array.isArray(o.data) ? o.data : [];
1071};
1072
1073var xlSeriesRole = function (s) {
1074    var o = (s && (s.userOptions || s.options || s)) || {};
1075    return o.xlRole || null;
1076};
1077
1078/**
1079 * Median + Perzentilband ueber eine Liste von Modellserien.
1080 * Nur Zeitpunkte mit mindestens XL_MIN_MODELS_FOR_STATS Werten werden
1081 * beruecksichtigt - dadurch laufen die Aggregate am Rand nicht ins Leere und
1082 * es entstehen keine Linien ueber den letzten belastbaren Datenpunkt hinaus.
1083 */
1084var xlComputeAggregates = function (modelSeries, monotone) {
1085    var buckets = {};
1086    var haveAny = false;
1087
1088    (modelSeries || []).forEach(function (s) {
1089        xlRawPoints(s).forEach(function (p) {
1090            if (!p) { return; }
1091            var x = Array.isArray(p) ? p[0] : p.x;
1092            var y = Array.isArray(p) ? p[1] : p.y;
1093            if (x === null || x === undefined) { return; }
1094            if (y === null || y === undefined || typeof y !== 'number' || !isFinite(y)) { return; }
1095            if (!buckets[x]) { buckets[x] = []; }
1096            buckets[x].push(y);
1097            haveAny = true;
1098        });
1099    });
1100
1101    if (!haveAny) { return { median: [], band: [], count: 0 }; }
1102
1103    var xs = Object.keys(buckets).map(Number).sort(function (a, b) { return a - b; });
1104    var median = [];
1105    var band = [];
1106    var maxCount = 0;
1107
1108    xs.forEach(function (x) {
1109        var vals = buckets[x];
1110        if (vals.length > maxCount) { maxCount = vals.length; }
1111        if (vals.length < XL_MIN_MODELS_FOR_STATS) { return; }
1112        vals.sort(function (a, b) { return a - b; });
1113        median.push([x, xlQuantile(vals, 0.5)]);
1114        band.push([x, xlQuantile(vals, 0.1), xlQuantile(vals, 0.9)]);
1115    });
1116
1117    // Bei kumulativen Groessen (Niederschlagssumme) kann der punktweise Median
1118    // zurueckspringen, sobald ein Modell endet und sich die beitragende
1119    // Modellmenge aendert. Das ist ein Artefakt der Aggregation, nicht der
1120    // Daten - die abgeleitete Linie wird deshalb monoton gehalten.
1121    if (monotone) {
1122        var runMed = -Infinity;
1123        median.forEach(function (p) {
1124            if (p[1] < runMed) { p[1] = runMed; } else { runMed = p[1]; }
1125        });
1126        var runLo = -Infinity, runHi = -Infinity;
1127        band.forEach(function (p) {
1128            if (p[1] < runLo) { p[1] = runLo; } else { runLo = p[1]; }
1129            if (p[2] < runHi) { p[2] = runHi; } else { runHi = p[2]; }
1130        });
1131    }
1132
1133    return { median: median, band: band, count: maxCount };
1134};
1135
1136/**
1137 * Baut die Serienliste eines XL-Charts um: Modelle optisch zuruecknehmen und
1138 * Band + Median als zusaetzliche Ebenen davorlegen.
1139 *
1140 * Die uebergebenen Objekte werden NICHT mutiert - die Originalserien aus dem
1141 * PHP-Template bleiben unveraendert erhalten.
1142 *
1143 * opts:
1144 *   smooth      Spline statt Polyline (NICHT fuer kumulative Groessen!)
1145 *   stats       Median/Band erzeugen (default true)
1146 *   band        Unsicherheitsband erzeugen (default = stats)
1147 *   column      Saeulendarstellung (Niederschlag)
1148 *   monotone    Aggregate monoton steigend halten (kumulative Groessen)
1149 *   medianColor Farbe der zentralen Linie/Saeule
1150 *   bandColor   Farbe der Unsicherheitsflaeche (default: --hc-xl-band)
1151 */
1152/**
1153 * Markerdefinition fuer eine Modelllinie: kleiner Punkt je Zeitschritt.
1154 * Bei 'auto' bleibt `enabled` bewusst UNGESETZT - nur dann wertet Highcharts
1155 * `enabledThreshold` aus und blendet zu dicht stehende Punkte selbst aus.
1156 */
1157var xlStepMarker = function (base, color) {
1158    var m = $.extend({}, base, {
1159        symbol: 'circle',
1160        radius: XL_STEP_MARKER_RADIUS,
1161        lineWidth: 0,
1162        fillColor: color,
1163        states: { hover: { enabled: true, radius: XL_STEP_MARKER_RADIUS + 1.8, lineWidth: 0 } }
1164    });
1165
1166    if (XL_STEP_MARKER_MODE === 'always') {
1167        m.enabled = true;
1168    } else if (XL_STEP_MARKER_MODE === 'auto') {
1169        delete m.enabled;
1170        m.enabledThreshold = XL_STEP_MARKER_THRESHOLD;
1171    } else {
1172        m.enabled = false;
1173    }
1174
1175    return m;
1176};
1177
1178var xlSeries = function (raw, opts) {
1179    if (!Array.isArray(raw)) { return raw; }
1180    opts = opts || {};
1181
1182    var wantStats = opts.stats !== false;
1183    var wantBand = XL_SHOW_BAND &&
1184                   ((opts.band !== undefined) ? opts.band : (wantStats && !opts.column));
1185    var medianColor = opts.medianColor || xlColor('--hc-xl-median', '#1a3852');
1186    var bandColor = opts.bandColor || xlColor('--hc-xl-band', '#007dfe');
1187    var lineType = opts.column ? 'column' : (opts.smooth ? 'spline' : 'line');
1188
1189    var models = raw.map(function (s) {
1190        // Bewusst FLACHE Kopie: `data` wird nie mutiert und muss deshalb nicht
1191        // geklont werden (bei ~15 Serien x ~200 Punkten waere das teuer).
1192        var copy = $.extend({}, s);
1193        copy.type = copy.type || lineType;
1194        // Darkmode: aufgehellte Variante derselben Modellfarbe. Die Rampen
1195        // sind serverseitig in `model_color_dark` hinterlegt, damit die
1196        // Abstufung innerhalb einer Gruppe erhalten bleibt.
1197        if (xlIsDark() && copy.colorDark) { copy.color = copy.colorDark; }
1198        if (opts.column) {
1199            copy.borderWidth = 0;
1200            copy.pointPadding = 0.02;
1201            copy.groupPadding = 0.12;
1202            // Balken in voller Farbe: anders als bei den Linien-Charts gibt es
1203            // hier keine Medianebene, die sich davor schieben muesste.
1204            // Ohne das rendert Highcharts fuer jeden 0-Wert einen sichtbaren
1205            // 1px-Strich - bei Niederschlag waere das ein Meer aus Mini-Balken.
1206            copy.minPointLength = 0;
1207        } else {
1208            // Deutlich schwaecher als die Medianlinie (3px, volle Deckung),
1209            // aber kraeftig genug, um einzelne Modelle nachverfolgen zu koennen.
1210            copy.lineWidth = 2;
1211            copy.opacity = 0.65;
1212        }
1213        // Saeulen (Niederschlag) zeigen ihre Zeitschritte schon durch die
1214        // Balkenbreite - dort bleiben die Marker aus.
1215        copy.marker = opts.column
1216            ? $.extend({}, s.marker, { enabled: false, symbol: 'circle' })
1217            : xlStepMarker(s.marker, copy.color);
1218        copy.states = $.extend(true, {}, s.states, {
1219            hover: { lineWidthPlus: 1, halo: false },
1220            inactive: { opacity: 0.12 }
1221        });
1222        copy.zIndex = (typeof copy.zIndex === 'number') ? copy.zIndex : 3;
1223        return copy;
1224    });
1225
1226    if (!wantStats) { return models; }
1227
1228    // Initialer Aufbau: nur die serverseitig aktiven Modelle zaehlen.
1229    var active = models.filter(function (s) { return s.visible !== false; });
1230    var agg = xlComputeAggregates(active, opts.monotone);
1231    var out = [];
1232
1233    if (wantBand && agg.band.length) {
1234        out.push({
1235            xlRole: 'band',
1236            xlMonotone: !!opts.monotone,
1237            type: 'arearange',
1238            name: xlStatsT('band'),
1239            data: agg.band,
1240            color: xlAlpha(bandColor, 0.3),
1241            // Alpha steckt bewusst in der Farbe selbst - `fillOpacity` wird
1242            // von Highcharts ignoriert, sobald `fillColor` gesetzt ist.
1243            fillColor: xlAlpha(bandColor, 0.3),
1244            lineWidth: 0,
1245            zIndex: 20,
1246            marker: { enabled: false },
1247            enableMouseTracking: false,
1248            states: { inactive: { opacity: 1 }, hover: { enabled: false } },
1249            showInLegend: false
1250        });
1251    }
1252
1253    if (agg.median.length) {
1254        out.push({
1255            xlRole: 'median',
1256            xlMonotone: !!opts.monotone,
1257            type: opts.column ? 'column' : (opts.smooth ? 'spline' : 'line'),
1258            name: xlStatsT('median'),
1259            data: agg.median,
1260            color: medianColor,
1261            lineWidth: opts.column ? undefined : 3,
1262            zIndex: 60,
1263            grouping: opts.column ? false : undefined,
1264            pointPadding: opts.column ? 0.36 : undefined,
1265            borderWidth: opts.column ? 0 : undefined,
1266            marker: { enabled: false, symbol: 'circle', states: { hover: { enabled: true, radius: 4 } } },
1267            states: { inactive: { opacity: 1 }, hover: { lineWidthPlus: 0, halo: false } },
1268            showInLegend: false
1269        });
1270    }
1271
1272    return out.concat(models);
1273};
1274
1275/**
1276 * Ensemble-Charts auf die XL-Linienoptik bringen.
1277 * ------------------------------------------------------------------------
1278 * Uebernimmt aus `xlSeries` genau die Linienaesthetik - NICHT die Aggregate:
1279 * Ensembles bringen Main/Mean/Range/Perzentile bereits serverseitig mit.
1280 *
1281 *   - Marker konsequent aus (bei 50 Membern sonst ein Punktteppich)
1282 *   - Hover verbreitert um 1px, ohne Halo
1283 *   - nicht gehoverte Member werden abgedunkelt (wie in XL)
1284 *   - Member leicht transparent, damit die Buendelung lesbar bleibt
1285 *   - Leitlinien (Main/Mean) in voller Deckung und kraeftiger
1286 *
1287 * Daten, Farben, Reihenfolge, zIndex und Serien-Namen bleiben unangetastet -
1288 * der Tooltip erkennt die Leitserien weiterhin ueber `name`.
1289 */
1290var XL_ENS_LEAD_SERIES = ['Main', 'Mean'];
1291
1292var xlEnsembleSeries = function (raw) {
1293    if (!Array.isArray(raw)) { return raw; }
1294
1295    return raw.map(function (s) {
1296        // Flache Kopie: `data` wird nie mutiert.
1297        var copy = $.extend({}, s);
1298
1299        // Flaechen (Range/Perzentile) sind Kontext, keine Linien - die
1300        // bekommen nur das Dimmen abgewoehnt, damit sie beim Hover stehen
1301        // bleiben.
1302        if (copy.type === 'arearange' || copy.type === 'areasplinerange') {
1303            copy.states = $.extend(true, {}, s.states, {
1304                inactive: { opacity: 1 },
1305                hover: { enabled: false }
1306            });
1307            return copy;
1308        }
1309
1310        var lead = XL_ENS_LEAD_SERIES.indexOf(copy.name) !== -1;
1311
1312        copy.marker = $.extend({}, s.marker, { enabled: false });
1313        // Bewusst KEIN Wechsel auf 'spline': die Ensemble-Member sollen genau
1314        // die gelieferten Stuetzstellen zeigen, nicht eine interpolierte Kurve.
1315        copy.lineWidth = lead ? 3 : 1.5;
1316        copy.opacity = lead ? 1 : 0.6;
1317        copy.states = $.extend(true, {}, s.states, {
1318            hover: { lineWidthPlus: 1, halo: false },
1319            inactive: { opacity: lead ? 1 : 0.12 }
1320        });
1321
1322        return copy;
1323    });
1324};
1325
1326/**
1327 * Zieht Median/Band eines bestehenden Charts auf die aktuell SICHTBAREN
1328 * Modelle nach (nach einem Klick in der Modellauswahl).
1329 * Gibt true zurueck, wenn sich tatsaechlich etwas geaendert hat.
1330 */
1331var xlRefreshAggregates = function (chart) {
1332    if (!chart || !chart.series) { return false; }
1333
1334    var aggregates = chart.series.filter(function (s) { return xlSeriesRole(s); });
1335    if (!aggregates.length) { return false; }
1336
1337    var visibleModels = chart.series.filter(function (s) {
1338        return xlSeriesParam(s) && s.visible;
1339    });
1340
1341    // Neuberechnung nur, wenn sich die Menge der sichtbaren Modelle geaen
1341dert
1342    // hat - sonst wuerde jeder Tabwechsel ein volles Redraw ausloesen.
1343    var key = visibleModels.map(xlSeriesParam).sort().join('|');
1344    if (chart.xlAggKey === key) { return false; }
1345    chart.xlAggKey = key;
1346
1347    var enough = visibleModels.length >= XL_MIN_MODELS_FOR_STATS;
1348    var monotone = aggregates.some(function (s) { return s.options.xlMonotone; });
1349    var agg = enough ? xlComputeAggregates(visibleModels, monotone) : { median: [], band: [], count: 0 };
1350
1351    aggregates.forEach(function (s) {
1352        var role = xlSeriesRole(s);
1353        var next = (role === 'band') ? agg.band : agg.median;
1354        // redraw=false - der Aufrufer redrawt gesammelt.
1355        s.setData(next, false, false, false);
1356        if (s.visible !== (next.length > 0)) {
1357            s.setVisible(next.length > 0, false);
1358        }
1359    });
1360
1361    return true;
1362};
1363
1364/**
1365 * Gemeinsamer XL-Tooltip: zuerst die zentrale Medianinformation, darunter die
1366 * Modellwerte. Dadurch traegt der Tooltip die Detailinformation, die in der
1367 * Grafik bewusst zurueckgenommen ist.
1368 *
1369 * opts.rangeHours  Zeitraum-Kopf ("Von ... bis ...") statt einzelnem Zeitpunkt
1370 */
1371/**
1372 * Ab wie vielen Modellen die Tooltip-Liste zweispaltig wird. Bei rund 24
1373 * sichtbaren Modellen waere eine einspaltige Liste hoeher als der Chart.
1374 */
1375var XL_TT_COLUMN_THRESHOLD = 10;
1376
1377/** Rand, den der Tooltip im sichtbaren Ausschnitt frei laesst (Rahmen/Padding). */
1378var XL_TT_WIDTH_RESERVE = 24;
1379
1380/** Unterhalb dieser sichtbaren Breite wird die Modelltabelle kleiner gesetzt. */
1381var XL_TT_NARROW_WIDTH = 360;
1382
1383/** Untergrenze, damit der Tooltip nie absurd schmal berechnet wird. */
1384var XL_TT_MIN_WIDTH = 200;
1385
1386/**
1387 * Zweispaltige Tooltips gibt es nur auf schmalen Geraeten. Auf dem Desktop
1388 * ist genug Hoehe vorhanden, dort bleibt die Liste immer einspaltig.
1389 */
1390var xlTooltipColumns = function (count) {
1391    if (count <= XL_TT_COLUMN_THRESHOLD) { return 1; }
1392    if (typeof window === 'undefined') { return 1; }
1393    return (window.innerWidth || 0) <= XL_MOBILE_MAX_WIDTH ? 2 : 1;
1394};
1395
1396/**
1397 * Bricht eine per <br> aufgebaute Modellliste auf schmalen Geraeten in zwei
1398 * Spalten, sobald sie zu viele Zeilen hat. Die Tooltips werden bei 24
1399 * sichtbaren Modellen sonst hoeher als der Chart. Auf dem Desktop ist genug
1400 * Hoehe vorhanden, dort bleibt die Liste unveraendert einspaltig.
1401 *
1402 * Inhalt, Reihenfolge und Werte bleiben unveraendert - es wird ausschliesslich
1403 * umgebrochen. Gefuellt wird spaltenweise, damit die Liste weiter von oben
1404 * nach unten gelesen werden kann. Die Breite wird auf den sichtbaren
1405 * Ausschnitt begrenzt, damit nichts hinter der Achsenmaske verschwindet.
1406 *
1407 * @param html    Der vom Formatter gebaute Inhalt (Kopfzeile, dann <br>-Liste)
1408 * @param ctx     Der Formatter-Kontext (`this`), fuer die Chartbreite
1409 * @param reserve Zusaetzlich freizuhaltende Breite, z.B. fuer das Wettersymbol
1410 */
1411var ttCols = function (html, ctx, reserve) {
1412    var parts = String(html).split(/<br\s*\/?>/i);
1413    if (xlTooltipColumns(parts.length - 1) < 2) { return html; }
1414
1415    var head = parts.shift();
1416    var n = parts.length;
1417    var perCol = Math.ceil(n / 2);
1418
1419    var availW = 0;
1420    var chart = (ctx && ctx.points && ctx.points.length) ? ctx.points[0].series.chart : null;
1421    if (chart) {
1422        availW = Math.max(XL_TT_MIN_WIDTH,
1423                          chart.chartWidth - chart.plotLeft - XL_TT_WIDTH_RESERVE - (reserve || 0));
1424    }
1425
1426    // `width: max-content` verhindert, dass der Browser den Tooltip auf die
1427    // schmalste moegliche Breite zusammenzieht und jede Zeile umbricht.
1428    var style = availW ? ';width:max-content;max-width:' + Math.round(availW) + 'px' : '';
1429    // Die Spaltendarstellung wird zusaetzlich inline gesetzt, damit sie auch
1430    // ohne frisch ausgeliefertes CSS greift.
1431    var out = head + '<div class="tt-cols" style="display:flex;gap:14px;white-space:normal' + style + '">';
1432    for (var c = 0; c < 2; c++) {
1433        out += '<div class="tt-col" style="flex:1 1 0;min-width:0">';
1434        for (var i = c * perCol; i < Math.min(n, (c + 1) * perCol); i++) {
1435            out += '<div class="tt-row" style="white-space:nowrap;overflow:hidden;text-overflow:ellipsis">' +
1436                   parts[i] + '</div>';
1437        }
1438        out += '</div>';
1439    }
1440    return out + '</div>';
1441};
1442
1443var xlTooltip = function (unit, digits, opts) {
1444    opts = opts || {};
1445    if (typeof digits !== 'number') { digits = 1; }
1446
1447    return {
1448        xlDigits: digits,
1449        crosshairs: {
1450            width: 1,
1451            color: xlColor('--hc-xl-crosshair', 'rgba(120,130,140,.35)'),
1452            zIndex: 2
1453        },
1454        shared: true,
1455        valueSuffix: ' ' + unit,
1456        shape: 'square',
1457        useHTML: true,
1458        // Der Tooltip bleibt IM Chart (`outside: false`). Ein Versuch mit
1459        // `outside: true` positionierte in dieser Highcharts-Version
1460        // unzuverlaessig - der Tooltip landete weit ausserhalb des Charts.
1461        // Das Hoehenproblem wird stattdessen an der Wurzel geloest: ab
1462        // XL_TT_COLUMN_THRESHOLD Modellen wird die Liste zweispaltig, der
1463        // Tooltip also nur noch halb so hoch.
1464        outside: false,
1465        backgroundColor: xlColor('--hc-xl-tooltip-bg', 'rgba(255,255,255,.97)'),
1466        borderColor: xlColor('--hc-xl-tooltip-border', '#d8dee4'),
1467        borderRadius: 6,
1468        borderWidth: 1,
1469        shadow: false,
1470        style: {
1471            zIndex: 10000,
1472            pointerEvents: 'auto',
1473            color: cssVar('--color-text')
1474        },
1475        positioner: tooltipPositioner,
1476        formatter: function () {
1477            var fmt = function (v) {
1478                return Highcharts.numberFormat(v, digits);
1479            };
1480
1481            var head;
1482            if (opts.rangeHours) {
1483                var ms = opts.rangeHours * 3600 * 1000;
1484                head = hccompact_units['from'] + ' ' +
1485                    Highcharts.dateFormat(getDynDateFormat(this.x - ms), this.x - ms) + '<br />' +
1486                    hccompact_units['until'] + ' ' +
1487                    Highcharts.dateFormat(getDynDateFormat(this.x), this.x);
1488            } else {
1489                head = Highcharts.dateFormat(getDynDateFormat(this.x), this.x);
1490            }
1491
1492            var chart = (this.points && this.points.length) ? this.points[0].series.chart : null;
1493
1494            // Sichtbare Breite ab der Achse: der Tooltip steht linksbuendig an
1495            // `plotLeft`, `chartWidth` ist die Breite des Sichtfensters (bei
1496            // scrollbarer Zeichenflaeche ist das SVG breiter). Mehr Platz hat
1497            // er nicht, sonst verschwinden die rechten Spalten hinter der
1498            // Maske der fixierten Achse.
1499            var availW = 0;
1500            if (chart) {
1501                availW = Math.max(XL_TT_MIN_WIDTH,
1502                                  chart.chartWidth - chart.plotLeft - XL_TT_WIDTH_RESERVE);
1503            }
1504
1505            // `width: max-content` ist hier entscheidend: ohne feste Breite
1506            // wuerde der Browser den Tooltip auf die schmalste moegliche
1507            // Breite zusammenziehen und jede Zeile umbrechen. So bleibt er so
1508            // breit wie noetig - und hoechstens so breit wie erlaubt.
1509            var s = '<div class="xl-tt"' +
1510                    (availW ? ' style="width:max-content;max-width:' + Math.round(availW) + 'px"' : '') +
1511                    '><div class="xl-tt-head">' + head + '</div>';
1512
1513            var median = null;
1514            var band = null;
1515            var models = [];
1516            this.points.forEach(function (p) {
1517                var role = xlSeriesRole(p.series);
1518                if (role === 'median') { median = p; }
1519                else if (role === 'band') { band = p; }
1520                else { models.push(p); }
1521            });
1522
1523            if (median) {
1524                s += '<div class="xl-tt-median">' +
1525                     '<span class="xl-tt-median-label">' + xlStatsT('median') + '</span>' +
1526                     '<span class="xl-tt-median-value">' + fmt(median.y) + ' ' + unit + '</span>' +
1527                     '</div>';
1528            }
1529            if (band && band.point && band.point.low !== undefined) {
1530                s += '<div class="xl-tt-band">' + xlStatsT('band') + ': ' +
1531                     fmt(band.point.low) + '–' + fmt(band.point.high) + ' ' + unit + '</div>';
1532            }
1533
1534            if (models.length) {
1535                models.sort(ordertooltip);
1536
1537                // Auf schmalen Geraeten ab vielen Modellen zweispaltig: sonst
1538                // wird der Tooltip hoeher als der Chart und wird unten
1539                // abgeschnitten (die Zeichenflaeche der XL-Charts ist
1540                // horizontal scrollbar, ihr Container kann `overflow-y` nicht
1541                // freigeben). Auf dem Desktop bleibt es einspaltig.
1542                // Gefuellt wird SPALTENWEISE, damit die Sortierung nach
1543                // Werten von oben nach unten lesbar bleibt.
1544                var cols = xlTooltipColumns(models.length);
1545                var rows = Math.ceil(models.length / cols);
1546
1547                // Mehrspaltig ist der Platz knapp: die Einheit steht bereits
1548                // am Medianwert, in den Zellen wird sie weggelassen. Auf
1549                // schmalen Geraeten zusaetzlich eine Stufe kleinere Schrift.
1550                var cellUnit = cols > 1 ? '' : ' ' + unit;
1551                // Die Breitenbegrenzung ist entscheidend dafuer, dass nichts
1552                // hinter der Achsenmaske verschwindet - deshalb zusaetzlich
1553                // inline, damit sie auch ohne frisch kompiliertes CSS greift.
1554                var tblStyle = '';
1555                var nameStyle = '';
1556                if (cols > 1) {
1557                    tblStyle = 'table-layout:fixed;width:100%;';
1558                    if (availW > 0 && availW < XL_TT_NARROW_WIDTH) {
1559                        tblStyle += 'font-size:10px;';
1560                    }
1561                    nameStyle = ' style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap"';
1562                }
1563                tblStyle = tblStyle ? ' style="' + tblStyle + '"' : '';
1564
1565                s += '<table class="xl-tt-table' + (cols > 1 ? ' xl-tt-multicol' : '') +
1566                     '"' + tblStyle + ' border="0" cellspacing="1">';
1567                for (var r = 0; r < rows; r++) {
1568                    s += '<tr>';
1569                    for (var c = 0; c < cols; c++) {
1570                        var p = models[r + c * rows];
1571                        if (!p) {
1572                            s += '<td class="xl-tt-name"></td><td class="xl-tt-val"></td>';
1573                            continue;
1574                        }
1575                        s += '<td class="xl-tt-name"' + nameStyle + '><span class="hc-legend-color" style="color:' +
1576                             p.series.color + '">●</span> ' + p.series.name + '</td>' +
1577                             '<td class="xl-tt-val"><b>' + fmt(p.y) + '</b>' + cellUnit + '</td>';
1578                    }
1579                    s += '</tr>';
1580                }
1581                s += '</table>';
1582            }
1583
1584            return s + '</div>';
1585        }
1586    };
1587};
1588
1589/**
1590 * Y-Achse fuer Niederschlag/Niederschlagssumme.
1591 *
1592 * Der bisherige feste softMax von 10 mm liess typische Ereignisse im unteren
1593 * Zehntel der Flaeche verschwinden. Stattdessen ein kleiner, sinnvoller
1594 * Mindestbereich: geringe Mengen fuellen den Plot, groessere Mengen skalieren
1595 * automatisch hoch. `tickAmount` sorgt fuer gerundete Schritte (0/2/4/6/8 mm).
1596 */
1597var xlRainYAxis = function () {
1598    var mm = hccompact_units['rain'] == 'mm';
1599    return {
1600        title: { text: false },
1601        floor: 0,
1602        min: 0,
1603        softMax: mm ? 2 : 0.2,
1604        allowDecimals: true,
1605        labels: {
1606            format: '{value} ' + hccompact_units['rain'],
1607            style: {
1608                color: cssVar('--hc-xl-label', '#79838D'),
1609                fontSize: '12px'
1610            }
1611        },
1612        minorTickInterval: null,
1613        minorGridLineWidth: 0,
1614        gridLineWidth: 1,
1615        gridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
1616        majorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
1617        lineWidth: 0,
1618        tickAmount: 5,
1619        maxPadding: 0.08
1620    };
1621};
1622
1623var getVHStationUnitSoftMax = function() {
1624    if ($('#btn-vhs-unit-ms').hasClass('btn-active')) {
1625        return 20;
1626    }
1627    else if ($('#btn-vhs-unit-kmh').hasClass('btn-active')) {
1628        return 80;
1629    }
1630    else if ($('#btn-vhs-unit-kn').hasClass('btn-active')) {
1631        return 40;
1632    }
1633    else if ($('#btn-vhs-unit-kjm2').hasClass('btn-active')) {
1634        if($('#btn-vhs-mode-minutes').hasClass('btn-active')) {
1635            return 600;
1636        } else {
1637            return 1000;
1638        }
1639        
1640    }
1641    return 100;
1642}
1643var getVHStationUnit = function() {
1644    if ($('#btn-vhs-unit-ms').hasClass('btn-active')) {
1645        return 'm/s';
1646    }
1647    else if ($('#btn-vhs-unit-kmh').hasClass('btn-active')) {
1648        return 'km/h';
1649    }
1650    else if ($('#btn-vhs-unit-kn').hasClass('btn-active')) {
1651        return 'kn';
1652    }
1653    else if ($('#btn-vhs-unit-kjm2').hasClass('btn-active')) {
1654        return 'kJ/m²';
1655    }
1656    else if ($('#btn-vhs-unit-hpa').hasClass('btn-active')) {
1657        return 'hPa';
1658    }
1659    else if ($('#btn-vhs-unit-jcm2').hasClass('btn-active')) {
1660        return 'J/cm²';
1661    }
1662    else if ($('#btn-vhs-unit-percent').hasClass('btn-active')) {
1663        return '%';
1664    }
1665    return '';
1666}
1667
1668var getVHStationDateFormat = function(value, is_tooltip) {
1669    var date_format;
1670    date_format='%e. %b';
1671    if(is_tooltip) date_format = '%A, der %e. %B';
1672
1673    if ($('#btn-vhs-mode-hour').hasClass('btn-active')) {
1674        var hour = Highcharts.dateFormat("%H", value);
1675        if(hour%24!=0) { date_format='%H:%M'; }
1676        if(is_tooltip) date_format="%A, der %e.%B, %H:%M Uhr";
1677    }
1678    else if ($('#btn-vhs-mode-minutes').hasClass('btn-active')) {
1679        var hour = Highcharts.dateFormat("%H", value);
1680        if(hour%24!=0) { date_format='%H:%M'; }
1681        if(is_tooltip) date_format="%A, der %e.%B, %H:%M Uhr";
1682    }
1683    else if ($('#btn-vhs-mode-week').hasClass('btn-active')) {
1684        //date_format='%w';
1685    }
1686    else if ($('#btn-vhs-mode-month').hasClass('btn-active')) {
1687        date_format='%b';
1688        if(is_tooltip) date_format = '%B %Y';
1689    }
1690    else if ($('#btn-vhs-mode-year').hasClass('btn-active')) {
1691        date_format='%Y';
1692    }
1693    return date_format;
1694}
1695
1696function ordertooltip( a, b ) {
1697    if ( a.y < b.y ){
1698        return 1;
1699    }
1700    if ( a.y >
1700 b.y ){
1701        return -1;
1702    }
1703    return 0;
1704}
1705
1706(function(){
1707    const SCROLLER_SELECTOR = '.highcharts-scrolling, .highcharts-scrolling-parent, [data-highcharts-chart] .highcharts-scrolling';;
1708
1709    const lastLeft = new WeakMap();   // merkt pro Scroller die letzte scrollLeft-Position
1710    let hint, host, dismissed = false;
1711
1712    function isHorizOverflow(el){
1713        return el && el.scrollWidth - el.clientWidth > 2;
1714    }
1715    function isVisible(el){
1716        if (!el) return false;
1717        const cs = getComputedStyle(el);
1718        if (cs.visibility === 'hidden' || cs.display === 'none') return false;
1719        const r = el.getBoundingClientRect();
1720        return r.width > 0 && r.height > 0;
1721    }
1722    function getActiveScroller(){
1723        const root = (host && host.isConnected ? host : document);
1724        let list = Array.from(root.querySelectorAll(SCROLLER_SELECTOR));
1725
1726        if (!list.length && root !== document) {
1727            list = Array.from(document.querySelectorAll(SCROLLER_SELECTOR));
1728        }
1729
1730        return list.find(el => isVisible(el) && isHorizOverflow(el)) || list[0] || null;
1731    }
1732
1733
1734    function dismissHint(){
1735        if (!hint || dismissed) return;
1736        dismissed = true;
1737        hint.classList.add('dismiss');
1738        hint.addEventListener('animationend', () => hint.remove(), { once:true });
1739    }
1740
1741    function onScrollerScroll(e){
1742        const el = e.currentTarget || e.target;
1743        const prev = lastLeft.get(el) ?? el.scrollLeft;
1744        const moved = Math.abs(el.scrollLeft - prev) > 0;
1745        lastLeft.set(el, el.scrollLeft);
1746        if (moved && el.scrollLeft > 0) dismissHint();
1747    }
1748
1749    function attachToScroller(el){
1750        if (!el || el.__hcHintBound) return;
1751        el.__hcHintBound = true;
1752        lastLeft.set(el, el.scrollLeft);
1753        el.addEventListener('scroll', onScrollerScroll, { passive:true });
1754    }
1755
1756    function attachGlobalScrollListeners(){
1757
1758        document.querySelectorAll(SCROLLER_SELECTOR).forEach(attachToScroller);
1759        document.addEventListener('scroll', (e)=>{
1760            const t = e.target;
1761            if (!(t instanceof Element)) return;
1762            if (t.matches && t.matches(SCROLLER_SELECTOR)) onScrollerScroll(e);
1763        }, { passive:true, capture:true });
1764
1765        const mo = new MutationObserver(()=> {
1766            document.querySelectorAll(SCROLLER_SELECTOR).forEach(attachToScroller);
1767        });
1768        mo.observe(document.body, { subtree:true, childList:true, attributes:true, attributeFilter:['class','style'] });
1769    }
1770
1771
1772
1773    window.addGlobalChartScrollHint = function(hostContainer){
1774        host = hostContainer || document.body;
1775        if (!hint) {
1776            const firstScroller = getActiveScroller();
1777            if (!firstScroller || !isHorizOverflow(firstScroller)) return;
1778
1779            hint = document.createElement('button');
1780            hint.type = 'button';
1781            hint.className = 'scroll-hint';
1782            hint.textContent = (displayLanguage()=="EN")?'More Data →':'Mehr Daten →';
1783            (host).style.position = getComputedStyle(host).position === 'static' ? 'relative' : getComputedStyle(host).position;
1784            host.appendChild(hint);
1785
1786            hint.addEventListener('click', () => {
1787                const sc = getActiveScroller();
1788                if (sc) sc.scrollBy({ left: Math.round(sc.clientWidth * 0.33), behavior: 'smooth' });
1789                dismissHint();
1790            }, { passive:true });
1791
1792            attachGlobalScrollListeners();
1793        }
1794    };
1795})();
1796
1797var plotGraph = function() {
1798    Highcharts.seriesTypes.line.prototype.drawLegendSymbol = Highcharts.seriesTypes.column.prototype.drawLegendSymbol;
1799    Highcharts.AST.allowedAttributes.push('title');
1800    Highcharts.AST.allowedAttributes.push('data-longname');
1801    Highcharts.AST.allowedAttributes.push('data-flagfile');
1802    Highcharts.AST.allowedAttributes.push('data-run');
1803    Highcharts.AST.allowedAttributes.push('border');
1804    Highcharts.AST.allowedAttributes.push('cellspacing');
1805    var timezone_id_local = typeof timezone_id !== 'undefined' ? timezone_id : null;
1806    Highcharts.setOptions({
1807        global: {
1808            /**
1809             * Use moment-timezone.js to return the timezone offset for individual 
1810             * timestamps, used in the X axis labels and the tooltip header.
1811             */
1812            // getTimezoneOffset: function (timestamp) {
1813            //     return -moment.tz(timezone_id).utcOffset();
1814            // }
1815            timezone: timezone_id_local || $('#real-user-timezone').attr('data-value') || 'UTC'
1816
1817        },
1818        lang: typeof hc_user_settings_lang !== 'undefined' ? hc_user_settings_lang : {
1819            loading: 'Wird geladen...',
1820            months: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
1821            weekdays: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
1822            shortMonths: ['Jan', 'Feb', 'Mrz', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'],
1823        }
1824    });
1825    var zeroline = 0;
1826    if (typeof hccompact_units != 'undefined') {
1827        if (hccompact_units['temp'] == '°F') {
1828            zeroline = 32;
1829        }
1830        else if(hccompact_units['temp']=="K") {
1831            zeroline = 273.15;
1832        }
1833    }
1834    if (typeof hc_data_temp != 'undefined') {
1835       $('#temp_graph').highcharts({
1836           title: 'false',
1837
1838            chart: {
1839               scrollablePlotArea: {minWidth: getMinWidth()},
1840               className: (typeof hc_data_temp_chartclass != 'undefined')?hc_data_temp_chartclass:'',
1841               events: {
1842                   load: function() {
1843                       temp_graphContainerId = this.container.id;
1844                       $( '#'+temp_graphContainerId+'.toggle-flags' ).tooltip({
1845                           content: function() {
1846                               return "<img src='"+$(this).data('flagfile')+"' /><br /><span style='display: inline-block; color:#555; font-size: 13px; font-weight: bold; margin-top: 7px;'>"+$(this).data('longname')+"</span><br /><span style='color: #555; font-size:11px;'>"+$(this).data('run')+"</span>";
1847                           }
1848                       });
1849                       //drawHourlyLabels(this,'xl');
1850                        drawNightShadows(this,1,'xl');
1851                        fixLabels(this,'xl');
1852                   },
1853                   redraw: function(){
1854                       //drawHourlyLabels(this,'xl');
1855                        drawNightShadows(this,1,'xl');
1856                        fixLabels(this,'xl');
1857                    },
1858
1859               }
1860            },
1861           legend: xlLegendWithFlag,
1862           responsive: xlChartOptions(xlAlleNumbers),
1863
1864            xAxis: xlXAxisStandard,
1865            yAxis: xlYAxisTemp("{value} "+hccompact_units['temp'], zeroline),
1866            tooltip: xlTooltip(hccompact_units['temp'], 1),
1867            credits: { enabled: false },
1868            exporting: { enabled: false },
1869            plotOptions: xlPlotOptions('temp_graph'),
1870            series: xlSeries(hc_data_temp, {smooth: true}),
1871            reflow: true
1872        });
1873    }
1874    if (typeof hc_data_temp850 != 'undefined') {
1875       $('#temp850_graph').highcharts({
1876            title: 'false',
1877           chart: {
1878               scrollablePlotArea: {minWidth: getMinWidth()},
1879               className: (typeof hc_data_temp850_chartclass != 'undefined')?hc_data_temp850_chartclass:'',
1880               events: {
1881                   load: function() {
1882                       temp850_graphContainerId = this.container.id;
1883                       $( '#'+temp850_graphContainerId+'.toggle-flags' ).tooltip({
1884                           content: function() {
1885                               return "<img src='"+$(this).data('flagfile')+"' /><br /><span style='display: inline-block; color:#555; font-size: 13px; font-weight: bold; margin-top: 7px;'>"+$(this).data('longname')+"</span><br /><span style='color: #555; font-size:11px;'>"+$(this).data('run')+"</span>";
1886                           }
1887                       });
1888                   //drawHourlyLabels(this,'xl');
1889                        drawNightShadows(this,3,'xl');
1890                        fixLabels(this,'xl');
1891                   },
1892                   redraw: function(){
1893                       //drawHourlyLabels(this,'xl');
1894                        drawNightShadows(this,3,'xl');
1895                        fixLabels(this,'xl');
1896                    }
1897               }
1898           },
1899           legend: xlLegendWithFlag,
1900           responsive: xlChartOptions(xl850Numbers),
1901            xAxis: xlXAxisStandard,
1902            yAxis: xlYAxisTemp("{value} "+hccompact_units['temp'],zeroline),
1903            tooltip: xlTooltip(hccompact_units['temp'], 1),
1904            credits: { enabled: false },
1905            exporting: { enabled: false },
1906            plotOptions: xlPlotOptions('temp850_graph'),
1907            series: xlSeries(hc_data_temp850, {smooth: true}),
1908            reflow: true
1909        });
1910    }
1911
1912    if (typeof hc_data_temp925 != 'undefined') {
1913       $('#temp925_graph').highcharts({
1914           title: 'false',
1915           chart: {
1916               scrollablePlotArea: {minWidth: getMinWidth()},
1917               className: (typeof hc_data_temp925_chartclass != 'undefined')?hc_data_temp925_chartclass:'',
1918               events: {
1919                   load: function() {
1920                       temp925_graphContainerId = this.container.id;
1921                       $( '#'+temp925_graphContainerId+'.toggle-flags' ).tooltip({
1922                           content: function() {
1923                               return "<img src='"+$(this).data('flagfile')+"' /><br /><span style='display: inline-block; color:#555; font-size: 13px; font-weight: bold; margin-top: 7px;'>"+$(this).data('longname')+"</span><br /><span style='color: #555; font-size:11px;'>"+$(this).data('run')+"</span>";
1924                           }
1925                       });
1926                   //drawHourlyLabels(this,'xl');
1927                        drawNightShadows(this,4,'xl');
1928                        fixLabels(this,'xl');
1929                   },
1930                   redraw: function(){
1931                       //drawHourlyLabels(this,'xl');
1932                        drawNightShadows(this,4,'xl');
1933                        fixLabels(this,'xl');
1934                    }
1935               }
1936           },
1937           legend: xlLegendWithFlag,
1938           responsive: xlChartOptions(xl925Numbers),
1939            xAxis: xlXAxisStandard,
1940            yAxis: xlYAxisTemp("{value} "+hccompact_units['temp'],zeroline),
1941            tooltip: xlTooltip(hccompact_units['temp'], 1),
1942            credits: { enabled: false },
1943            exporting: { enabled: false },
1944           plotOptions: xlPlotOptions('temp925_graph'),
1945            series: xlSeries(hc_data_temp925, {smooth: true}),
1946            reflow: true
1947        });
1948    }
1949    
1950    if (typeof hc_data_temp700 != 'undefined') {
1951       $('#temp700_graph').highcharts({
1952           title: 'false',
1953           chart: {
1954               scrollablePlotArea: {minWidth: getMinWidth()},
1955               className: (typeof hc_data_temp700_chartclass != 'undefined')?hc_data_temp700_chartclass:'',
1956               events: {
1957                   load: function() {
1958                       temp700ContainerId = this.container.id;
1959                       $( '#'+temp700ContainerId+'.toggle-flags' ).tooltip({
1960                           content: function() {
1961                               return "<img src='"+$(this).data('flagfile')+"' /><br /><span style='display: inline-block; color:#555; font-size: 13px; font-weight: bold; margin-top: 7px;'>"+$(this).data('longname')+"</span><br /><span style='color: #555; font-size:11px;'>"+$(this).data('run')+"</span>";
1962                           }
1963                       });
1964                   //drawHourlyLabels(this,'xl');
1965                        drawNightShadows(this,5,'xl');
1966                        fixLabels(this,'xl');
1967                   },
1968                   redraw: function(){
1969                       //drawHourlyLabels(this,'xl');
1970                        drawNightShadows(this,5,'xl');
1971                        fixLabels(this,'xl');
1972                    }
1973               }
1974           },
1975           legend: xlLegendWithFlag,
1976           responsive: xlChartOptions(xl700Numbers),
1977            xAxis: xlXAxisStandard,
1978            yAxis: xlYAxisTemp("{value} "+hccompact_units['temp'],zeroline),
1979            tooltip: xlTooltip(hccompact_units['temp'], 1),
1980            credits: { enabled: false },
1981            exporting: { enabled: false },
1982           plotOptions: xlPlotOptions('temp700_graph'),
1983            series: xlSeries(hc_data_temp700, {smooth: true}),
1984            reflow: true
1985        });
1986    }
1987
1988    if (typeof hc_data_dewpoint != 'undefined') {
1989       $('#dewpoint_graph').highcharts({
1990           title: 'false',
1991           chart: {
1992               scrollablePlotArea: {minWidth: getMinWidth()},
1993               className: (typeof hc_data_dewpoint_chartclass != 'undefined')?hc_data_dewpoint_chartclass:'',
1994               events: {
1995                   load: function() {
1996                       dewpointContainerId = this.container.id;
1997                       $( '#'+dewpointContainerId+'.toggle-flags' ).tooltip({
1998                           content: function() {
1999                               return "<img src='"+$(this).data('flagfile')+"' /><br /><span style='display: inline-block; color:#555; font-size: 13px; font-weight: bold; margin-top: 7px;'>"+$(this).data('longname')+"</span><br /><span style='color: #555; font-size:11px;'>"+$(this).data('run')+"</span>";
2000                           }
2001                       });
2002                       //drawHourlyLabels(this,'xl');
2003                        drawNightShadows(this,6,'xl');
2004                        fixLabels(this,'xl');
2005                    },
2006                    redraw: function(){
2007                       //drawHourlyLabels(this,'xl');
2008                        drawNightShadows(this,6,'xl');
2009                        fixLabels(this,'xl');
2010                    }
2011               }
2012           },
2013           legend: xlLegendWithFlag,
2014           responsive: xlChartOptions(xlAlleNumbers),
2015            xAxis: xlXAxisStandard,
2016            yAxis: xlYAxisTemp("{value}"+hccompact_units['temp'],zeroline),
2017            tooltip: xlTooltip(hccompact_units['temp'], 1),
2018            credits: { enabled: false },
2019            exporting: { enabled: false },
2020           plotOptions: xlPlotOptions('dewpoint_graph'),
2021            series: xlSeries(hc_data_dewpoint, {smooth: true}),
2022            reflow: true
2023        });
2024    }
2025
2026    if (typeof hc_data_wbulb != 'undefined') {
2027        $('#wbulb_graph').highcharts({
2028             title: 'false',
2029            chart: {
2030                scrollablePlotArea: {minWidth: getMinWidth()},
2031               className: (typeof hc_data_wbulb_chartclass != 'undefined')?hc_data_wbulb_chartclass:'',
2032                events: {
2033                    load: function() {
2034                        wbulbContainerId = this.container.id;
2035                        $( '#'+wbulbContainerId+'.toggle-flags' ).tooltip({
2036                            content: function() {
2037                                return "<img src='"+$(this).data('flagfile')+"' /><br /><span style='display: inline-block; color:#555; font-size: 13px; font-weight: bold; margin-top: 7px;'>"+$(this).data('longname')+"</span><br /><span style='color: #555; font-size:11px;'>"+$(this).data('run')+"</span>";
2038                            }
2039                        });
2040                    //drawHourlyLabels(this,'xl');
2041                        drawNightShadows(this,7,'xl');
2042                        fixLabels(this,'xl');
2043                    },
2044                    redraw: function(){
2045                       //drawHourlyLabels(this,'xl');
2046                        drawNightShadows(this,7,'xl');
2047                        fixLabels(this,'xl');
2048                    }
2049                }
2050            },
2051            legend: xlLegendWithFlag,
2052            responsive: xlChartOptions(xlWbulbNumbers),
2053             xAxis: xlXAxisStandard,
2054             yAxis: xlYAxisTemp("{value} "+hccompact_units['temp'],zeroline),
2055             tooltip: xlTooltip(hccompact_units['temp'], 1),
2056             credits: { enabled: false },
2057             exporting: { enabled: false },
2058            plotOptions: xlPlotOptions('wbulb_graph'),
2059             series: xlSeries(hc_data_wbulb, {smooth: true}),
2060             reflow: true
2061         });
2062     }
2063
2064    if (typeof hc_data_pressure != 'undefined') {
2065        console.log("pressure");
2066       $('#pressure_graph').highcharts({
2067            title: 'false',
2068           chart: {
2069               scrollablePlotArea: {minWidth: getMinWidth()},
2070               className: (typeof hc_data_pressure_chartclass != 'undefined')?hc_data_pressure_chartclass:'',
2071               events: {
2072                   load: function() {
2073                       pressureContainerId = this.container.id;
2074                       $( '#'+pressureContainerId+'.toggle-flags' ).tooltip({
2075                           content: function() {
2076                               return "<img src='"+$(this).data('flagfile')+"' /><br /><span style='display: inline-block; color:#555; font-size: 13px; font-weight: bold; margin-top: 7px;'>"+$(this).data('longname')+"</span><br /><span style='color: #555; font-size:11px;'>"+$(this).data('run')+"</span>";
2077                           }
2078                       });
2079                   //drawHourlyLabels(this,'xl');
2080                        drawNightShadows(this,31,'xl');
2081                        fixLabels(this,'xl');
2082                   },
2083                   redraw: function(){
2084                       //drawHourlyLabels(this,'xl');
2085                        drawNightShadows(this,31,'xl');
2086                        fixLabels(this,'xl');
2087                    }
2088               }
2089           },
2090           legend: xlLegendWithFlag,
2091           responsive: xlChartOptions(xlAlleNumbers),
2092            xAxis: xlXAxisStandard,
2093            yAxis: xlYAxisStandardFormatter(function() {
2094                        return Highcharts.numberFormat(this.value,hccompact_units['pressure'] === '
2094inHg' ? 1 : 0)+(hccompact_units['pressure'] === 'mbar' ? "":" ")+hccompact_units['pressure'];
2095                    },0, hccompact_units['pressure'] === 'inHg', hccompact_units['pressure'] === 'inHg' ? 0.1:1),
2096            tooltip: xlTooltip(hccompact_units['pressure'], 1),
2097            credits: { enabled: false },
2098            exporting: { enabled: false },
2099            plotOptions: xlPlotOptions('pressure_graph'),
2100            series: xlSeries(hc_data_pressure, {smooth: true}),
2101            reflow: true
2102        });
2103    }
2104
2105    if (typeof hc_data_wind != 'undefined') {
2106        $('#wind_graph').highcharts({
2107            title: 'false',
2108            chart: {
2109                scrollablePlotArea: {minWidth: getMinWidth()},
2110               className: (typeof hc_data_wind_chartclass != 'undefined')?hc_data_wind_chartclass:'',
2111                events: {
2112                    load: function() {
2113                        windContainerId = this.container.id;
2114                        $( '#'+windContainerId+'.toggle-flags' ).tooltip({
2115                            content: function() {
2116                                return "<img src='"+$(this).data('flagfile')+"' /><br /><span style='display: inline-block; color:#555; font-size: 13px; font-weight: bold; margin-top: 7px;'>"+$(this).data('longname')+"</span><br /><span style='color: #555; font-size:11px;'>"+$(this).data('run')+"</span>";
2117                            }
2118                        });
2119                    //drawHourlyLabels(this,'xl');
2120                        drawNightShadows(this,9,'xl');
2121                        fixLabels(this,'xl');
2122                   },
2123                   redraw: function(){
2124                       //drawHourlyLabels(this,'xl');
2125                        drawNightShadows(this,9,'xl');
2126                        fixLabels(this,'xl');
2127                    }
2128                }
2129            },
2130            legend: xlLegendWithFlag,
2131            responsive: xlChartOptions(xlAlleNumbers),
2132            xAxis: xlXAxisStandard,
2133            yAxis: {
2134                title: {
2135                    text: false
2136                },
2137                floor: 0,
2138                labels: {
2139                    format: "{value} "+hccompact_units['wind'],
2140                    style: {
2141                        color: cssVar('--color-text')
2142                    }
2143                },
2144                min: 0,
2145                max: hccompact_units['wind']=="Bft" ? 12 : hccompact_units['wind']=="m/s" ? 30 : hccompact_units['wind']=="kn" ? 60 : hccompact_units['wind']=="mph" ? 60 : 100,
2146                allowDecimals: false,
2147                minorTickInterval: 5,
2148                gridLineColor: cssVar('--hc-gridLineColorC0C0C0'),
2149                minorGridLineColor: cssVar('--hc-gridLineColorf2f2f2'),
2150
2151                endOnTick: false,
2152                tickAmount: 5
2153            },
2154            tooltip: xlTooltip(hccompact_units['wind'], hccompact_units['wind'] == 'm/s' ? 1 : 0),
2155            credits: { enabled: false },
2156            exporting: { enabled: false },
2157            plotOptions: xlPlotOptions('wind_graph'),
2158            series: xlSeries(hc_data_wind, {smooth: false}),
2159            reflow: true
2160        });
2161    }
2162    
2163    if (typeof wind_graph_open != 'undefined') {
2164        $('#wind_graph_open').highcharts({
2165            title: 'false',
2166            chart: {
2167                scrollablePlotArea: {minWidth: getMinWidth()},
2168               className: (typeof wind_graph_open_chartclass != 'undefined')?wind_graph_open_chartclass:'',
2169                events: {
2170                    load: function() {
2171                        windopenContainerId = this.container.id;
2172                        $( '#'+windopenContainerId+'.toggle-flags' ).tooltip({
2173                            content: function() {
2174                                return "<img src='"+$(this).data('flagfile')+"' /><br /><span style='display: inline-block; color:#555; font-size: 13px; font-weight: bold; margin-top: 7px;'>"+$(this).data('longname')+"</span><br /><span style='color: #555; font-size:11px;'>"+$(this).data('run')+"</span>";
2175                            }
2176                        });
2177                    //drawHourlyLabels(this,'xl');
2178                        drawNightShadows(this,10,'xl');
2179                        fixLabels(this,'xl');
2180                   },
2181                   redraw: function(){
2182                       //drawHourlyLabels(this,'xl');
2183                        drawNightShadows(this,10,'xl');
2184                        fixLabels(this,'xl');
2185                    }
2186                }
2187            },
2188            legend: xlLegendWithFlag,
2189            responsive: xlChartOptions(xlAlleNumbers),
2190            xAxis: xlXAxisStandard,
2191            yAxis: {
2192                title: {
2193                    text: false
2194                },
2195                floor: 0,
2196                labels: {
2197                    format: "{value} "+hccompact_units['wind']
2198                },
2199                min:0,
2200                allowDecimals: false,
2201                gridLineColor: cssVar('--hc-gridLineColorC0C0C0'),
2202            },
2203            tooltip: xlTooltip(hccompact_units['wind'], hccompact_units['wind'] == 'm/s' ? 1 : 0),
2204            credits: { enabled: false },
2205            exporting: { enabled: false },
2206            plotOptions: xlPlotOptions('wind_graph_open'),
2207            series: xlSeries(hc_data_wind_open, {smooth: false}),
2208            reflow: true
2209        });
2210    }
2211    
2212    if (typeof hc_data_gusts != 'undefined') {
2213        $('#gusts_graph').highcharts({
2214            title: 'false',
2215            chart: {
2216                scrollablePlotArea: {minWidth: getMinWidth()},
2217               className: (typeof hc_data_gusts_chartclass != 'undefined')?hc_data_gusts_chartclass:'',
2218                events: {
2219                    load: function() {
2220                        gustsContainerId = this.container.id;
2221                        $( '#'+gustsContainerId+'.toggle-flags' ).tooltip({
2222                            content: function() {
2223                                return "<img src='"+$(this).data('flagfile')+"' /><br /><span style='display: inline-block; color:#555; font-size: 13px; font-weight: bold; margin-top: 7px;'>"+$(this).data('longname')+"</span><br /><span style='color: #555; font-size:11px;'>"+$(this).data('run')+"</span>";
2224                            }
2225                        });
2226                    //drawHourlyLabels(this,'xl');
2227                        drawNightShadows(this,11,'xl');
2228                        fixLabels(this,'xl');
2229                   },
2230                   redraw: function(){
2231                       //drawHourlyLabels(this,'xl');
2232                        drawNightShadows(this,11,'xl');
2233                        fixLabels(this,'xl');
2234                    }
2235                }
2236            },
2237            legend: xlLegendWithFlag,
2238            responsive: xlChartOptions(xlAlleNumbers),
2239            xAxis: xlXAxisStandard,
2240            yAxis: {
2241                title: {
2242                    text: false
2243                },
2244                allowDecimals: false,
2245                floor: 0,
2246                labels: {
2247                    format: "{value} "+hccompact_units['wind'],
2248                    style: {
2249                        color: cssVar('--color-text')
2250                    }
2251                },
2252                min:0,
2253                softMax: hccompact_units['wind']=="Bft" ? 12 : hccompact_units['wind']=="m/s" ? 30 : hccompact_units['wind']=="kn" ? 60 : hccompact_units['wind']=="mph" ? 60 : 100,
2254                minorTickInterval: 5,
2255                gridLineColor: cssVar('--hc-gridLineColorC0C0C0'),
2256                minorGridLineColor: cssVar('--hc-gridLineColorf2f2f2'),
2257                tickAmount: 5
2258            },
2259            tooltip: xlTooltip(hccompact_units['wind'], hccompact_units['wind'] == 'm/s' ? 1 : 0),
2260            credits: { enabled: false },
2261            exporting: { enabled: false },
2262            plotOptions: xlPlotOptions('gusts_graph'),
2263            series: xlSeries(hc_data_gusts, {smooth: false}),
2264            reflow: true
2265        });
2266    }
2267
2268    if (typeof hc_data_gusts_open != 'undefined') {
2269        $('#gusts_graph_open').highcharts({
2270            title: 'false',
2271            chart: {
2272                scrollablePlotArea: {minWidth: getMinWidth()},
2273               className: (typeof hc_data_gusts_open_chartclass != 'undefined')?hc_data_gusts_open_chartclass:'',
2274                events: {
2275                    load: function() {
2276                        gustsopenContainerId = this.container.id;
2277                        $( '#'+gustsopenContainerId+'.toggle-flags' ).tooltip({
2278                            content: function() {
2279                                return "<img src='"+$(this).data('flagfile')+"' /><br /><span style='display: inline-block; color:#555; font-size: 13px; font-weight: bold; margin-top: 7px;'>"+$(this).data('longname')+"</span><br /><span style='color: #555; font-size:11px;'>"+$(this).data('run')+"</span>";
2280                            }
2281                        });
2282                    //drawHourlyLabels(this,'xl');
2283                        drawNightShadows(this,13,'xl');
2284                        fixLabels(this,'xl');
2285                   },
2286                   redraw: function(){
2287                       //drawHourlyLabels(this,'xl');
2288                        drawNightShadows(this,13,'xl');
2289                        fixLabels(this,'xl');
2290                    }
2291                }
2292            },
2293            legend: xlLegendWithFlag,
2294            responsive: xlChartOptions(xlAlleNumbers),
2295            xAxis: xlXAxisStandard,
2296            yAxis: {
2297                title: {
2298                    text: false
2299                },
2300                floor: 0,
2301                labels: {
2302                    format: "{value} "+hccompact_units['wind'],
2303                    style: {
2304                        color: cssVar('--color-text')
2305                    }
2306                },
2307                min:0,
2308                allowDecimals: false,
2309                gridLineColor: cssVar('--hc-gridLineColorC0C0C0'),
2310                minorGridLineColor: cssVar('--hc-gridLineColorf2f2f2'),
2311            },
2312            tooltip: xlTooltip(hccompact_units['wind'], hccompact_units['wind'] == 'm/s' ? 1 : 0),
2313            credits: { enabled: false },
2314            exporting: { enabled: false },
2315            plotOptions: xlPlotOptions('gusts_graph_open'),
2316            series: xlSeries(hc_data_gusts_open, {smooth: false}),
2317            reflow: true
2318        });
2319    }
2320    
2321    if (typeof hc_data_rain != 'undefined') {
2322        $('#rain_graph').highcharts({
2323
2324            chart: {
2325                scrollablePlotArea: {minWidth: getMinWidth()},
2326               type: 'column',
2327                className: (typeof hc_data_rain_chartclass != 'undefined')?hc_data_rain_chartclass:'',
2328                events: {
2329                    load: function() {
2330                        rainContainerId = this.container.id;
2331                        $( '#'+rainContainerId+'.toggle-flags' ).tooltip({
2332                            content: function() {
2333                                return "<img src='"+$(this).data('flagfile')+"' /><br /><span style='display: inline-block; color:#555; font-size: 13px; font-weight: bold; margin-top: 7px;'>"+$(this).data('longname')+"</span><br /><span style='color: #555; font-size:11px;'>"+$(this).data('run')+"</span>";
2334                            }
2335                        });
2336                        drawHourlyLabels(this,'xl2');
2337                        drawIntervals(this,8,undefined,'xl');
2338                        fixLabels(this,'temp');
2339                   },
2340                   redraw: function(){
2341                        drawHourlyLabels(this,'xl2');
2342                        drawIntervals(this,8,undefined,'xl');
2343                        fixLabels(this,'temp');
2344                    }
2345                }
2346            },
2347            title: 'false',
2348            legend: xlLegendWithFlag,
2349            responsive: xlChartOptions(xlAlleNumbers),
2350            xAxis: {
2351                opposite:true,
2352                type: 'datetime',
2353                tickInterval: 24*36e5,
2354                gridLineWidth: 0,
2355                gridLineColor: cssVar('--hc-gridLineColor777777'),
2356                gridZIndex:2,
2357                tickLength: 0,
2358                dateTimeLabelFormats: {
2359                    hour: getDynHourDateFormat(),
2360                    day: getDynDayDateFormat()
2361                },
2362                labels: {
2363                        useHTML: true,
2364                        align: 'center',
2365                    style: {
2366                        color: cssVar('--color-text')
2367                    },
2368                        formatter: function () {
2369                                var date_format = getDynDayShortDateFormat(this.value, this.chart.plotWidth);
2370                                return Highcharts.dateFormat(date_format, this.value);
2371                        }
2372                }
2373
2374            },
2375            yAxis: xlRainYAxis(),
2376            tooltip: xlTooltip(hccompact_units['rain'], hccompact_units['rain'] == 'in' ? 2 : 1, {rangeHours: 6}),
2377            credits: { enabled: false },
2378            exporting: { enabled: false },
2379            plotOptions: xlPlotOptions('rain_graph'),
2380            series: xlSeries(hc_data_rain, {column: true, stats: false /*, medianColor: xlColor('--hc-xl-median-rain', '#1B6FB5') */}),
2381            reflow: true
2382        });
2383    }    
2384
2385    if (typeof hc_data_rain_day != 'undefined') {
2386        $('#rain_graph_day').highcharts({
2387
2388            chart: {
2389                scrollablePlotArea: {minWidth: getMinWidth()},
2390               type: 'column',
2391                className: (typeof hc_data_rain_chartclass != 'undefined')?hc_data_rain_chartclass:'',
2392                events: {
2393                    load: function() {
2394                        raindayContainerId = this.container.id;
2395                        $( '#'+raindayContainerId+'.toggle-flags' ).tooltip({
2396                            content: function() {
2397                                return "<img src='"+$(this).data('flagfile')+"' /><br /><span style='display: inline-block; color:#555; font-size: 13px; font-weight: bold; margin-top: 7px;'>"+$(this).data('longname')+"</span><br /><span style='color: #555; font-size:11px;'>"+$(this).data('run')+"</span>";
2398                            }
2399                        });
2400
2401                        //drawHourlyLabels(this,'xl3');
2402                        drawIntervals(this,8,48,'xl');
2403                        //fixLabels(this,'temp');
2404                    },
2405                    redraw: function() {
2406
2407                        //drawHourlyLabels(this,'xl3');
2408                        drawIntervals(this,8,48,'xl');
2409                        //fixLabels(this,'temp');
2410                    }
2411
2412                }
2413            },
2414            title: 'false',
2415            legend: xlLegendWithFlag,
2416            responsive: xlChartOptions(xlAlleNumbers),
2417            xAxis: {
2418                opposite:true,
2419                type: 'datetime',
2420                tickLength: 0,
2421                lineColor: cssVar('--hc-gridLineColorCCCCCC'),
2422                minorGridLineColor: cssVar('--hc-gridLineColorCCCCCC'),
2423                dateTimeLabelFormats: {
2424                    hour: getDynHourDateFormat(),
2425                    day: getDynDayDateFormat()
2426                },
2427                labels: {
2428                        useHTML: true,
2429                        align: 'center',
2430                    style: {
2431                        color: cssVar('--color-text')
2432                    },
2433                        formatter: function () {
2434                                var date_format = getDynDayShortDateFormat(this.value, this.chart.plotWidth);
2435                                return Highcharts.dateFormat(date_format, this.value);
2436                        }
2437                },
2438
2439
2440            },
2441            yAxis: xlRainYAxis(),
2442            tooltip: xlTooltip(hccompact_units['rain'], hccompact_units['rain'] == 'in' ? 2 : 1),
2443            credits: { enabled: false },
2444            exporting: { enabled: false },
2445            plotOptions: xlPlotOptions('rain_graph_day'),
2446            series: xlSeries(hc_data_rain_day, {column: true, stats: false /*, medianColor: xlColor('--hc-xl-median-rain', '#1B6FB5') */}),
2447            reflow: true
2448        });
2449    }
2450    
2451    if (typeof hc_data_sunshine_day != 'undefined') {
2452        $('#sunshine_graph_day').highcharts({
2453
2454            chart: {
2455                scrollablePlotArea: {min
2455Width: getMinWidth()},
2456               type: 'column',
2457                className: (typeof chartclass != 'undefined')?chartclass:'',
2458                events: {
2459                    load: function() {
2460                        sunshinedayContainerId = this.container.id;
2461                        $( '#'+sunshinedayContainerId+'.toggle-flags' ).tooltip({
2462                            content: function() {
2463                                return "<img src='"+$(this).data('flagfile')+"' /><br /><span style='display: inline-block; color:#555; font-size: 13px; font-weight: bold; margin-top: 7px;'>"+$(this).data('longname')+"</span><br /><span style='color: #555; font-size:11px;'>"+$(this).data('run')+"</span>";
2464                            }
2465                        });
2466                    //drawHourlyLabels(this,'xl');
2467                        drawNightShadows(this,15,'xl');
2468                        fixLabels(this,'xl');
2469                   },
2470                   redraw: function(){
2471                       //drawHourlyLabels(this,'xl');
2472                        drawNightShadows(this,15,'xl');
2473                        fixLabels(this,'xl');
2474                    }
2475                }
2476            },
2477            title: 'false',
2478            legend: xlLegendWithFlag,
2479            responsive: xlChartOptions(xlAlleNumbers),
2480            xAxis: xlXAxisStandard,
2481            yAxis: {
2482                title: {
2483                    text: false
2484                },
2485                floor: 0,
2486                labels: {
2487                    format: "{value} "+hccompact_units['sun'],
2488                    style: {
2489                        color: cssVar('--color-text')
2490                    }
2491                },
2492                min:0,
2493                softMax: 12,
2494                allowDecimals: false,
2495                minorTickInterval: 1,
2496                gridLineColor: cssVar('--hc-gridLineColorC0C0C0'),
2497
2498            },
2499            tooltip: {
2500                crosshairs: true,
2501                shared: true,
2502                valueSuffix: ' '+hccompact_units['sun'],
2503                shape: 'square',
2504                useHTML: true,
2505                dateTimeLabelFormats: {
2506                        minute:"%A, den %e.%B",
2507                        hour:"%A, den %e.%B",
2508                },
2509                zIndex: 50,
2510                outside: false,
2511                style: {
2512                    zIndex: 10000,
2513                    pointerEvents: 'auto'
2514                },
2515                positioner: tooltipPositioner,
2516                formatter: function () { 
2517                    var date_format = getDynDateFormat(this.x);
2518                    var s = '<span style="font-size:10px; font-weight: bold; line-height: 20px;">'+Highcharts.dateFormat(date_format, this.x)+ '</span> ';
2519                    this.points.sort( ordertooltip );
2520                    s += '<table width="100%" border="0" cellspacing="1">';
2521                    $.each(this.points, function () {
2522                        s += '<tr><td style="font-size: 11px; line-height: 16px;" width="70%"><span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ this.series.name + ':</td><td width="30%" style="text-align: right; font-size: 11px; line-height: 16px;"><b>'+(Math.round(this.y * 100) / 100).toFixed(1) + '</b> '+hccompact_units['sun']+'</td></tr>';
2523                    });
2524                    s += '</table>';
2525
2526
2527		            return s;
2528        		}
2529            },
2530            credits: { enabled: false },
2531            exporting: { enabled: false },
2532            plotOptions: xlPlotOptions('sunshine_graph_day'),
2533            series: xlSeries(hc_data_sunshine_day, {column: true, stats: false}),
2534            reflow: true
2535        });
2536    }
2537    
2538    if (typeof hc_data_rain2 != 'undefined') {
2539        $('#rain2_graph').highcharts({
2540            chart: {
2541                scrollablePlotArea: {minWidth: getMinWidth()},
2542               className: (typeof chartclass != 'undefined')?chartclass:'',
2543                events: {
2544                    load: function() {
2545                        rain2ContainerId = this.container.id;
2546                        $( '#'+rain2ContainerId+'.toggle-flags' ).tooltip({
2547                            content: function() {
2548                                return "<img src='"+$(this).data('flagfile')+"' /><br /><span style='display: inline-block; color:#555; font-size: 13px; font-weight: bold; margin-top: 7px;'>"+$(this).data('longname')+"</span><br /><span style='color: #555; font-size:11px;'>"+$(this).data('run')+"</span>";
2549                            }
2550                        });
2551                    //drawHourlyLabels(this,'xl');
2552                        drawNightShadows(this,17,'xl');
2553                        fixLabels(this,'xl');
2554                   },
2555                   redraw: function(){
2556                       //drawHourlyLabels(this,'xl');
2557                        drawNightShadows(this,17,'xl');
2558                        fixLabels(this,'xl');
2559                    }
2560                }
2561            },
2562            title: 'false',
2563            legend: xlLegendWithFlag,
2564            responsive: xlChartOptions(xlAlleNumbers),
2565            xAxis: {
2566                                opposite:true,
2567                type: 'datetime',
2568                tickInterval: 24*36e5,
2569                gridLineWidth: 1,
2570                gridLineColor: cssVar('--hc-gridLineColor777777'),
2571                gridZIndex:2,
2572                minorTickInterval: 3*36e5,
2573                minorGridLineColor: cssVar('--hc-gridLineColorCCCCCC'),
2574                minorGridWidth: 1,
2575                tickLength: 0,
2576                dateTimeLabelFormats: {
2577                    hour: getDynHourDateFormat(),
2578                    day: getDynDayDateFormat()
2579                },
2580                labels: {
2581                        useHTML: true,
2582                        align: 'center',
2583                        formatter: function () {
2584                                var date_format = getDynDayShortDateFormat(this.value, this.chart.plotWidth);
2585                                return Highcharts.dateFormat(date_format, this.value);
2586                        },
2587                    style: {
2588                        color: cssVar('--color-text')
2589                    }
2590                }
2591
2592            },
2593            yAxis: xlRainYAxis(),
2594            tooltip: xlTooltip(hccompact_units['rain'], hccompact_units['rain'] == 'in' ? 2 : 1),
2595            credits: { enabled: false },
2596            exporting: { enabled: false },
2597            plotOptions: xlPlotOptions('rain2_graph'),
2598            series: xlSeries(hc_data_rain2, {column: true, stats: false /*, medianColor: xlColor('--hc-xl-median-rain', '#1B6FB5') */}),
2599            reflow: true
2600        });
2601    }
2602
2603    if (typeof hc_data_accrain != 'undefined') {
2604        $('#accrain_graph').highcharts({
2605            chart: {
2606                scrollablePlotArea: {minWidth: getMinWidth()},
2607               className: (typeof hc_data_accrain_chartclass != 'undefined')?hc_data_accrain_chartclass:'',
2608                events: {
2609                    load: function() {
2610                        accrainContainerId = this.container.id;
2611                        $( '#'+accrainContainerId+'.toggle-flags' ).tooltip({
2612                            content: function() {
2613                                return "<img src='"+$(this).data('flagfile')+"' /><br /><span style='display: inline-block; color:#555; font-size: 13px; font-weight: bold; margin-top: 7px;'>"+$(this).data('longname')+"</span><br /><span style='color: #555; font-size:11px;'>"+$(this).data('run')+"</span>";
2614                            }
2615                        });
2616                    //drawHourlyLabels(this,'xl');
2617                        drawNightShadows(this,18,'xl');
2618                        fixLabels(this,'xl');
2619                   },
2620                   redraw: function(){
2621                       //drawHourlyLabels(this,'xl');
2622                        drawNightShadows(this,18,'xl');
2623                        fixLabels(this,'xl');
2624                    }
2625                }
2626            },
2627            title: 'false',
2628            legend: xlLegendWithFlag,
2629            responsive: xlChartOptions(xlAlleNumbers),
2630            xAxis: xlXAxisStandard,
2631            yAxis: xlRainYAxis(),
2632            tooltip: xlTooltip(hccompact_units['rain'], hccompact_units['rain'] == 'in' ? 2 : 1),
2633            credits: { enabled: false },
2634            exporting: { enabled: false },
2635            plotOptions: xlPlotOptions('accrain_graph'),
2636            series: xlSeries(hc_data_accrain, {smooth: false, monotone: true}),
2637            reflow: true
2638        });
2639    }
2640    addGlobalChartScrollHint(document.querySelector('.tab-content'));
2641    buildXlLegends();
2642};
2643
2644/**
2645 * ============================================================================
2646 *  XL-Multimodell-Legende (Modellauswahl unter dem Meteogramm)
2647 * ============================================================================
2648 *  Gruppen: Regional / Global / KI / Multimodell / MOS.
2649 *
2650 *  Designprinzip: EIN Zustand, EINE Wahrheit.
2651 *  `xlSelection` ist eine flache Map `param -> bool` über ALLE bekannten
2652 *  Modelle. Der Gruppen-Zustand wird nie gespeichert, sondern bei jedem
2653 *  Render frisch daraus abgeleitet (all / none / mixed). Dadurch ist
2654 *  "Nur diese Gruppe" lediglich ein Massen-Set auf dieselbe Map und
2655 *  beliebig mit einzelnen Modell-Toggles kombinierbar.
2656 *
2657 *  Alle Aktionen sind absolut (idempotent) - ein doppelt ausgelöstes Event
2658 *  kann den Zustand daher nicht mehr "umklappen".
2659 */
2660var XL_SEL_KEY = 'xlModelSelection.v2';
2661var XL_TAB_KEY = 'xlModelTab.v1';
2662
2663var xlSelection = null;   // { GFS: true, ICON_D2: false, ... }
2664var xlDefaults = {};      // Server-Default (aus series.visible beim ersten Sehen)
2665var xlBound = false;      // Event-Delegation nur EINMAL binden
2666var xlActiveTab = null;   // aktiver Reiter der Modellauswahl
2667var xlGroupOrder = ['regional', 'global', 'mos', 'multimodel', 'ai'];
2668
2669/**
2670 * Reiter der Modellauswahl.
2671 *
2672 * WICHTIG: Die Reiter sind ein reiner ANSICHTSFILTER fuer die Chip-Liste.
2673 * Sie veraendern die Sichtbarkeit im Chart nicht - der Zustand bleibt beim
2674 * Reiterwechsel unangetastet, damit Modelle weiterhin frei ueber Gruppen
2675 * hinweg kombiniert werden koennen.
2676 *
2677 * Jede Modellgruppe bekommt einen eigenen Reiter. "Weitere" bleibt als
2678 * Auffangbecken fuer Gruppen, die hier (noch) nicht bekannt sind.
2679 */
2680var xlTabOrder = ['all', 'regional', 'global', 'mos', 'multimodel', 'ai', 'other'];
2681
2682/** Gruppe -> Reiter. Unbekannte Gruppen landen automatisch unter "Weitere". */
2683var xlTabOf = function (g) {
2684    if (g === 'regional') { return 'regional'; }
2685    if (g === 'global') { return 'global'; }
2686    if (g === 'mos') { return 'mos'; }
2687    if (g === 'multimodel') { return 'multimodel'; }
2688    if (g === 'ai') { return 'ai'; }
2689    return 'other';
2690};
2691
2692/** Fallback-Labels, falls der Server (xlLegendI18n) nichts geliefert hat. */
2693var xlLegendFallback = {
2694    title: 'Modellauswahl',
2695    all: 'Alle anzeigen',
2696    only: 'Nur diese Gruppe',
2697    show: 'Alle einblenden',
2698    hide: 'Alle ausblenden',
2699    visible: '{visible} von {total} Modellen sichtbar',
2700    tabs: {
2701        all:        'Alle',
2702        regional:   'Regional',
2703        global:     'Global',
2704        mos:        'MOS',
2705        multimodel: 'Multi',
2706        ai:         'KI',
2707        other:      'Weitere'
2708    },
2709    groups: {
2710        regional:   { title: 'Regionale Modelle', color: '#2F8B78', colorDark: '#3FB29A' },
2711        global:     { title: 'Globale Modelle',   color: '#C8641E', colorDark: '#F58132' },
2712        mos:        { title: 'MOS',               color: '#0080D3', colorDark: '#0080D3' },
2713        multimodel: { title: 'Multimodell',       color: '#D54587', colorDark: '#D54587' },
2714        ai:         { title: 'KI-Modelle',        color: '#A062C2', colorDark: '#A062C2' }
2715    }
2716};
2717
2718var xlT = function (key) {
2719    var i18n = (typeof xlLegendI18n !== 'undefined' && xlLegendI18n) ? xlLegendI18n : {};
2720    return i18n[key] || xlLegendFallback[key] || key;
2721};
2722
2723var xlGroupMeta = function (g) {
2724    var i18n = (typeof xlLegendI18n !== 'undefined' && xlLegendI18n) ? xlLegendI18n : {};
2725    var fromServer = (i18n.groups || {})[g];
2726    var fallback = xlLegendFallback.groups[g] || { title: g, color: '#808080' };
2727    var meta = (fromServer && fromServer.title) ? fromServer : fallback;
2728    // Im Darkmode die aufgehellte Variante als wirksame Farbe liefern, damit
2729    // die Aufrufer (Gruppenpunkt in der Legende) nichts davon wissen muessen.
2730    // `colorDark` kann beim Server fehlen (aelterer Cache-Stand) - dann greift
2731    // der lokale Fallback, sonst bliebe der Punkt im Darkmode zu dunkel.
2732    if (xlIsDark()) {
2733        var dark = (fromServer && fromServer.colorDark) || fallback.colorDark;
2734        if (dark) { meta = { title: meta.title, color: dark, colorDark: dark }; }
2735    }
2736    return meta;
2737};
2738
2739var xlTabLabel = function (tabId) {
2740    var i18n = (typeof xlLegendI18n !== 'undefined' && xlLegendI18n) ? xlLegendI18n : {};
2741    var fromServer = (i18n.tabs || {})[tabId];
2742    return fromServer || xlLegendFallback.tabs[tabId] || tabId;
2743};
2744
2745/** Aktiver Reiter ('' = alle zugeklappt). Ueberlebt Seitenwechsel. */
2746var xlLoadTab = function () {
2747    if (xlActiveTab === null) {
2748        var stored = null;
2749        try { stored = localStorage.getItem(XL_TAB_KEY); } catch (e) {}
2750        // Default ist bewusst zugeklappt - die Modell-Liste ist lang und
2751        // soll die Seite nicht von vornherein aufblaehen.
2752        xlActiveTab = (stored && xlTabOrder.indexOf(stored) !== -1) ? stored : '';
2753    }
2754    return xlActiveTab;
2755};
2756
2757var xlSetTab = function (tabId) {
2758    // Erneuter Klick auf den offenen Reiter klappt ihn wieder zu.
2759    xlActiveTab = (tabId === xlActiveTab || xlTabOrder.indexOf(tabId) === -1) ? '' : tabId;
2760    try { localStorage.setItem(XL_TAB_KEY, xlActiveTab); } catch (e) {}
2761};
2762
2763/** Serien-Metadaten robust auslesen (userOptions überlebt Updates, options nicht immer). */
2764var xlSeriesParam = function (s) {
2765    var o = (s && (s.userOptions || s.options)) || {};
2766    return o.param || null;
2767};
2768var xlSeriesGroup = function (s) {
2769    var o = (s && (s.userOptions || s.options)) || {};
2770    return o.group || 'global';
2771};
2772
2773/**
2774 * Nur die XL-Multimodell-Charts. `Highcharts.charts` ist global und enthält
2775 * auch Kompakt-/14-Tage-/Ensemble-Graphen - die dürfen wir NIE anfassen.
2776 * Erkennungsmerkmal: mindestens eine Serie trägt ein `param`.
2777 */
2778var xlCharts = function () {
2779    if (typeof Highcharts === 'undefined' || !Highcharts.charts) { return []; }
2780    return Highcharts.charts.filter(function (c) {
2781        return c && c.series && c.series.length && c.series.some(xlSeriesParam);
2782    });
2783};
2784
2785/** Alle bekannten Params einer Gruppe (über alle XL-Charts hinweg). */
2786var xlParamsOfGroup = function (g) {
2787    var out = {};
2788    xlCharts().forEach(function (c) {
2789        c.series.forEach(function (s) {
2790            var p = xlSeriesParam(s);
2791            if (p && xlSeriesGroup(s) === g) { out[p] = true; }
2792        });
2793    });
2794    return Object.keys(out);
2795};
2796
2797/** Gruppen -> Serien (erste Fundstelle je param) für das Rendern der Legende. */
2798var xlCollectGroups = function () {
2799    var groups = {};
2800    var seen = {};
2801    xlCharts().forEach(function (c) {
2802        c.series.forEach(function (s) {
2803            var p = xlSeriesParam(s);
2804            if (!p || seen[p]) { return; }
2805            seen[p] = true;
2806            var g = xlSeriesGroup(s);
2807            if (!groups[g]) { groups[g] = []; }
2808            groups[g].push(s);
2809        });
2810    });
2811    return groups;
2812};
2813
2814/**
2815 * Zustand laden. Defaults werden fortlaufend aus den Serien nachgezogen,
2816 * damit auch Modelle korrekt behandelt werden, die erst in einem später
2817 * nachgeladenen Tab/Chart auftauchen.
2818 */
2819var xlLoadSelection = function () {
2820    var fresh = [];
2821    xlCharts().forEach(function (c) {
2822        c.series.forEach(function (s) {
2823            var p = xlSeriesParam(s);
2824            if (p && xlDefaults[p] === undefined) {
2825                // Wird immer VOR dem ersten xlApplySelection() aufgerufen,
2826                // s.visible entspricht hier also noch dem Server-Default.
2827                xlDefaults[p] = s.visible !== false;
2828                fresh.push(p);
2829            }
2830        });
2831    });
2832
2833    var stored = {};
2834    try { stored = JSON.parse(localStorage.getItem(XL_SEL_KEY) || '{}'); } catch (e) { stored = {}; }
2835
2836    if (!xlSelection) {
2837        xlSelection = {};
2838        Object.keys(xlDefaults).forEach(function (p) {
2839            xlSelection[p] = (typeof stored[p] === 'boolean') ? stored[p] : xlDefaults[p];
2840        });
2841    } else {
2842        // Neu aufgetauchte Modelle ergänzen, bestehende Auswahl nicht anfassen.
2843        fresh.forEach(function (p) {
2844            if (xlSelection[p] === undefined) {
2845                xlSelection[p] = (typeof stored[p] === 'boolean') ? stored[p] : xlDefaults[p];
2846            }
2847        });
2848    }
2849    return xlSelection;
2850};
2851
2852/**
2853 * Zentraler Schreibpfad: Patch anwenden -> Guard -> persistieren ->
2854 * Charts spiegeln (inkl. redraw) -> Legenden neu rendern.
2855 * `patch` ist eine Map `param -> bool`; null bedeutet "nur spiegeln".
2856 */
2857var xlApplySelection = function (patch) {
2858    var sel = xlLoadSelection();
2859
2860    if (patch) {
2861        Object.keys(patch).forEach(function (p) {
2862            if (sel[p] !== undefined) { sel[p] = !!patch[p]; }
2863        });
2864    }
2865
2866    // Guard: niemals alles ausblenden -> auf Server-Default zurückfallen.
2867    var anyVisible = Object.keys(sel).some(function (p) { return sel[p]; });
2868    if (!anyVisible) {
2869        Object.keys(sel).forEach(function (p) { sel[p] = !!xlDefaults[p]; });
2870        if (!Object.keys(sel).some(function (p) { return sel[p]; })) {
2871            Object.keys(sel).forEach(function (p) { sel[p] = true; });
2872        }
2873    }
2874
2875    try { localStorage.setItem(XL_SEL_KEY, JSON.stringify(sel)); } catch (e) {}
2876
2877    xlCharts().forEach(function (c) {
2878        var dirty = false;
2879        c.series.forEach(function (s) {
2880            var p = xlSeriesParam(s);
2881            if (!p || sel[p] === undefined) { return; }   // fremde Serien: nie anfassen
2882            if (s.visible !== sel[p]) {
2883                s.setVisible(sel[p], false);
2884                dirty = true;
2885            }
2886        });
2887        // Median/Band beziehen sich immer auf die AKTUELL sichtbaren Modelle.
2888        if (xlRefreshAggregates(c)) { dirty = true; }
2889        // Ohne redraw bleiben die Y-Achsen auf den ausgeblendeten Extremwerten stehen.
2890        if (dirty) { c.redraw(); }
2891    });
2892
2893    xlRenderLegends();
2894    xlRenderStats();
2895};
2896
2897/**
2898 * Params je Gruppe in EINEM Durchlauf - vermeidet das mehrfache Iterieren
2899 * über alle Charts/Serien beim Rendern.
2900 */
2901var xlParamsByGroup = function () {
2902    var out = {};
2903    var seen = {};
2904    xlCharts().forEach(function (c) {
2905        c.series.forEach(function (s) {
2906            var p = xlSeriesParam(s);
2907            if (!p || seen[p]) { return; }
2908            seen[p] = true;
2909            var g = xlSeriesGroup(s);
2910            if (!out[g]) { out[g] = []; }
2911            out[g].push(p);
2912        });
2913    });
2914    return out;
2915};
2916
2917/** Abgeleiteter Gruppen-Zustand: 'all' | 'none' | 'mixed'. */
2918var xlStateOf = function (params, sel) {
2919    var known = (params || []).filter(function (p) { return sel[p] !== undefined; });
2920    if (!known.length) { return 'none'; }
2921    var on = known.filter(function (p) { return sel[p]; }).length;
2922    if (on === 0) { return 'none'; }
2923    if (on === known.length) { return 'all'; }
2924    return 'mixed';
2925};
2926
2927var xlGroupState = function (g) {
2928    return xlStateOf(xlParamsOfGroup(g), xlLoadSelection());
2929};
2930
2931/* ---------------------------------------------------------------------------
2932 *  Aktionen - liefern jeweils einen absoluten Patch (idempotent).
2933 * ------------------------------------------------------------------------- */
2934var xlActions = {
2935    all: function () {
2936        var p = {};
2937        Object.keys(xlLoadSelection()).forEach(function (k) { p[k] = true; });
2938        return p;
2939    },
2940    only: function (g) {
2941        var p = {};
2942        var inGroup = {};
2943        xlParamsOfGroup(g).forEach(function (k) { inGroup[k] = true; });
2944        Object.keys(xlLoadSelection()).forEach(function (k) { p[k] = !!inGroup[k]; });
2945        return p;
2946    },
2947    groupSet: function (g, on) {
2948        var p = {};
2949        xlParamsOfGroup(g).forEach(function (k) { p[k] = !!on; });
2950        return p;
2951    },
2952    toggle: function (param) {
2953        var p = {};
2954        p[param] = !xlLoadSelection()[param];
2955        return p;
2956    }
2957};
2958
2959/* ---------------------------------------------------------------------------
2960 *  Rendern - baut/aktualisiert ausschliesslich DOM, bindet KEINE Listener.
2961 * ------------------------------------------------------------------------- */
2962var xlEsc = function (str) {
2963    return String(str == null ? '' : str)
2964        .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
2965        .replace(/"/g, '&quot;').replace(/'/g, '&#39;');
2966};
2967
2968/* ---------------------------------------------------------------------------
2969 *  Hover-Hervorhebung: Chip in der Modellauswahl -> zugehoerige Linie betonen.
2970 * ------------------------------------------------------------------------- */
2971
2972/** Aktuell hervorgehobener Param (null = kein Hover). */
2973var xlHoverParam = null;
2974/** Restdeckkraft der NICHT gehoverten Modelle (relativ zur Grunddeckkraft). */
2975var XL_HOVER_DIM = 0.22;
2976/** Zusaetzliche Linienstaerke der gehoverten Serie. */
2977var XL_HOVER_LINE_PLUS = 1.5;
2978/** Faktor, um den der gehoverte Balken (Niederschlag) breiter wird. */
2979var XL_HOVER_BAR_SCALE = 2.2;
2980
2981/**
2982 * Saeulenserien haben keine Linienstaerke, die man betonen koennte - dort
2983 * wird stattdessen der Balken verbreitert (mittig, damit er ueber dem
2984 * gleichen Zeitpunkt stehen bleibt).
2985 *
2986 * Die Ausgangsmasse kommen aus `shapeArgs`, das Highcharts bei jedem Redraw
2987 * neu berechnet - dadurch kann kein veralteter Cachewert die Balken nach
2988 * einem Resize verzerren.
2989 */
2990var xlColumnEmphasis = function (s, on) {
2991    if (!s || !s.points) { return; }
2992
2993    // Der verbreiterte Balken ueberlappt die Nachbarn. Damit er nicht unter
2994    // spaeter gezeichneten Serien verschwindet, wandert die Gruppe im DOM
2995    // nach vorn - die Ausgangsposition wird gemerkt und exakt
2996    // wiederhergestellt, damit die Zeichenreihenfolge unveraendert bleibt.
2997    var el = s.group && s.group.element;
2998    if (el && el.parentNode) {
2999        if (on) {
3000            if (!s.xlDomAnchor) {
3001                s.xlDomAnchor = { parent: el.parentNode, next: el.nextSibling };
3002                el.parentNode.appendChild(el);
3003            }
3004        } else if (s.xlDomAnchor) {
3005            var a = s.xlDomAnchor;
3006            s.xlDomAnchor = null;
3007            if (a.parent === el.parentNode) {
3008                var next = (a.next && a.next.parentNode === a.parent) ? a.next : null;
3009                a.parent.insertBefore(el, next);
3010            }
3011        }
3012    }
3013
3014    s.points.forEach(function (pt) {
3015        var g = pt && pt.graphic;
3016        var sa = pt && pt.shapeArgs;
3017        if (!g || !sa || !sa.width) { return; }
3018        if (!on) {
3019            g.attr({ width: sa.width, x: sa.x });
3020            return;
3021        }
3022        // Sehr schmale Balken (lange Zeitraeume) wuerden rein multiplikativ
3023        // kaum sichtbar wachsen - daher zusaetzlich ein absoluter Zuschlag.
3024        var w = Math.max(sa.width * XL_HOVER_BAR_SCALE, sa.width + 3);
3025        g.attr({ width: w, x: sa.x - (w - sa.width) / 2 });
3026    });
3027};
3028
3029/**
3030 * Hebt EIN Modell in allen XL-Charts hervor; `null` stellt den Normalzustand
3031 * wieder her.
3032 *
3033 * Bewusst ueber die SVG-Attribute statt ueber `series.update()`:
3034 * Letzteres wuerde die Serie neu aufbauen und einen Redraw ausloesen - bei
3035 * ~15 Serien x 4 Charts waere das bei jeder Mausbewegung viel zu teuer.
3036 * Das Unsicherheitsband bleibt als Kontext stehen, die Medianlinie wird
3037 * mitgedimmt, damit sie das hervorgehobene Modell nicht ueberstrahlt.
3038 */
3039var xlHighlight = function (param) {
3040    if (xlHoverParam === param) { return; }
3041    xlHoverParam = param;
3042
3043    xlCharts().forEach(function (c) {
3044        (c.series || []).forEach(function (s) {
3045            var p = xlSeriesParam(s);
3046            var o = (s.userOptions || s.options) || {};
3047
3048            // Die Medianlinie ist die kraeftigste Linie im Chart und wuerde
3049            // das hervorgehobene Modell sonst ueberstrahlen - sie wird
3050            // mitgedimmt. Das Band bleibt als Kontext stehen.
3051            if (!p && o.xlRole === 'median' && s.visible && s.group) {
3052                s.group.attr({ opacity: (param === null) ? 1 : XL_HOVER_DIM });
3053                if (s.markerGroup) { s.markerGroup.attr({ opacity: (param === null) ? 1 : XL_HOVER_DIM }); }
3054                return;
3055            }
3056
3057            if (!p || !s.visible || !s.group) { return; }
3058
3059            var baseOpacity = (typeof o.opacity === 'number') ? o.opacity : 1;
3060            var baseWidth = (typeof o.lineWidth === 'number') ? o.lineWidth : 2;
3061            var isHovered = (param !== null && p === param);
3062
3063            var opacity = baseOpacity;
3064            if (param !== null) {
3065                opacity = isHovered ? 1 : (baseOpacity * XL_HOVER_DIM);
3066            }
3067
3068            s.group.attr({ opacity: opacity });
3069            if (s.markerGroup) { s.markerGroup.attr({ opacity: opacity }); }
3070            // Saeulenserien (Niederschlag) haben keinen `graph`.
3071            if (s.graph) {
3072                s.graph.attr({ 'stroke-width': isHovered ? (baseWidth + XL_HOVER_LINE_PLUS) : baseWidth });
3073            } else if (s.type === 'column') {
3074                xlColumnEmphasis(s, isHovered);
3075            }
3076        });
3077    });
3078};
3079
3080var xlRenderLegends = function () {
3081    var legends = document.querySelectorAll('.xl-legend');
3082    if (!legends.length) { return; }
3083
3084    // Das Neuschreiben der Chips laesst kein `mouseout` mehr feuern - der
3085    // Hover-Zustand muss deshalb hier zurueckgesetzt werden.
3086    xlHighlight(null);
3087
3088    var sel = xlLoadSelection();
3089    var groups = xlCollectGroups();
3090    var paramsByGroup = xlParamsByGroup();
3091    if (!Object.keys(sel).length) { return; }
3092
3093    // Gruppenzustände einmal vorberechnen (statt pro Gruppe erneut alle
3094    // Charts zu durchlaufen).
3095    var states = {};
3096    Object.keys(paramsByGroup).forEach(function (g) {
3097        states[g] = xlStateOf(paramsByGroup[g], sel);
3098    });
3099    var visibleGroups = Object.keys(states).filter(function (g) {
3100        return states[g] !== 'none';
3101    });
3102
3103    var allOn = Object.keys(sel).every(function (p) { return sel[p]; });
3104    var totalCount = Object.keys(sel).length;
3105    var visibleCount = Object.keys(sel).filter(function (p) { return sel[p]; }).length;
3106
3107    // Bekannte Gruppen in fester Reihenfolge, unbekannte hinten anhängen.
3108    var order = xlGroupOrder.slice();
3109    Object.keys(groups).forEach(function (g) {
3110        if (order.indexOf(g) === -1) { order.push(g); }
3111    });
3112    var presentGroups = order.filter(function (g) {
3113        return groups[g] && groups[g].length;
3114    });
3115
3116    // Reiter nur anbieten, wenn sie tatsaechlich Gruppen enthalten.
3117    var tabGroups = {};
3118    presentGroups.forEach(function (g) {
3119        var t = xlTabOf(g);
3120        if (!tabGroups[t]) { tabGroups[t] = []; }
3121        tabGroups[t].push(g);
3122    });
3123    tabGroups.all = presentGroups.slice();
3124
3125    var tabs = xlTabOrder.filter(function (t) {
3126        return tabGroups[t] && tabGroups[t].length;
3127    });
3128    // Ein einzelner Sachgruppen-Reiter neben "Alle" waere redundant.
3129    if (tabs.length <= 2) { tabs = ['all']; }
3130
3131    // '' bedeutet zugeklappt und ist der Startzustand.
3132    var activeTab = xlLoadTab();
3133    if (activeTab && tabs.indexOf(activeTab) === -1) { activeTab = ''; xlSetTab(''); }
3134
3135    // Modellbezogene Hinweise (z.B. MOS-Standortangaben) liegen als Geschwister
3136    // der Legende im Markup. Sie werden in den Reiter-Inhalt der zugehoerigen
3137    // Gruppe gezogen, damit sie dort stehen, wo das Modell ausgewaehlt wird.
3138    // Das Markup ist in jedem Chart-Tab identisch -> erstes Vorkommen genuegt.
3139    var notes = {};
3140    document.querySelectorAll('.xl-legend-note[data-group]').forEach(function (el) {
3141        var g = el.getAttribute('data-group');
3142        if (g && notes[g] === undefined) { notes[g] = el.innerHTML; }
3143        el.classList.add('is-moved');
3144    });
3145
3146    var html = '';
3147    html += '<div class="xl-legend-global">';
3148    html += '<span class="xl-legend-global-name">' + xlEsc(xlT('title')) + '</span>';
3149    html += '<span class="xl-legend-count' + (allOn ? '' : ' is-reduced') + '">' +
3150            xlEsc(String(xlT('visible')).replace('{visible}', visibleCount).replace('{total}', totalCount)) +
3151            '</span>';
3152    html += '<button type="button" class="xl-legend-global-toggle' + (allOn ? ' is-disabled' : '') + '">' + xlEsc(xlT('all')) + '</button>';
3153    html += '</div>';
3154
3155    // Reiterleiste: filtert ausschliesslich die Chip-Liste, nie den Chart.
3156    // Jeder Reiter ist auf-/zuklappbar; ein Zaehler erscheint nur dort, wo
3157    // tatsaechlich Modelle ausgeblendet sind - so muss man sich nicht durch
3158    // die Reiter klicken, um das zu sehen.
3159    html += '<div class="xl-legend-tabs" role="tablist">';
3160    tabs.forEach(function (t) {
3161        var params = {};
3162        tabGroups[t].forEach(function (g) {
3163            (paramsByGroup[g] || []).forEach(function (p) {
3164                if (sel[p] !== undefined) { params[p] = true; }
3165            });
3166        });
3167        var keys = Object.keys(params);
3168        var on = keys.filter(function (p) { return sel[p]; }).length;
3169        var partial = on < keys.length;
3170        var isActive = (t === activeTab);
3171
3172        html += '<button type="button" class="xl-legend-tab' + (isActive ? ' is-active' : '') + '"' +
3173                ' data-tab="' + xlEsc(t) + '" role="tab" aria-expanded="' + (isActive ? 'true' : 'false') + '">';
3174        html += '<span class="xl-legend-tab-name">' + xlEsc(xlTabLabel(t)) + '</span>';
3175        html += '<span class="xl-legend-tab-count">(' +
3176                (partial ? (on + '/' + keys.length) : keys.length) + ')</span>';
3177        html += '<span class="xl-legend-tab-arrow" aria-hidden="true"></span>';
3178        html += '</button>';
3179    });
3180    html += '</div>';
3181
3182    if (!activeTab) {
3183        legends.forEach(function (el) {
3184            if (el.innerHTML !== html) { el.innerHTML = html; }
3185        });
3186        return;
3187    }
3188
3189    html += '<div class="xl-legend-groups">';
3190
3191    presentGroups.forEach(function (g) {
3192        // Reiterfilter: nur die Gruppen des aktiven Reiters rendern.
3193        if (tabGroups[activeTab].indexOf(g) === -1) { return; }
3194
3195        var series = groups[g];
3196        var meta = xlGroupMeta(g);
3197        var state = states[g] || 'none';
3198        // Einzige Gruppe mit sichtbaren Modellen -> "Alle ausblenden" würde
3199        // den Graphen leeren und ist daher gesperrt.
3200        var soloGroup = state !== 'none' && visibleGroups.length === 1;
3201
3202        html += '<div class="xl-legend-group is-' + state + '" data-group="' + xlEsc(g) + '">';
3203        html += '<div class="xl-legend-group-head">';
3204        html += '<span class="xl-legend-group-dot" style="background:' + xlEsc(meta.color || '#808080') + '"></span>';
3205        html += '<span class="xl-legend-group-name">' + xlEsc(meta.title || g) + '</span>';
3206        // "Nur diese Gruppe" ist sinnlos, wenn die Gruppe schon exklusiv sichtbar ist.
3207        html += '<button type="button" class="xl-legend-group-only' + ((state === 'all' && soloGroup) ? ' is-disabled' : '') + '">' + xlEsc(xlT('only')) + '</button>';
3208        if (state === 'none') {
3209            html += '<button type="button" class="xl-legend-group-toggle" data-on="1">' + xlEsc(xlT('show')) + '</button>';
3210        } else {
3211            // Ausblenden nur erlauben, wenn danach noch eine andere Gruppe sichtbar bleibt.
3212            html += '<button type="button" class="xl-legend-group-toggle' + (soloGroup ? ' is-disabled' : '') + '" data-on="0">' + xlEsc(xlT('hide')) + '</button>';
3213        }
3214        html += '</div>';
3215
3216        html += '<div class="xl-legend-items">';
3217        series.forEach(function (s) {
3218            var p = xlSeriesParam(s);
3219            if (!p || sel[p] === undefined) { return; }
3220            var o = s.userOptions || s.options || {};
3221            var run = o.run || '';
3222            var tip = (o.longname || s.name || p) + (run ? ' \u2014 ' + run : '');
3223            html += '<button type="button" class="xl-legend-item' + (sel[p] ? '' : ' is-hidden') + '"' +
3224                    ' data-param="' + xlEsc(p) + '"' +
3225                    ' aria-pressed="' + (sel[p] ? 'true' : 'false') + '"' +
3226                    ' title="' + xlEsc(tip) + '">';
3227            html += '<span class="xl-legend-swatch" style="background:' + xlEsc(s.color || o.color || '#888888') + '"></span>';
3228            html += '<span class="xl-legend-name">' + xlEsc(s.name || p) + '</span>';
3229            html += '</button>';
3230        });
3231        html += '</div>';
3232        if (notes[g]) {
3233            html += '<div class="xl-legend-group-note">' + notes[g] + '</div>';
3234        }
3235        html += '</div>';
3236    });
3237
3238    html += '</div>';
3239
3240    // Identisches Markup für alle Legenden - der Zustand ist global.
3241    legends.forEach(function (el) {
3242        if (el.innerHTML !== html) { el.innerHTML = html; }
3243    });
3244};
3245
3246/**
3247 * Einstiegspunkt: nach jedem (Neu-)Aufbau der Charts aufrufen.
3248 * Spiegelt den gespeicherten Zustand auf alle Charts und rendert die Legenden.
3249 */
3250var buildXlLegends = function () {
3251    if (!document.querySelector('.xl-legend')) { return; }
3252    xlLoadSelection();
3253    xlApplySelection(null);
3254
3255    if (!xlBound) {
3256        xlBound = true;
3257
3258        // Tabwechsel: Highcharts kennt die Grösse eines versteckten Charts
3259        // nicht, deshalb nach dem Einblenden Zustand + Legende nachziehen.
3260        $(document).on('shown.bs.tab', '.graphtab', function () {
3261            setTimeout(function () {
3262                if (document.querySelector('.xl-legend')) {
3263                    xlApplySelection(null);
3264                }
3265            }, 50);
3266        });
3267
3268        // EIN delegierter Listener auf document - übersteht jedes innerHTML
3269        // und jeden Tabwechsel, kann also nicht mehr mehrfach binden.
3270        // `mouseover` (nicht `mouseenter`) blubbert bis zum document hoch und
3271        // feuert auch ausserhalb der Legende - ein separates `mouseout`
3272        // braucht es deshalb nicht: jede Bewegung neben einen Chip raeumt auf.
3273        document.addEventListener('mouseover', function (e) {
3274            var item = e.target.closest ? e.target.closest('.xl-legend-item') : null;
3275            // Ausgeblendete Modelle haben keine Linie, die man betonen koennte.
3276            if (item && !item.classList.contains('is-hidden')) {
3277                xlHighlight(item.getAttribute('data-param'));
3278            } else if (xlHoverParam !== null) {
3279                xlHighlight(null);
3280            }
3281        });
3282
3283        document.addEventListener('click', function (e) {
3284            var root = e.target.closest ? e.target.closest('.xl-legend') : null;
3285            if (!root) { return; }
3286            if (e.target.closest('.is-disabled')) { return; }
3287
3288            var item = e.target.closest('.xl-legend-item');
3289            if (item) {
3290                xlApplySelection(xlActions.toggle(item.getAttribute('data-param')));
3291                return;
3292            }
3293            // Reiterwechsel ist ein reiner Ansichtswechsel: NICHT ueber
3294            // xlApplySelection laufen lassen, sonst wuerden alle Charts
3295            // unnoetig neu gezeichnet.
3296            var tab = e.target.closest('.xl-legend-tab');
3297            if (tab) {
3298                xlSetTab(tab.getAttribute('data-tab'));
3299                xlRenderLegends();
3300                return;
3301            }
3302            if (e.target.closest('.xl-legend-global-toggle')) {
3303                xlApplySelection(xlActions.all());
3304                return;
3305            }
3306            var grpEl = e.target.closest('.xl-legend-group');
3307            if (!grpEl) { return; }
3308            var g = grpEl.getAttribute('data-group');
3309            if (e.target.closest('.xl-legend-group-only')) {
3310                xlApplySelection(xlActions.only(g));
3311                return;
3312            }
3313            var toggle = e.target.closest('.xl-legend-group-toggle');
3314            if (toggle) {
3315                xlApplySelection(xlActions.groupSet(g, toggle.getAttribute('data-on') === '1'));
3316            }
3317        });
3318    }
3319};
3320
3321/**
3322 * Statistikzeile unter dem Plot: erklaert die drei visuellen Ebenen und
3323 * verdichtet die Kernaussage ("N Modelle, Median X, Spannweite Y-Z").
3324 * Wird aus den bereits berechneten Aggregatserien gespeist - keine
3325 * zusaetzliche Statistik, keine zusaetzlichen Daten.
3326 */
3327var xlRenderStats = function () {
3328    var nodes = document.querySelectorAll('.xl-stats');
3329    if (!nodes.length || typeof Highcharts === 'undefined') { return; }
3330
3331    Array.prototype.forEach.call(nodes, function (el) {
3332        var id = el.getAttribute('data-chart');
3333        var holder = id ? document.getElementById(id) : null;
3334        var chart = (holder && $(holder).highcharts) ? $(holder).highcharts() : null;
3335        if (!chart || !chart.series) { el.innerHTML = ''; return; }
3336
3337        var ttOpts = (chart.options && chart.options.tooltip) || {};
3338        var unit = (ttOpts.valueSuffix || '').trim();
3339        var digits = (typeof ttOpts.xlDigits === 'number') ? ttOpts.xlDigits : 1;
3340        var nf = function (v) { return Highcharts.numberFormat(v, digits); };
3341
3342        var models = chart.series.filter(function (s) { return xlSeriesParam(s) && s.visible; });
3343        var median = null;
3344        var band = null;
3345        chart.series.forEach(function (s) {
3346            var role = xlSeriesRole(s);
3347            if (role === 'median') { median = s; }
3348            else if (role === 'band') { band = s; }
3349        });
3350
3351        var html = '<div class="xl-stats-keys">';
3352        html += '<span class="xl-stats-key">' +
3353                '<span class="xl-stats-swatch xl-stats-swatch-models"></span>' +
3354                '<span class="xl-stats-label">' + xlEsc(xlStatsT('models')) + '</span></span>';
3355
3356        if (median && median.visible) {
3357            html += '<span class="xl-stats-key">' +
3358                    '<span class="xl-stats-swatch xl-stats-swatch-median" style="background:' +
3359                    xlEsc(median.color) + '"></span>' +
3360                    '<span class="xl-stats-label">' + xlEsc(xlStatsT('median')) + '</span></span>';
3361        }
3362        if (band && band.visible) {
3363            html += '<span class="xl-stats-key">' +
3364                    '<span class="xl-stats-swatch xl-stats-swatch-band" style="background:' +
3365                    xlEsc(band.color) + '"></span>' +
3366                    '<span class="xl-stats-label">' + xlEsc(xlStatsT('band')) +
3367                    ' <span class="xl-stats-sub">(' + xlEsc(xlStatsT('bandhint')) + ')</span></span></span>';
3368        }
3369        html += '</div>';
3370
3371        // Kennzahlen (Modellanzahl / Median / Spannweite) vorerst ausgeblendet:
3372        // Die Modellanzahl steht bereits neben der Ueberschrift "Modellauswahl",
3373        // der Median ist als Linie im Chart erkennbar. Bei Bedarf reaktivieren.
3374        /*
3375        var vals = [];
3376        if (median && median.visible && median.type !== 'column') {
3377            xlRawPoints(median).forEach(function (p) {
3378                var y = Array.isArray(p) ? p[1] : p.y;
3379                if (typeof y === 'number' && isFinite(y)) { vals.push(y); }
3380            });
3381        }
3382        if (vals.length) {
3383            var sorted = vals.slice().sort(function (a, b) { return a - b; });
3384            html += '<div class="xl-stats-figures">' +
3385                    '<b>' + models.length + ' ' + xlEsc(xlStatsT('count')) + '</b>' +
3386                    '<span class="xl-stats-sep">|</span>' +
3387                    xlEsc(xlStatsT('median')) + ' ' + nf(xlQuantile(sorted, 0.5)) + ' ' + xlEsc(unit) +
3388                    '<span class="xl-stats-sep">|</span>' +
3389                    xlEsc(xlStatsT('range')) + ' ' + nf(sorted[0]) + ' – ' + nf(sorted[sorted.length - 1]) + ' ' + xlEsc(unit) +
3390                    '</div>';
3391        }
3392        */
3393
3394        // Stattdessen steht hier der Hinweis zur Zeitzone - er gehoert
3395        // inhaltlich zur Zeitachse direkt darueber.
3396        var xlStats18n = (typeof xlLegendI18n !== 'undefined' && xlLegendI18n && xlLegendI18n.stats) || {};
3397        var tz = xlStats18n.timezone || '';
3398        var tzShort = xlStats18n.timezoneshort || tz;
3399        if (tz) {
3400            html += '<div class="xl-stats-timezone">' +
3401                    '<span class="out-xs">' + xlEsc(tz) + '</span>' +
3402                    '<span class="in-xs">' + xlEsc(tzShort) + '</span>' +
3403                    '</div>';
3404        }
3405
3406        if (el.innerHTML !== html) { el.innerHTML = html; }
3407    });
3408};
3409
3410var drawSingleArrow = function (speed) {
3411
3412    if (speed === 0) {
3413        return [];
3414    }
3415
3416    var length = speed < 100 ? 10 : 11
3417    var triangleOffset = speed < 100 ? 4 : 3;
3418    var lineOffset = speed < 150 ? 3 : 2;
3419
3420    var path = [
3421        'M', 0, 7, // base of arrow
3422        'L', -1.5, 7,
3423        0, length,
3424        1.5, 7,
3425        0, 7,
3426        0, length * -1 // top
3427    ];
3428
3429    var triangleCount = Math.floor(speed / 50);
3430    var longLineCount = Math.floor((speed % 50) / 10);
3431    var shortLineCount = Math.floor((speed % 10) / 5);
3432
3433    var offset = length * -1;
3434
3435    for (var i = 0; i < triangleCount; i++) {
3436        path.push('M', 0, offset, 'L', 7, offset, 'L', 0, offset + 2); // triangle
3437        offset += triangleOffset;
3438    }
3439
3440    for (var i = 0; i < longLineCount; i++) {
3441        path.push('M', 0, offset, 'L', 7, offset); // long line
3442        offset += lineOffset;
3443    }
3444
3445    for (var i = 0; i < shortLineCount; i++) {
3446        path.push('M', 0, offset, 'L', 4, offset); // short line
3447        offset += 3;
3448    }
3449
3450    return path;
3451};
3452
3453var highcharts_arrows=[];
3454var highcharts_plottype;
3455
3456var drawWindArrowsVH = function (chart, plot) {
3457    if (typeof vhstation_wind_data_dir === 'undefined') return;
3458    if (vhstation_wind_data_dir.length == 0) return;
3459
3460    $.each(highcharts_arrows, function (i, arrow) { arrow.destroy(); });
3461
3462    highcharts_arrows=[];
3463    highcharts_plottype=plot;
3464
3465    var lastX = false;
3466
3467    $.each(chart.series[0].data, function (i, point) {
3468
3469        var arrow, x, y;
3470        // Draw the wind arrows
3471        x = point.plotX + chart.plotLeft;
3472        y = chart.plotTop + chart.plotHeight + 20;
3473
3474        if(vhstation_wind_data_ws[i] == 0)
3475            return;
3476
3477        arrow = chart.renderer.path(
3478            drawSingleArrow(vhstation_wind_data_ws[i])
3479        ).attr({
3480            rotation: vhstation_wind_data_dir[i],
3481            translateX: x, // rotation center
3482            translateY: y // rotation center
3483        });
3484        arrow.attr({
3485            stroke: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black',
3486            'stroke-width': 1.5,
3487            zIndex: 5
3488        });
3489        arrow.add();
3490
3491        //Check if arrow should be drawn
3492        if(highcharts_arrows.length > 0 && lastX !== false) {
3493
3494            var lastDrawnIndex = highcharts_arrows.length-1;
3495
3496            var lastWidth = highcharts_arrows[lastDrawnIndex].getBBox().width;
3497            var nowWidth = arrow.getBBox().width;
3498
3499            var combinedWidth = lastWidth / 2 + nowWidth / 2;
3500
3501            if(15 > point.plotX - lastX) {
3502                arrow.destroy();
3503                return;
3504            }
3505
3506        }
3507
3508        highcharts_arrows.push(arrow);
3509        lastX = point.plotX;
3510
3511    });
3512    
3513};
3514
3515
3516var drawWindArrows = function (chart, plot) {
3517    if (typeof hccompact_data_direction === 'undefined')  return;
3518
3519	$.each(highcharts_arrows, function (i, arrow) { arrow.destroy(); });
3520	highcharts_arrows=[];
3521	highcharts_plottype=plot;
3522
3523    var lastX = false;
3524
3525	$.each(chart.series[0].data, function (i, point) {
3526        var arrow, x, y;
3527
3528        
3529        // Draw the wind arrows
3530        x = point.plotX + chart.plotLeft;
3531        y = 124;
3532        if(highcharts_plottype=="landing") { y = 278; }
3533
3534        //console.log({compact_interval: compact_interval, h_utc: h_utc, i: i, speed: hccompact_data_windarr[i], first_series_obj: chart.series[0].data[i]});
3535
3536        if(hccompact_data_windarr[i] == 0)
3537            return;
3538
3539        arrow = chart.renderer.path(
3540            drawSingleArrow(hccompact_data_windarr[i])
3541        ).attr({
3542            rotation: hccompact_data_direction[i],
3543            translateX: x, // rotation center
3544            translateY: y // rotation center
3545        });
3546        arrow.attr({
3547            stroke: (Highcharts.theme && Highcharts.theme.contrastTextColor) ||cssVar('--hc-windArrows'),
3548            'stroke-width': 1.5,
3549            zIndex: 5
3550        });
3551        arrow.add();
3552
3553        //Check if arrow should be drawn
3554        if(highcharts_arrows.length > 0 && lastX !== false) {
3555
3556            var lastDrawnIndex = highcharts_arrows.length-1;
3557
3558            var lastWidth = highcharts_arrows[lastDrawnIndex].getBBox().width;
3559            var nowWidth = arrow.getBBox().width;
3560
3561            var combinedWidth = lastWidth / 2 + nowWidth / 2;
3562
3563            if(15 > point.plotX - lastX) {
3564                arrow.destroy();
3565                return;
3566            }
3567
3568            //console.log({lastBoundingBox: { x: lastX, width: highcharts_arrows[lastDrawnIndex].getBBox().width }, nowBoundingBox: { x: point.plotX, width: arrow.getBBox().width }});
3569
3570        }
3571
3572        highcharts_arrows.push(arrow);
3573        lastX = point.plotX;
3574
3575    });
3576};
3577
3578var highcharts_blocks=[];
3579var drawBlocksForWindArrows = function (chart) {
3580	$.each(highcharts_blocks, function (i, line) {line.destroy();});
3581	highcharts_blocks=[];
3582
3583    var xAxis = chart.xAxis[0],x,pos,max,isLong,isLast,i,line;
3584    pos = xAxis.min;
3585    max = xAxis.max;
3586
3587    for (i = 0; pos < max ; pos += 36e5, i += 1) {
3588        // Get the X position
3589        isLast = pos === max + 36e5;
3590        x = Math.round(xAxis.toPixels(pos)-3);
3591
3592        isLong = (i+moment.tz(timezone_id).utcOffset()/60) % compact_interval === 0;
3593        
3594        line=chart.renderer.path(['M', x, chart.plotTop + chart.plotHeight + (isLong ? 0 : 24), 'L', x, chart.plotTop + chart.plotHeight + 24, 'Z'])
3595            .attr({ 'stroke' : chart.options.chart.plotBorderColor, 'stroke-width': 1 });
3596        line.add();
3597        highcharts_blocks.push(line);
3598    }
3599};
3600
3601var highcharts_nightshadows=[];
3602var drawNightShadows=function(chart,plot,variant) {
3603    if(typeof highcharts_nightshadows[plot]!='undefined') {
3604        $.each(highcharts_nightshadows[plot], function (i, symbol) {symbol.destroy();}); 
3605    }
3606    highcharts_nightshadows[plot]=[];
3607
3608    // 'xl': deutlich dezentere Toenung, damit die Nacht nicht mehr als grosser
3609    // grauer Block mit den Datenlinien konkurriert.
3610    var shade = (variant === 'xl')
3611        ? cssVar('--hc-xl-night', '#F4F6F8')
3612        : cssVar('--hc-night_shadows');
3613
3614    var xAxis = chart.xAxis[0];
3615    var x1,x2,y,pos,max,i,h,interval;
3616    
3617    pos  = (xAxis.min)-(xAxis.min)%(24*36e5);
3618    max  = (xAxis.max)+moment.tz(xAxis.max,timezone_id).utcOffset()/60*36e5;
3619    var sunset = 4;
3620    var sunrise = 5;
3621    if (typeof hclanding_sunrise !== 'undefined') {
3622        sunrise = parseInt(hclanding_sunrise);
3623    }
3624    if (typeof hclanding_sunset !== 'undefined') {
3625        sunset = parseInt(hclanding_sunset);
3626    }
3627    for (i = 0; pos <= max+24*36e5; pos += 24*36e5, i += 1) {
3628        // Get the X position
3629        x1 = Math.round(xAxis.toPixels(pos-sunset*36e5-moment.tz(pos-sunset*36e5,timezone_id).utcOffset()/60*36e5));
3630        x2 = Math.round(xAxis.toPixels(pos+sunrise*36e5-moment.tz(pos+sunrise*36e5,timezone_id).utcOffset()/60*36e5));
3631        
3632        if(x1<chart.plotLeft) { x1=chart.plotLeft; }
3633        if(x2>chart.plotWidth+chart.plotLeft) { x2=chart.plotWidth+chart.plotLeft; }
3634        group = chart.renderer.g().attr({
3635        	translateX: x1,
3636        	translateY: chart.plotTop,
3637        	zIndex: 0
3638    	}).add();
3639        //add image
3640    	chart.renderer.rect(0,0,x2-x1,chart.plotHeight,1).attr({
3641        	stroke: shade,
3642        	fill: shade,
3643        	zIndex: 0
3644    	}).add(group);
3645    	highcharts_nightshadows[plot].push(group);
3646    }
3647}
3648
3649var highcharts_intervals=[];
3650var drawIntervals=function(chart,plot, flag, variant) {
3651    if(typeof highcharts_intervals[plot]!=='undefined') {
3652        $.each(highcharts_intervals[plot], function (i, symbol) {symbol.destroy();});
3653    }
3654    highcharts_intervals[plot]=[];
3655
3656    // 'xl': sehr dezente Toenung statt kraeftigem Blau.
3657    var shade = (variant === 'xl')
3658        ? cssVar('--hc-xl-night', '#F4F6F8')
3659        : cssVar('--hc-interval-background');
3660
3661    var xAxis = chart.xAxis[0];
3662    var x1,x2,y,pos,max,i,intervall,len;
3663    if (typeof flag === 'undefined') {
3664        intervall = 12;
3665    }
3666    else {
3667        intervall = parseInt(flag);
3668    }
3669    len=Math.round(intervall/4);
3670
3671    pos  = (xAxis.min)-(xAxis.min)%(24*36e5);
3672    max  = (xAxis.max);
3673    for (i = 0; pos <= max; pos += intervall*36e5, i += 1) {
3674        // Get the X position
3675
3676        if (typeof flag === 'undefined') {
3677            x1 = Math.round(xAxis.toPixels(pos-len*36e5));
3678            x2 = Math.round(xAxis.toPixels(pos+len*36e5));
3679        }
3680        else {
3681            x1 = Math.round(xAxis.toPixels(pos-len*36e5-moment.tz(pos-len*36e5,timezone_id).utcOffset()/60*36e5));
3682            x2 = Math.round(xAxis.toPixels(pos+len*36e5-moment.tz(pos+len*36e5,timezone_id).utcOffset()/60*36e5));
3683        }
3684
3685        if(x1<chart.plotLeft) { x1=chart.plotLeft; }
3686        if(x2>chart.plotWidth+chart.plotLeft) { x2=chart.plotWidth+chart.plotLeft; }
3687        group = chart.renderer.g().attr({
3688        	translateX: x1,
3689        	translateY: chart.plotTop,
3690        	zIndex: 0
3691    	}).add();
3692        //add image
3693    	chart.renderer.rect(0,0,x2-x1,chart.plotHeight,1).attr({
3694        	stroke: shade,
3695        	fill: shade,
3696    	}).add(group);
3697    	highcharts_intervals[plot].push(group);
3698    }
3699}
3700
3701var highcharts_symbols=[];
3702var highcharts_symbols_timestamps=[];
3703var drawWeatherSymbols=function(chart) {
3704	$.each(highcharts_symbols, function (i, symbol) {symbol.destroy();});
3705	highcharts_symbols=[];
3706
3707	if(typeof hccompact_data_symbols == 'undefined') return;
3708    
3709    var lastDrawnIndex = false;
3710    var lastDrawnSevere = false;
3711    var symbolPixelSize = 24;
3712    var severePixelSize = 40;
3713
3714    var pixelTolerance = 5;
3715
3716    var symbolYMargin = 6;
3717    var severeYMargin = 2;
3718
3719    $.each(chart.series[0].data, function (i, point) {
3720        var group;
3721        h=(point.x-hccompact_model_starttime)/36e5; 
3722
3723        highcharts_symbols_timestamps[point.x]=i;
3724
3725        var isSevereSymbol = hccompact_data_symbols[i].search("severe") >= 0;
3726
3727        var pixelSize = isSevereSymbol ? severePixelSize : symbolPixelSize;
3728        var yMargin = isSevereSymbol ? severeYMargin : symbolYMargin;
3729
3730        //Check if pixel space between last drawn symbol and this symbol is enough
3731        if(i !== 0 && lastDrawnIndex !== false) {
3732            if(isSevereSymbol || lastDrawnSevere) {
3733                var pixelDifference = point.plotX - chart.series[0].data[lastDrawnIndex].plotX;
3734
3735                if(isSevereSymbol && !lastDrawnSevere || !isSevereSymbol && lastDrawnSevere) {
3736                    if(pixelDifference < (0.5 * severePixelSize + 0.5 * symbolPixelSize) - pixelTolerance)
3737                        return; 
3738                } else {
3739                    if(pixelDifference < severePixelSize - pixelTolerance)
3740                        return; 
3741                }
3742            } else {
3743                var pixelDifference = point.plotX - chart.series[0].data[lastDrawnIndex].plotX;
3744                if(pixelDifference < symbolPixelSize - pixelTolerance)
3745                    return; 
3746            }
3747        }
3748
3749        //Check if next symbols are severe and therefore this symbol should not be drawn
3750        if(!isSevereSymbol) {
3751            for(var sevIndex = 1; i + sevIndex <= hccompact_data_symbols.length - 1 && typeof chart.series[0].data[i + sevIndex] !== 'undefined' && chart.series[0].data[i + sevIndex].plotX - point.plotX < (0.5 * severePixelSize + 0.5 * symbolPixelSize) - pixelTolerance; sevIndex++) {
3752                if(hccompact_data_symbols[i + sevIndex].search("severe") >= 0) {
3753                    return;
3754                }
3755            }
3756        }
3757
3758        //console.log({plotX: point.plotX, chartLeft: chart.plotLeft, chartWidth: chart.plotWidth });
3759
3760        if(point.plotX - pixelSize / 2 > chart.plotWidth)
3761            return;
3762
3763        if(point.plotX + pixelSize / 2 < 0)
3764            return;
3765
3766        //console.log({pointX: point.plotX, chartLeft: chart.plotLeft});
3767
3768        lastDrawnIndex = i;
3769        lastDrawnSevere = false;
3770
3771        if(isSevereSymbol)
3772            lastDrawnSevere = true;
3773
3774
3775        //Calc symbol y by avg 2 highest points of the actuel and 2 nearest points
3776        var pointYArray = [point.plotY];
3777        var pixelOffsetSum = 0;
3778
3779        for (var iOffset = 1; pixelOffsetSum < pixelSize && iOffset < 200; iOffset++) {
3780
3781            var leftPixelOffset = 0;
3782            var rightPixelOffset = 0;
3783
3784            if(i-iOffset >= 1) {
3785                if(point.plotX - chart.series[0].data[i-iOffset].plotX < pixelSize || iOffset == 1) {
3786                    pointYArray.push(chart.series[0].data[i-iOffset].plotY);
3787                    leftPixelOffset = point.plotX - chart.series[0].data[i-iOffset].plotX;
3788                }
3789            }
3790
3791            if(i+iOffset <= chart.series[0].data.length - 1) {
3792                if(chart.series[0].data[i+iOffset].plotX - point.plotX < pixelSize || iOffset == 1) {
3793                    pointYArray.push(chart.series[0].data[i+iOffset].plotY);
3794                    rightPixelOffset = chart.series[0].data[i+iOffset].plotX - point.plotX;
3795                }
3796            }
3797
3798            if(leftPixelOffset + 0.2 < rightPixelOffset && leftPixelOffset != 0) {
3799                rightPixelOffset = leftPixelOffset;
3800            }
3801
3802            pixelOffsetSum = leftPixelOffset > rightPixelOffset ? leftPixelOffset*2 : rightPixelOffset*2;
3803            
3804        }
3805
3806        pointYArray = pointYArray.sort(function (a, b) {  return a - b;  });
3807
3808        var pointY = 0;
3809        if(pointYArray.length >= 3)
3810            pointY = pointYArray[0] * 0.7 + pointYArray[1] * 0.2 + pointYArray[2] * 0.1;
3811        if(pointYArray.length <= 2)
3812            pointY = pointYArray[0];
3813
3814
3815
3816        if(pointY - yMargin > point.plotY) 
3817            pointY = point.plotY;
3818        
3819
3820        group = chart.renderer.g().attr(
3821            {
3822                translateX: point.plotX + chart.plotLeft - (pixelSize / 2),
3823                translateY: pointY + chart.plotTop - (pixelSize + yMargin),
3824                zIndex: 7
3825            }
3826        ).clip(chart.renderer.clipRect(0, 0, 120, 120)).add();
3827        //add image
3828        chart.renderer.image('/images/symbole/sym_' + hccompact_data_symbols[i] + '.svg', 0, 0, pixelSize, pixelSize).add(group);
3829        //remember group for cleanup during resize
3830
3831        highcharts_symbols.push(group);
3832        
3833    });
3834}
3835
3836var hcsunsums_labels=[];
3837var drawSunshineSums=function(chart) {
3838	$.each(hcsunsums_labels, function (i, symbol) {symbol.destroy();});
3839	hcsunsums_labels=[];
3840	var xAxis = chart.xAxis[0];
3841    
3842	//alert(pos);
3843	var pos;
3844    pos= (xAxis.min)-(xAxis.min)%(24*36e5)+18*36e5;
3845    
3846    var is_this_inside = false;
3847
3848    $.each(hccompact_sunsum, function (i, point) {
3849        var group,x;
3850        
3851
3852        var i_next = i+1;
3853        if(typeof hccompact_sunsum[i_next] === 'undefined')
3854            i_next = false;
3855
3856        // position group
3857        x = Math.round(xAxis.toPixels(point[0]-moment.tz(timezone_id).utcOffset()/60*36e5));
3858        x_next = i_next === false ? false : Math.round(xAxis.toPixels(hccompact_sunsum[i_next][0]-moment.tz(timezone_id).utcOffset()/60*36e5));
3859
3860        var is_next_inside = x_next === false ? false : x_next < chart.plotLeft + chart.plotWidth && x_next > chart.plotLeft;
3861        var is_before_inside = is_this_inside;
3862        is_this_inside = x < chart.plotLeft + chart.plotWidth && x > chart.plotLeft;
3863
3864        // console.log({is_this_inside, is_next_inside});
3865
3866        var summe = Math.round(point[1]*10.)/10.;
3867        var text = summe === 0 ? '0' : Highcharts.numberFormat(summe,1).toString();
3868        var textSize = text.length;
3869        var textWidth = 0;
3870        if(text.indexOf('.') !== -1) {
3871            textSize -= 1;
3872            textWidth += 3.8;
3873        }
3874        textWidth += textSize * 7.5;
3875        
3876        var middle_x_day = false;
3877        if(is_this_inside) {
3878            middle_x_day = x;
3879        }
3880        
3881        if(!is_this_inside && is_next_inside) {
3882            x = Math.round(xAxis.toPixels(point[0]-moment.tz(timezone_id).utcOffset()/60*36e5+12*36e5));
3883            middle_x_day = (x - chart.plotLeft) / 2 + chart.plotLeft;
3884        }
3885        
3886        if(is_before_inside && !is_this_inside) {
3887            x = Math.round(xAxis.toPixels(point[0]-moment.tz(timezone_id).utcOffset()/60*36e5-12*36e5));
3888            var middle_x_day = chart.plotLeft + chart.plotWidth - ((chart.plotLeft + chart.plotWidth) - x) / 2;
3889        }
3890        
3891        if(middle_x_day !== false) {
3892            group = chart.renderer.g().attr({
3893                translateX: middle_x_day - textWidth/2 - 3,
3894                translateY: 10,
3895                zIndex: 6
3896            }).add();
3897            //add image
3898            chart.renderer.label(text).css({ color: cssVar('--color-text') }).add(group);
3899            //remember group for cleanup during resize
3900            hcsunsums_labels.push(group);
3901        }
3902
3903    })
3904}
3905
3906var hcrainsums_labels=[];
3907var drawRainSums=function(chart) {
3908	$.each(hcrainsums_labels, function (i, symbol) {symbol.destroy();});
3909	hcrainsums_labels=[];
3910	var xAxis = chart.xAxis[0];
3911  
3912  var unit = hccompact_units['rain']=="mm" ? 10. : 100.;
3913  var digits = hccompact_units['rain']=="in" ? 2 : 1;
3914
3915	var pos;
3916	pos= (xAxis.min)-(xAxis.min)%(24*36e5)+2*36e5;
3917    //console.log(pos);
3918    
3919    var is_this_inside = false;
3920
3921    $.each(hccompact_rainsum, function (i, point) {
3922        var group,x;
3923        
3924        var i_next = i+1;
3925        if(typeof hccompact_rainsum[i_next] === 'undefined')
3926            i_next = false;
3927
3928        // position group
3929        x = Math.round(xAxis.toPixels(point[0]-moment.tz(timezone_id).utcOffset()/60*36e5));
3930        x_next = i_next === false ? false : Math.round(xAxis.toPixels(hccompact_rainsum[i_next][0]-moment.tz(timezone_id).utcOffset()/60*36e5));
3931
3932        var is_next_inside = x_next === false ? false : x_next < chart.plotLeft + chart.plotWidth && x_next > chart.plotLeft;
3933        var is_before_inside = is_this_inside;
3934        is_this_inside = x < chart.plotLeft + chart.plotWidth && x > chart.plotLeft;
3935
3936        // console.log({is_this_inside, is_next_inside});
3937        var summe = Math.round(point[1]*unit)/unit;
3938        var text = summe === 0 ? '0' : Highcharts.numberFormat(summe,digits).toString();
3939        var textSize = text.length;
3940        var textWidth = 0;
3941        if(text.indexOf('.') !== -1) {
3942            textSize -= 1;
3943            textWidth += 3.8;
3944        }
3945        textWidth += textSize * 7.5;
3946
3947        var middle_x_day = false;
3948        if(is_this_inside) {
3949            middle_x_day = x;
3950        }
3951        
3952        if(!is_this_inside && is_next_inside) {
3953            x = Math.round(xAxis.toPixels(point[0]-moment.tz(timezone_id).utcOffset()/60*36e5+12*36e5));
3954            middle_x_day = (x - chart.plotLeft) / 2 + chart.plotLeft;
3955        }
3956        
3957        if(is_before_inside && !is_this_inside) {
3958            x = Math.round(xAxis.toPixels(point[0]-moment.tz(timezone_id).utcOffset()/60*36e5-12*36e5));
3959            var middle_x_day = chart.plotLeft + chart.plotWidth - ((chart.plotLeft + chart.plotWidth) - x) / 2;
3960        }
3961        
3962        if(middle_x_day !== false) {
3963            group = chart.renderer.g().attr({
3964                translateX: middle_x_day - textWidth/2 - 3,
3965                translateY: 10,
3966                zIndex: 6
3967            }).add();
3968            //add image
3969            chart.renderer.label(text).css({ color: cssVar('--color-text') }).add(group);
3970            //remember group for cleanup during resize
3971            hcrainsums_labels.push(group);
3972        }
3973
3974    })
3975}
3976
3977var hchours_labels=[];
3978hchours_labels[    'temp']=[];
3979hchours_labels[    'xl']=[];
3980hchours_labels[    'xl2']=[];
3981hchours_labels[    'xl3']=[];
3982hchours_labels[     'sun']=[];
3983hchours_labels[    'rain']=[];
3984hchours_labels['pressure']=[];
3985hchours_labels['ensemble']=[];
3986hchours_labels['landing']=[];
3987hchours_labels['obs'] = [];
3988var drawHourlyLabels=function(chart, plot) {
3989        $.each(hchours_labels[plot], function (i, symbol) {symbol.destroy();});
3990	hchours_labels[plot]=[];
3991	var xAxis = chart.xAxis[0];
3992    
3993	var x,y,pos,max,i,h,interval;
3994    pos  = (xAxis.min)-(Math.abs(xAxis.min))%(24*36e5);
3995    max  = (xAxis.max)+moment.tz(xAxis.max,timezone_id).utcOffset()/60*36e5;
3996
3997	if(chart.plotWidth<260 && plot!='obs')return;
3998	if(chart.plotWidth<300 && displayLanguage()=="EN" && plot!='obs')return;
3999        if(chart.plotWidth<420 && plot==='xl2')return;
4000
4001	if(typeof hccompact_superhd != 'undefined'){
4002		interval=3
4003    } else {
4004    	if     (chart.plotWidth<540)interval=6;
4005    	else 				   		interval=3;
4006    }
4007
4008    var labelInterval = 3*36e5;
4009    var maxX = chart.plotWidth + 69;
4010    var minX = 69;
4011    var pixelsPerHour = chart.plotWidth / ((max - xAxis.min) / 1000 / (60*60))
4012    if (pixelsPerHour < 5) { labelInterval = 6*36e5; }
4013
4014    if(plot==    'temp')y=18;
4015    if(plot==     'sun')y=53;
4016    if(plot==    'rain')y=73;
4017    if(plot=='pressure')y=113;
4018    if(plot=='landing')minX=chart.plotLeft;
4019    if(plot=='ensemble'){
4020        y=18;
4021        var interval = 1;
4022        var labelInterval = 1*36e5;
4023        var maxX = chart.plotWidth;
4024        
4025        var timespan = (xAxis.max - xAxis.min) / 36e5;
4026        var labelWidth = 16;
4027        var labelNum = maxX / labelWidth;
4028        minX = chart.plotLeft - labelWidth;
4029
4030        interval = Math.ceil(timespan / labelNum);
4031        if(interval == 2) interval = 3;
4032        if(interval == 4) interval = 6;
4033        if(interval == 5) interval = 6;
4034        if(interval >= 7 && interval <= 11) interval = 12;
4035        labelInterval = interval*36e5;
4036        max += labelInterval;
4037    }
4038    if(plot=='xl') {
4039        y=18;
4040        interval=12;
4041        labelInterval=12*36e5;
4042    }
4043    if(plot=='xl2') {
4044        y=18;
4045        interval=6;
4046        labelInterval=6*36e5;
4047    }
4048    if(plot=='xl3') {
4049        y=18;
4050        interval=24;
4051        labelInterval=24*36e5;
4052    }
4053    if(plot=='obs') {
4054        y=chart.plotHeight+chart.plotTop;
4055        labelInterval = 1*36e5;
4056        interval = 1;
4057        minX = chart.plotLeft;
4058
4059        var min;
4060
4061        if(typeof hc_obs_max != 'undefined')
4062            max = hc_obs_max+moment.tz(hc_obs_max,timezone_id).utcOffset()/60*36e5;
4063
4064        if(chart.plotWidth < 800) {
4065            labelInterval = 2*36e5;
4066            interval = 2;
4067        }
4068        if(chart.plotWidth < 360) {
4069            labelInterval = 3*36e5;
4070            interval = 3;
4071        }
4072
4073        var timespan = (xAxis.max - xAxis.min) / 36e5;
4074        var labelWidth = 16;
4075        var labelNum = chart.plotWidth / labelWidth;
4076        
4077        interval = Math.ceil(timespan / labelNum);
4078        if(interval >= 5) interval = 6;
4079        labelInterval = interval*36e5;
4080
4081    }
4082
4083    if (plot !== 'xl2' && plot !== 'xl3') {
4084        for (i = 0; pos <= max; pos += labelInterval, i += 1) {
4085            // Get the X position
4086            var utcTs = pos-moment.tz(pos, timezone_id).utcOffset()/60*36e5;
4087            x = Math.round(xAxis.toPixels(utcTs));
4088            if((x<maxX || plot=="ensemble") && x>minX){
4089                    group = chart.renderer.g().attr({
4090                        translateX: x-9,
4091                        translateY: y ,
4092                        zIndex: 6
4093                    }).add();
4094                    h=moment(utcTs).tz(timezone_id).hour();
4095                    if(h%interval==0) {
4096                            if(h>9)
4097                                    chart.renderer.label(h).css({'fontSize':'9px','color':cssVar('--color-text')}).add(group);
4098                            else
4099                                    chart.renderer.label('0'+h).css({'fontSize':'9px','color':cssVar('--color-text')}).add(group);
4100                        //remember group for cleanup during resize
4101                            hchours_labels[plot].push(group);
4102                    }
4103            }
4104        }
4105    }
4106    else {
4107        var until = '-';
4108        var poscorr = until.length === 1 ? 18 : poscorr = until.length === 5 ? 26 : 40;
4109        for (i = 0; pos <= max; pos += labelInterval, i += 1) {
4110            // Get the X position
4111            x = Math.round(xAxis.toPixels(pos));
4112            if(x<maxX && x>minX){
4113                    group = chart.renderer.g().attr({
4114                        translateX: x-poscorr,
4115                        translateY: y ,
4116                        zIndex: 6
4117                    }).add();
4118                    h=(pos)%(24*36e5)/36e5;
4119                    if(h%interval==0) {
4120                        h += Math.round(moment.tz(pos, timezone_id).utcOffset()/60,1);
4121                        if (h<=0) { h+=24;}
4122                        if (h>24) {h=h-24;}
4123                        var text = '';
4124                        var start=h-interval; if (start < 0) { start = 24+start; } if (start >= 24) { start = start-24; }
4125                        if (start>9) { text=start + until; } else { text='0' + start + until; }
4126                        if (h>9) { text+=h; } else { text+='0' + h; }
4127                        chart.renderer.label(text).css({'fontSize':'9px','color':cssVar('--color-text')}).add(group);
4128                        //remember group for cleanup during resize
4129                        hchours_labels[plot].push(group);
4130                    }
4131            }
4132        }
4133
4134    }
4135}
4136
4137var hcrainpopgrid_box=[];
4138
4139var nth = function (d) {
4140  if(d>3 && d<21) return 'th'; // thanks kennebec
4141  switch (d % 10) {
4142        case 1:  return "st";
4143        case 2:  return "nd";
4144        case 3:  return "rd";
4145        default: return "th";
4146    }
4147} 
4148
4149var fixLabels = function(chart, plot) {
4150    var labels = $('div.highcharts-xaxis-labels span', chart.container).sort(function(a, b) {
4151        return +parseInt($(a).css('left')) - +parseInt($(b).css('left'));
4152    });
4153    if (plot === 'landing') {
4154        labels.css('margin-left', (parseInt($(labels.get(1)).css('left')) - parseInt($(labels.get(0)).css('left'))) / 2 );
4155    }
4156    else {
4157        labels.css('margin-left', (parseInt($(labels.get(1)).css('left')) - parseInt($(labels.get(0)).css('left'))) / 2 );
4158    }
4159
4160    if(plot=='temp')
4161        labels.css('margin-top',-4);
4162    else if(plot=='ensemble')
4163        labels.css('margin-top', -4);
4164    else
4165        labels.css('margin-top', 5);
4166    
4167
4168    var lastTickPosition = chart.xAxis[0].tickPositions.slice(-1)[0];
4169    var lastTickX = (lastTickPosition - chart.xAxis[0].min) / (chart.xAxis[0].max - chart.xAxis[0].min) * chart.plotWidth + chart.plotLeft;
4170
4171    var xAxisEnd = chart.plotLeft + chart.plotWidth;
4172    //console.log({lastTickX, xAxisEnd});
4173
4174    labels.last().css('left', lastTickX);
4175
4176    if(xAxisEnd - lastTickX < labels.last().width()) {
4177        labels.last().css('opacity', 0);
4178    } else {
4179        labels.last().css('opacity', 1);
4180        var middlePointOffset = ((xAxisEnd - lastTickX) - labels.last(
4180).width()) / 2;
4181        labels.last().css('margin-left', middlePointOffset);
4182    }
4183
4184};
4185
4186
4187var highcharts_windblocks=[];
4188var drawBlocksForWindSymbols = function (chart) {
4189	$.each(highcharts_windblocks, function (i, line) {line.destroy();});
4190	highcharts_windblocks=[];
4191
4192    var xAxis = chart.xAxis[0],x,pos,max,i,faktor,len,img,rain_storm,len2,faktor2;
4193    pos = xAxis.min;
4194    max = xAxis.max;
4195    x = Math.round(xAxis.toPixels(0));
4196    faktor=0.8;
4197    faktor2=0.6;
4198    len = Math.round((xAxis.toPixels(1)-x)*faktor);
4199    len2 = Math.round((xAxis.toPixels(1)-x)*faktor2);
4200    if (len>32) { len=32; faktor=1}
4201    if (len2>18) { len2=18; faktor2=1}
4202    for (i = pos; i <= max ; i += 1) {
4203        x = Math.round(xAxis.toPixels(i));
4204        if (typeof hccompact_data_14days_rsym[i] !== 'undefined' && typeof hccompact_data_14days_tsym[i] !== 'undefined') {
4205            rain_storm=hccompact_data_14days_tsym[i];
4206            if (rain_storm === 'null') {
4207                rain_storm=hccompact_data_14days_rsym[i];
4208            }
4209            if (rain_storm === 'null') {
4210                rain_storm='';
4211            }
4212            if (rain_storm.length>0) {
4213                group = chart.renderer.g().attr({
4214                    translateX: x - Math.round(len/2),
4215                    translateY: chart.plotTop + Math.round(6*faktor),
4216                    zIndex: 5
4217                }).clip(chart.renderer.clipRect(0, 0, 120, 120)).add();
4218                //add image
4219                chart.renderer.image('/images/symbole/'+rain_storm,0,0,len,len).add(group);
4220                //remember group for cleanup during resize
4221                highcharts_windblocks.push(group);
4222            }
4223        }
4224        if (typeof hccompact_data_14days_gusts_raw[i] !== 'undefined') {
4225            img = getWindSymbol(hc_data_14days_gusts_raw[i]);
4226            if (img.length>0) {
4227                var placement = len2+Math.round(6*faktor2);
4228                group = chart.renderer.g().attr({
4229                    translateX: x - Math.round(len2/2),
4230                    translateY: chart.plotTop + chart.plotHeight-placement,
4231                    zIndex: 5
4232                }).clip(chart.renderer.clipRect(0, 0, 120, 120)).add();
4233                //add image
4234                chart.renderer.image('/images/symbole/'+img,0,0,len2,len2).add(group);
4235                //remember group for cleanup during resize
4236                highcharts_windblocks.push(group);
4237            }
4238        }
4239        //highcharts_windblocks.push(line);
4240    }
4241};
4242
4243var highcharts_windblocksV2=[];
4244var drawBlocksForWindSymbolsV2 = function (chart) {
4245	$.each(highcharts_windblocksV2, function (i, line) {line.destroy();});
4246	highcharts_windblocksV2=[];
4247
4248    var xAxis = chart.xAxis[0],x,pos,max,i,faktor,len,img,rain,storm,cloudcoverage,len2,faktor2,len3,faktor3;
4249    pos = xAxis.min;
4250    max = xAxis.max;
4251    x = Math.round(xAxis.toPixels(0));
4252    faktor=0.8;
4253    faktor2=0.6;
4254    faktor3=0.2;
4255    len = Math.round((xAxis.toPixels(1)-x)*faktor);
4256    len2 = Math.round((xAxis.toPixels(1)-x)*faktor2);
4257    len3 = Math.round((xAxis.toPixels(1)-x)*faktor3);
4258    if (len>32) { len=32; faktor=1;}
4259    if (len2>18) { len2=18; faktor2=1;}
4260    if (len3>14) { len2=14; faktor3=1;}
4261    for (i = pos; i <= max ; i += 1) {
4262        x = Math.round(xAxis.toPixels(i));
4263        if (typeof hc_data_14days_gusts_raw[i] !== 'undefined') {
4264            img = getWindSymbol(hc_data_14days_gusts_raw[i]);
4265            if (img.length>0) {
4266                var placement = len2+Math.round(6*faktor2);
4267                group = chart.renderer.g().attr({
4268                    translateX: x - Math.round(len2/2),
4269                    translateY: chart.plotTop + chart.plotHeight-placement,
4270                    zIndex: 5
4271                }).clip(chart.renderer.clipRect(0, 0, 120, 120)).add();
4272                //add image
4273                chart.renderer.image('/images/symbole/'+img,0,0,len2,len2).add(group);
4274                //remember group for cleanup during resize
4275                highcharts_windblocksV2.push(group);
4276            }
4277        }
4278        //highcharts_windblocksV2.push(line);
4279    }
4280};
4281var highcharts_14daysshortblocks=[];
4282var drawBlocksFor14DaysTrendV2short = function (chart) {
4283	$.each(highcharts_14daysshortblocks, function (i, line) {line.destroy();});
4284	highcharts_14daysshortblocks=[];
4285
4286    var xAxis = chart.xAxis[0],x,pos,max,i,faktor,len,img,rain,storm,cloudcoverage,len2,faktor2,len3,faktor3;
4287    pos = xAxis.min;
4288    max = xAxis.max;
4289    x = Math.round(xAxis.toPixels(0));
4290    faktor=0.8;
4291    faktor2=0.6;
4292    faktor3=0.4;
4293    len = Math.round((xAxis.toPixels(1)-x)*faktor);
4294    len2 = Math.round((xAxis.toPixels(1)-x)*faktor2);
4295    len3 = Math.round((xAxis.toPixels(1)-x)*faktor3);
4296    if (len>32) { len=32; faktor=1;}
4297    if (len2>22) { len2=22; faktor2=0.9;}
4298    if (len3>14) { len3=14; faktor3=1;}
4299    for (i = pos; i <= max ; i += 1) {
4300        x = Math.round(xAxis.toPixels(i));
4301        if (typeof hc_data_14days_gusts_raw[i] !== 'undefined') {
4302            img = getWindSymbol(hc_data_14days_gusts_raw[i]);
4303            if (img.length>0) {
4304                var placement = 35+Math.round(len3*1.5);
4305                group = chart.renderer.g().attr({
4306                    translateX: x - Math.round(len3/3),
4307                    translateY: chart.plotTop + chart.plotHeight-placement,
4308                    zIndex: 5
4309                }).clip(chart.renderer.clipRect(0, 0, 120, 120)).add();
4310                //add image
4311                chart.renderer.image('/images/symbole/'+img,0,0,len3,len3).add(group);
4312                //remember group for cleanup during resize
4313                highcharts_14daysshortblocks.push(group);
4314            }
4315        }
4316        if (typeof hc_data_14days_xaxis2[pos] !== 'undefined') {
4317            group = chart.renderer.g().attr({
4318                translateX: x-9,
4319                translateY: 0 ,
4320                zIndex: 6
4321            }).add();
4322            chart.renderer.label(hc_data_14days_xaxis2[i]).css({'fontSize':'11px','color':cssVar('--color-text')}
4322).add(group);
4323            highcharts_14daysshortblocks.push(group);
4324        }
4325        if (typeof hc_data_14days_rtype[i] !== 'undefined' && hc_data_14days_rtype[i] !== null && typeof hc_data_14days_rint[i] !== 'undefined' && hc_data_14days_rint[i]>0) {
4326            rain=hc_data_14days_rtype[i]+hc_data_14days_rint[i];
4327            if (rain === 'null') {
4328                rain='';
4329            }
4330            if (rain.length>0) {
4331                var placement = 31;
4332                var verschiebung = 0;
4333                if (typeof hc_data_14days_tsym[i] !== 'undefined' && hc_data_14days_tsym[i]>0) {
4334                    verschiebung = Math.round(5*faktor2*0.8);
4335                }
4336                group = chart.renderer.g().attr({
4337                    translateX: x - Math.round(len2/2)-verschiebung,
4338                    translateY: chart.plotTop + chart.plotHeight-placement,
4339                    zIndex: 6
4340                }).clip(chart.renderer.clipRect(0, 0, 120, 120)).add();
4341                //add image
4342                chart.renderer.image('/images/layout/icons/trend/precipitation-'+rain+'.svg',0,0,len2,len2).add(group);
4343                highcharts_14daysshortblocks.push(group);
4344                if (typeof hc_data_14days_tsym[i] !== 'undefined' && hc_data_14days_tsym[i] > 0) {
4345                        group = chart.renderer.g().attr({
4346                        translateX: x - Math.round(len2/5)+Math.round(verschiebung*faktor2),
4347                        translateY: chart.plotTop + chart.plotHeight-placement+Math.round(len2/2.1)-Math.round(verschiebung*faktor2),
4348                        zIndex: 7
4349                    }).clip(chart.renderer.clipRect(0, 0, 120, 120)).add();
4350                    //add image
4351                    chart.renderer.image('/images/layout/icons/trend/thunderstorm-1.svg',0,0,len2,len2).add(group);
4352                    highcharts_14daysshortblocks.push(group);
4353                }
4354            }
4355        }
4356    }
4357    var limit_clear = 90;
4358    var limit_few = 78;
4359    var limit_scattered = 60;
4360    var limit_broken = 30;
4361    if ($('#trend-14days').attr('data-version') !=="v2" && $('#trend-14days').attr('data-version') !=="v2") {
4362        limit_clear = 85;
4363        limit_few = 70;
4364        limit_scattered = 50;
4365        limit_broken = 20;
4366    }
4367    for (i = pos; i <= max ; i += 1) {
4368        var len = xAxis.toPixels(2)-xAxis.toPixels(1);
4369        var suncolor=cssVar('--hc-suncolor_0');
4370        if (typeof hc_data_14days_sun_rel[i] !== 'undefined') {
4371            if (hc_data_14days_sun_rel[i]>=limit_clear) {
4372                suncolor=cssVar('--hc-suncolor_4');
4373            }
4374            else if (hc_data_14days_sun_rel[i]>=limit_few) {
4375                suncolor=cssVar('--hc-suncolor_3');
4376            }
4377            else if (hc_data_14days_sun_rel[i]>=limit_scattered) {
4378                suncolor=cssVar('--hc-suncolor_2');
4379            }
4380            else if (hc_data_14days_sun_rel[i]>=limit_broken) {
4381                suncolor=cssVar('--hc-suncolor_1');
4382            }
4383            // Get the X position
4384            var x1 = Math.round(xAxis.toPixels(i)-(len/2))+2;
4385            var x2 = Math.round(xAxis.toPixels(i)+(len/2))-3;
4386            if(x1<chart.plotLeft) { x1=chart.plotLeft; }
4387            if(x2>chart.plotWidth+chart.plotLeft) { x2=chart.plotWidth+chart.plotLeft; }
4388            group = chart.renderer.g().attr({
4389                    translateX: x1,
4390                    translateY: chart.plotHeight-13,
4391                    zIndex: 0
4392            }).add();
4393            //add image
4394            chart.renderer.rect(0,0,x2-x1,33,1).attr({
4395                    stroke: suncolor,
4396                    fill: suncolor,
4397                    zIndex: 0
4398            }).add(group);
4399            highcharts_14daysshortblocks.push(group);
4400        }
4401    }
4402   
4403};
4404
4405
4406var highcharts_gustsblocks=[];
4407var drawBlocksForGustSymbolsV2 = function (chart) {
4408    $.each(highcharts_gustsblocks, function (i, line) {line.destroy();});
4409    highcharts_gustsblocks=[];
4410    var xAxis = chart.xAxis[0],x,pos,max,i,faktor,len,img,len2,faktor2,len3,faktor3;
4411    pos = xAxis.min;
4412    max = xAxis.max;
4413    x = Math.round(xAxis.toPixels(0));
4414    faktor=0.6;
4415    len = Math.round((xAxis.toPixels(1)-x)*faktor);
4416    if (len>18) { len=18; faktor=1;}
4417    for (i = pos; i <= max ; i += 1) {
4418        x = Math.round(xAxis.toPixels(i));
4419        if (typeof hc_data_14days_gusts_raw[i] !== 'undefined') {
4420            img = getWindSymbol(hc_data_14days_gusts_raw[i]);
4421            if (img.length>0) {
4422                group = chart.renderer.g().attr({
4423                    translateX: x - Math.round(len/2),
4424                    translateY: chart.plotTop + Math.round(6*faktor),
4425                    zIndex: 5
4426                }).clip(chart.renderer.clipRect(0, 0, 120, 120)).add();
4427                //add image
4428                chart.renderer.image('/images/symbole/'+img,0,0,len,len).add(group);
4429                //remember group for cleanup during resize
4430                highcharts_gustsblocks.push(group);
4431            }
4432        }
4433    }
4434    $.each(chart.series[0].data,function(i,data){
4435        if (typeof data.dataLabel !== 'undefined') {
4436            data.dataLabel.attr({
4437                y: chart.yAxis[0].height
4438            });
4439        }
4440    });
4441    for (pos = 0; pos < 14; pos += 1) {
4442            // Get the X position
4443            x = Math.round(xAxis.toPixels(pos));
4444            group = chart.renderer.g().attr({
4445                translateX: x-9,
4446                translateY: 0 ,
4447                zIndex: 6
4448            }).add();
4449            chart.renderer.label(hc_data_14days_xaxis2[pos]).css({'fontSize':'10px','color':cssVar('--color-text')}
4449).add(group);
4450            highcharts_gustsblocks.push(group);
4451    }
4452};
4453
4454
4455var highcharts_sunblocks=[];
4456var highcharts_sunblocks_days=[];
4457var drawBlocksForSunSymbolsV2 = function (chart) {
4458    $.each(highcharts_sunblocks, function (i, line) {line.destroy();});
4459    $.each(highcharts_sunblocks_days, function (i, line) {line.destroy();});
4460    highcharts_sunblocks=[];
4461    highcharts_sunblocks_days=[];
4462    
4463
4464    var xAxis = chart.xAxis[0],x,pos,max,i,faktor,len,cloudcoverage,len2,faktor2,len3,faktor3;
4465    pos = xAxis.min;
4466    max = xAxis.max;
4467    x = Math.round(xAxis.toPixels(0));
4468    faktor=0.8;
4469    len = Math.round((xAxis.toPixels(1)-x)*faktor);
4470    if (len>32) { len=32; faktor=1;}
4471    for (i = pos; i <= max ; i += 1) {
4472        x = Math.round(xAxis.toPixels(i));
4473        if (typeof hc_data_14days_ssym[i] !== 'undefined' && typeof hc_data_14days_sun_maxpos[i] !== 'undefined'
4474                && hc_data_14days_sun_maxpos[i]>0) {
4475            cloudcoverage=hc_data_14days_ssym[i];
4476            if (cloudcoverage === 'null') {
4477                cloudcoverage='';
4478            }
4479            if (cloudcoverage.length>0) {
4480                group = chart.renderer.g().attr({
4481                    translateX: x - Math.round(len/2),
4482                    translateY: chart.plotTop + Math.round(6*faktor),
4483                    zIndex: 5
4484                }).clip(chart.renderer.clipRect(0, 0, 120, 120)).add();
4485                chart.renderer.image('/images/layout/icons/trend/cloudcoverage-'+cloudcoverage+'.svg',0,0,len,len).add(group);
4486                highcharts_sunblocks.push(group);
4487            }
4488        }
4489    }    
4490    $.each(chart.series[0].data,function(i,data){
4491        if (typeof data.dataLabel !== 'undefined') {
4492            data.dataLabel.attr({
4493                y: chart.yAxis[0].height
4494            });
4495        }
4496    });
4497    for (pos = 0; pos < 14; pos += 1) {
4498            // Get the X position
4499            x = Math.round(xAxis.toPixels(pos));
4500            group = chart.renderer.g().attr({
4501                translateX: x-9,
4502                translateY: 0 ,
4503                zIndex: 6
4504            }).add();
4505            chart.renderer.label(hc_data_14days_xaxis2[pos]).css({'fontSize':'10px','color': cssVar('--color-text')}).add(group);
4506            highcharts_sunblocks_days.push(group);
4507    }
4508};
4509
4510var highcharts_rainblocks=[];
4511var highcharts_rainblocks_days=[];
4512var highcharts_thunderstormblocks=[];
4513var highcharts_rainprobs=[];
4514var drawBlocksForRainSymbolsV2 = function (chart) {
4515    $.each(highcharts_rainblocks, function (i, line) {line.destroy();});
4516    $.each(highcharts_rainblocks_days, function (i, line) {line.destroy();});
4517    $.each(highcharts_thunderstormblocks, function (i, line) {line.destroy();});
4518    $.each(highcharts_rainprobs, function (i, line) {line.destroy();});
4519    highcharts_rainblocks=[];highcharts_rainblocks_days=[];highcharts_thunderstormblocks=[];highcharts_rainprobs=[];
4520
4521    var xAxis = chart.xAxis[0],x,pos,max,i,faktor,len,rain, len2;
4522    pos = xAxis.min;
4523    max = xAxis.max;
4524    x = Math.round(xAxis.toPixels(0));
4525    faktor=0.8;
4526    len = Math.round((xAxis.toPixels(1)-x)*faktor);
4527    if (len>24) { len=24; faktor=1;}
4528    len2 = Math.round((xAxis.toPixels(1)-x)*faktor);
4529    if (len2>18) { len2=18; }
4530    for (i = pos; i <= max ; i += 1) {
4531        x = Math.round(xAxis.toPixels(i));
4532        if (typeof hc_data_14days_rtype[i] !== 'undefined' && hc_data_14days_rtype[i] !== null && typeof hc_data_14days_rint[i] !== 'undefined') {
4533            rain=hc_data_14days_rtype[i]+hc_data_14days_rint[i];
4534            if (rain === 'null') {
4535                rain='';
4536            }
4537            if (rain.length>0) {
4538                if (typeof hc_data_14days_tsym[i] !== 'undefined' && hc_data_14days_tsym[i]>0) {
4539                        group = chart.renderer.g().attr({
4540                        translateX: x - Math.round(len/2),
4541                        translateY: chart.plotTop + 20,
4542                        zIndex: 6
4543                    }).clip(chart.renderer.clipRect(0, 0, 120, 120)).add();
4544                    //add image
4545                    chart.renderer.image('/images/layout/icons/trend/thunderstorm-'+hc_data_14days_tsym[i]+'.svg',0,0,len,len).add(group);
4546                    highcharts_thunderstormblocks.push(group);
4547                }
4548            }
4549        }
4550    }
4551    $.each(chart.series[0].data,function(i,data){
4552        if (typeof data.dataLabel !== 'undefined') {
4553            data.dataLabel.attr({
4554                y: chart.yAxis[0].height
4555            });
4556        }
4557    });
4558    var show_perc = false;
4559    for (pos = 0; pos < 14; pos += 1) {
4560        var len = xAxis.toPixels(2)-xAxis.toPixels(1);
4561        var suncolor='#ccd9f2';
4562        // Get the X position
4563        x = Math.round(xAxis.toPixels(pos));
4564        group = chart.renderer.g().attr({
4565            translateX: x-9,
4566            translateY: 0 ,
4567            zIndex: 6
4568        }).add();
4569        chart.renderer.label(hc_data_14days_xaxis2[pos]).css({'fontSize':'10px','color': cssVar('--color-text')}).add(group);
4570        highcharts_rainblocks_days.push(group);
4571        var percentage_str = '%';
4572        var corrpos=0;
4573        if (len < 30) { percentage_str=''; show_perc=true;}
4574        var perc_str = hc_data_14days_prob[pos]+percentage_str;
4575        if (perc_str.length-percentage_str.length > 2) {
4576            corrpos=4;
4577        }
4578        if (percentage_str.length === 0){
4579            if (perc_str.length > 2) {
4580                corrpos=0;
4581            }
4582            else {
4583                corrpos=-4;
4584            }
4585        }
4586        group = chart.renderer.g().attr({
4587            translateX: x-14-corrpos,
4588            translateY: 20 ,
4589            zIndex: 7
4590        }).add();
4591        chart.renderer.label(perc_str).css({'fontSize':'11px','color': cssVar('--color-text')}).add(group);
4592        highcharts_rainblocks_days.push(group);
4593    }
4594    if (show_perc) {
4595        group = chart.renderer.g().attr({
4596            translateX: 47,
4597            translateY: 20 ,
4598            zIndex: 7
4599        }).add();
4600        chart.renderer.label('%').css({'fontSize':'11px','color': cssVar('--color-text')}).add(group);
4601        highcharts_rainblocks_days.push(group);
4602    }
4603    for (pos = 0; pos < 14; pos += 1) {
4604        var len = xAxis.toPixels(2)-xAxis.toPixels(1);
4605        var x1 = Math.round(xAxis.toPixels(pos)-(len/2))+2;
4606        var x2 = Math.round(xAxis.toPixels(pos)+(len/2))-3;
4607        if(x1<chart.plotLeft) { x1=chart.plotLeft; }
4608        if(x2>chart.plotWidth+chart.plotLeft) { x2=chart.plotWidth+chart.plotLeft; }
4609        group = chart.renderer.g().attr({
4610                translateX: x1,
4611                translateY: chart.plotTop+2,
4612                zIndex: 6
4613        }).add();
4614        chart.renderer.rect(0,0,x2-x1,16,1).attr({
4615                stroke: cssVar('--hc-rainProps'),
4616                fill: cssVar('--hc-rainProps'),
4617                zIndex: 6
4618        }).add(group);
4619        highcharts_rainprobs.push(group);
4620    }
4621};
4622
4623var plotGraphCompact = function() {
4624
4625
4626	var margin;
4627    var timezone_id_local = typeof timezone_id !== 'undefined' ? timezone_id : null;
4628    Highcharts.setOptions({
4629        global: {
4630            /**
4631             * Use moment-timezone.js to return the timezone offset for individual 
4632             * timestamps, used in the X axis labels and the tooltip header.
4633             */
4634            // getTimezoneOffset: function (timestamp) {
4635            //     return -moment.tz(timezone_id).utcOffset();
4636            // }
4637            timezone: timezone_id_local || $('#real-user-timezone').attr('data-value') || 'UTC'
4638
4639        },
4640        lang: typeof hc_user_settings_lang !== 'undefined' ? hc_user_settings_lang : {
4641            loading: 'Wird geladen...',
4642            months: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
4643            weekdays: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
4644            shortMonths: ['Jan', 'Feb', 'Mrz', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'],
4645        }
4646    });
4647    
4648    var zeroline = 0;
4649    if (typeof hccompact_units != 'undefined') {
4650        if(hccompact_units['temp']=="°F") {
4651            zeroline = 32;
4652        }
4653        else if(hccompact_units['temp']=="K") {
4654            zeroline = 273.15;
4655        }
4656    }
4657
4658    if (typeof hccompact_data_temp != 'undefined') {
4659    	 var yaxismax = false;
4660    	 if (typeof hccompact_tempmax != 'undefined') {
4661    	 		yaxismax = hccompact_tempmax > -2 && hccompact_tempmax < 2 ? true : false;
4662    	 }
4663    	 
4664       $('#temp_graph').highcharts({
4665            chart: {
4666                scrollablePlotArea: {minWidth: getMinWidth()},
4667                marginBottom: 22,
4668            	marginLeft:69,
4669							height: 260,
4670							events: {
4671								load: function(){
4672									drawWeatherSymbols(this);
4673									drawHourlyLabels(this,'temp');
4674									drawNightShadows(this, 19, 'xl');
4675									fixLabels(this,'temp');
4676
4677                                    var firstTry = new Date();
4678                                    var scrollListenerInterval = function(){
4679                                        var scrollAreas = $('.highcharts-scrolling');
4680                                        if(scrollAreas.length > 0) {
4681                                            scrollAreas.on('scroll', function (event) {
4682                                                let scrollLeft = event.target.scrollLeft;
4683                                                const containers = document.querySelectorAll('.highcharts-scrolling');
4684                                                containers.forEac
4684h(otherContainer => {
4685                                                    if (otherContainer !== event.target) {
4686                                                        otherContainer.scrollLeft = scrollLeft;
4687                                                    }
4688                                                });
4689                                            });
4690                                            addGlobalChartScrollHint(document.querySelector('.forecast-compact-wrapper'));
4691                                            window.clearInterval(intervalId);
4692                                        }
4693                                        if( new Date() - firstTry >= 10000) {
4694                                            window.clearInterval(intervalId);
4695                                        }
4696                                    };
4697                                    const intervalId = window.setInterval(scrollListenerInterval, 100);
4698
4699
4700								},
4701								redraw: function(){
4702									drawWeatherSymbols(this);
4703									drawHourlyLabels(this,'temp');
4704									drawNightShadows(this, 19, 'xl');
4705									fixLabels(this,'temp');
4706								}
4707            	}
4708            },
4709            title: 'false',
4710            legend: 'false',
4711            xAxis: {
4712            	opposite:true,
4713                type: 'datetime',
4714                tickInterval: 24*36e5,
4715                gridLineWidth: 1,
4716                gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
4717                gridZIndex:2,
4718                minorTickInterval: 3*36e5,
4719                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
4720                minorGridWidth: 1,
4721                min: hccompact_xmin,
4722                max: hccompact_xmax,
4723                dateTimeLabelFormats: {
4724                    hour: getDynHourDateFormat(),
4725                    day: getDynDayDateFormat()
4726                },
4727                labels: {
4728    				useHTML: true,
4729    				align: 'center',
4730    				formatter: function () {
4731                                        var date_format = getDynDayDateFormat(this.value, this.chart.plotWidth);
4732                                        return Highcharts.dateFormat(date_format, this.value);
4733    				},
4734                    style: {
4735                        color: cssVar('--color-text')
4736                    }
4737    			},
4738                tickLength: 0
4739            },
4740            yAxis: {
4741                title: {
4742                    text: false
4743                },
4744                labels: {
4745                    formatter: function() {
4746                        return Highcharts.numberFormat(this.value,0)+" "+hccompact_units['temp'];
4747                    },
4748                    style: {
4749                        color: cssVar('--color-text')
4750                    }
4751                },
4752                plotLines: [{
4753                    value: zeroline,
4754                    width: 1,
4755                    color: cssVar('--hc-xl-zeroline', '#C3CAD1'),
4756                    zIndex: 2
4757                }],
4758                gridLineWidth: 1,
4759                gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
4760                gridZIndex:2,
4761                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
4762                allowDecimals: false,
4763                minorTickInterval: hccompact_units['temp']=="°C" ? 2.5 :  5,
4764                tickInterval:      hccompact_units['temp']=="°C" ?   5 : 10,
4765                //gridLineColor: '#C0C0C0',
4766                maxPadding: 0.16,
4767                max: yaxismax ? 5 : null
4768            },
4769            tooltip: {
4770                crosshairs: true,
4771                shared: true,
4772                useHTML: true,
4773                shape: 'square',
4774                useHTML: true,
4775                outside: false,
4776    		    positioner: tooltipPositioner,
4777                formatter: function () { 
4778                	// fix for faulty highcharts tooltip recognition
4779                    var date_format = getDynDateFormat(this.x);
4780                	var s = '<span style="font-size:10px;">'+Highcharts.dateFormat(date_format, this.x)+ '</span> ';
4781                	var c=0;
4782		            $.each(this.points, function () {
4783	            		c++;
4784       		        	s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ this.series.name + ': ' +
4785              	    	'<b>'+Highcharts.numberFormat(this.y,1) + '</b> ' + ' ' + hccompact_units['temp'];
4786            		});
4787                    i=highcharts_symbols_timestamps[this.x];
4788                    
4789                    var severeStr = '';
4790                    if(hccompact_data_symbols[i].search('severe') >= 0) {
4791                        if(displayLanguage()=="EN"){
4792                            severeStr = '<div style="font-weight:700; "><img style="max-height:16px; margin-right:2px;" src="/images/blitz_icon.png">Severe storms possible</div>';
4793                        } else {
4794                            severeStr = '<div style="font-weight:700; "><img style="max-height:16px; margin-right:2px;" src="/images/blitz_icon.png">Schwere Gewitter möglich</div>';
4795                        }
4796                    }
4797
4798		            return '<div class="highcharts-tooltip"><table><tr><td>' + ttCols(s, this, 48) + '</td><td><img src="/images/symbole/sym_'+hccompact_data_symbols[i]+'.svg" width=32></img></td></tr></table>'+severeStr+'</div>';
4799        		}
4800            },
4801            credits: { enabled: false },
4802            exporting: { enabled: false },
4803            series: hccompact_data_temp,
4804            reflow: true
4805        });
4806    }  
4807
4808    if (typeof hccompact_data_wind != 'undefined') {
4809       $('#wind_graph').highcharts({
4810            chart: {
4811                scrollablePlotArea: {minWidth: getMinWidth()},
4812                marginLeft:69,
4813            	spacingLeft:0,
4814                height: 150, 
4815                events: {
4816                	load: function(){
4817            			//drawBlocksForWindArrows(this);
4818            			drawNightShadows(this, 20, 'xl');
4819            			drawWindArrows(this);
4820            		},
4821                	redraw: function(){
4822            			//drawBlocksForWindArrows(this);
4823            			drawNightShadows(this, 20, 'xl');
4824            			drawWindArrows(this);
4825            		}
4826            	}
4827            },
4828            title: 'false',
4829            legend: 'false',
4830            xAxis: {
4831                type: 'datetime',
4832                offset: 24,
4833                tickInterval: 24*36e5,
4834                gridLineWidth: 1,
4835                gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
4836                gridZIndex:2,
4837                minorTickInterval: 3*36e5,
4838                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
4839                minorGridWidth: 1,
4840                min: hccompact_xmin,
4841                max: hccompact_xmax,
4842                dateTimeLabelFormats: {
4843                    hour: '%H:%M',
4844                    day: '<b>%a</b>, %e. %b'
4845                },
4846                tickLength: 0,
4847                labels: { enabled:false }
4848            },
4849            yAxis: {
4850                title: {
4851                    text: false
4852                },
4853                labels: {
4854                    formatter: function() {
4855                        return Highcharts.numberFormat(this.value,0)+" "+hccompact_units['wind'];
4856                    },
4857                    style: {
4858                        color: cssVar('--color-text')
4859                    }
4860                },
4861                plotLines: [{
4862                    value: 0,
4863                    width: 1,
4864                    color: cssVar('--hc-xl-zeroline', '#C3CAD1'),
4865                    zIndex: 2
4866                }],
4867                gridLineWidth: 1,
4868                gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
4869                gridZIndex:2,
4870                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
4871                allowDecimals: false,
4872                minorTickInterval: hccompact_units['wind']==='m/s' ? 5 : hccompact_units['wind']==='Bft' ? 1 : hccompact_units['wind']==='kn' ? 7.5 : hccompact_units['wind']==='mph' ? 7.5 : 7.5,
4873                tickInterval: hccompact_units['wind']==='m/s' ? 10 : hccompact_units['wind']==='Bft' ? 3 : hccompact_units['wind']==='kn' ? 15 : hccompact_units['wind']==='mph' ? 15 : 15,
4874                //gridLineColor: '#C0C0C0'
4875            },
4876            tooltip: {
4877                crosshairs: true,
4878                shared: true,
4879                valueSuffix: ' '+hccompact_units['wind'],
4880                 shape: 'square',
4881                useHTML: true,
4882                outside: false,
4883                positioner: tooltipPositioner,
4884                formatter: function () { 
4885                	// fix for faulty highcharts tooltip recognition
4886                	var date_format = getDynDateFormat(this.x);
4887                        var digits = hccompact_units['wind'] == 'm/s' ? 1 : 0;
4888                	var s = '<span style="font-size:10px;">'+Highcharts.dateFormat(date_format, this.x)+ '</span> ';
4889                    var c=0;
4890                    
4891                    var sortedPoints = this.points.sort(function(a, b){
4892                        return ((a.y > b.y) ? -1 : ((a.y < b.y) ? 1 : 0));
4893                    });
4894
4895		            $.each(sortedPoints, function () {
4896	            		c++;
4897       		        	s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ this.series.name + ': ' +
4898              	    	'<b>'+Highcharts.numberFormat(this.y,digits) + '</b> ' + ' ' + hccompact_units['wind'];
4899            		});
4900		            return '<div class="highcharts-tooltip">' + ttCols(s, this) + '</div>';
4901        		}
4902            },
4903            credits: { enabled: false },
4904            exporting: { enabled: false },
4905            series: hccompact_data_wind, 
4906            reflow: true
4907        });
4908    }
4909
4910    if (typeof hccompact_data_pressure != 'undefined') {
4911        var pressure_decimals = false;
4912        var pressure_minortick = 2;
4913        var pressure_tick = 10;
4914        if (typeof hccompact_units['pressure'] !== 'undefined' && hccompact_units['pressure'] === 'inHg') {
4915            pressure_decimals=true;
4916            pressure_minortick = 0.1;
4917            pressure_tick=0.3;
4918        }
4919       $('#pressure_graph').highcharts({
4920            chart: {
4921                scrollablePlotArea: {minWidth: getMinWidth()},
4922                marginBottom: 45,
4923                marginLeft:69,
4924            	spacingLeft:0,
4925                height: 160,
4926                events: {
4927                	load: function(){
4928                		drawHourlyLabels(this,'pressure');
4929                		drawNightShadows(this, 21, 'xl');
4930            			fixLabels(this);
4931            		},
4932                	redraw: function(){
4933                		drawHourlyLabels(this,'pressure');
4934                		drawNightShadows(this, 21, 'xl');
4935            			fixLabels(this);
4936            		}
4937            	}
4938            },
4939            title: 'false',
4940            legend: {
4941                useHTML: true   
4942            },
4943            xAxis: {
4944                type: 'datetime',
4945                tickInterval: 24*36e5,
4946                gridLineWidth: 1,
4947                gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
4948                gridZIndex:2,
4949                minorTickInterval: 3*36e5,
4950                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
4951                minorGridWidth: 1,
4952                min: hccompact_xmin,
4953                max: hccompact_xmax,
4954                dateTimeLabelFormats: {
4955                    hour: '%H:%M',
4956                    day: '<b>%a</b>, %e. %b'
4957                },
4958                labels: {
4959    				useHTML: true,
4960    				align: 'center',
4961    				formatter: function () {
4962    					var date_format = getDynDayDateFormat(this.value, this.chart.plotWidth);
4963                                        return Highcharts.dateFormat(date_format, this.value);
4964    				},
4965                    style: {
4966                        color: cssVar('--color-text')
4967                    }
4968    			},
4969                tickLength: 0,
4970            },
4971            yAxis: {
4972                title: {
4973                    text: false
4974                },
4975                labels: {
4976                    formatter: function() {
4977                        return Highcharts.numberFormat(this.value,0)+(hccompact_units['pressure'] =='mbar' ? hccompact_units['pressure'] : ' '+hccompact_units['pressure']);
4978                    },
4979                    style: {
4980                        color: cssVar('--color-text')
4981                    }
4982                },
4983                offset: hccompact_units['pressure'] =='mbar' ? (-6) : hccompact_units['pressure'] =='inHg' ? -4 : (-5),
4984                gridLineWidth: 1,
4985                gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
4986                gridZIndex:2,
4987                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
4988                allowDecimals: pressure_decimals,
4989                minorTickInterval: pressure_minortick,
4990                //gridLineColor: '#C0C0C0',
4991                tickInterval: pressure_tick,
4992                maxPadding: 0,
4993                minPadding: 0
4994            },
4995            tooltip: {
4996                crosshairs: true,
4997                shared: true,
4998                valueSuffix: ' '+hccompact_units['pressure'],
4999                 shape: 'square',
5000                useHTML: true,
5001                zIndex: 50,
5002                outside: false,
5003                positioner: tooltipPositioner,
5004                formatter: function () { 
5005                	// fix for faulty highcharts tooltip recognition
5006                	var date_format = getDynDateFormat(this.x);
5007                	var s = '<span style="font-size:10px;">'+Highcharts.dateFormat(date_format, this.x)+ '</span> ';
5008                	var c=0;
5009                        $.each(this.points, function () {
5010                            c++;
5011                            s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ this.series.name + ': ' +
5012                                '<b>'+Highcharts.numberFormat(this.y,1) + '</b> ' + ' '+hccompact_units['pressure'];
5013            		});
5014		            return '<div class="highcharts-tooltip">' + ttCols(s, this) + '</div>';
5015        		}
5016            },
5017            credits: { enabled: false },
5018            exporting: { enabled: false },
5019            series: hccompact_data_pressure, 
5020            reflow: true
5021        });
5022    } 
5023
5024	if (typeof hccompact_data_sun != 'undefined') {
5025        var langOpts = {
5026            weekday: "long",
5027            year: "numeric",
5028            month: "short",
5029            day: "numeric",
5030        };
5031
5032        var hccompact_sun_frontend = hccompact_data_sun.map(serie => ({
5033            ...serie,
5034            data: serie.data.map(point => ({ ...point, timestamp: point.x, x: point.x - point.z }))
5035        })).filter(serie => serie.data.length > 0);
5036
5037        var minimalSunZ = hccompact_sun_frontend.length === 0 ? 36e5 : Math.min(...hccompact_sun_frontend.map(serie => Math.min(...serie.data.map(point => point.z))));
5038
5039        $('#sun_graph').highcharts({
5040            plotOptions: {
5041                series: {
5042                    states: {
5043                        inactive: {
5044                            opacity: 1
5045                        }
5046                    }
5047                },
5048                variwide: {
5049                    color: "#e7d621",
5050                    borderColor: "#F7E631",
5051                    cropThreshold: 500,
5052                    pointPadding: 0,
5053                    groupPadding: 0,
5054                    borderWidth: 1,
5055                }
5056            },
5057            chart: {
5058                scrollablePlotArea: {minWidth: getMinWidth()},
5059                marginBottom: 45,
5060                marginLeft: 69,
5061                height: 100,
5062                events: {
5063                    load: function () {
5064                        drawSunshineSums(this);
5065                        drawHourlyLabels(this, 'sun');
5066                        drawNightShadows(this, 22, 'xl');
5067                        fixLabels(this);
5068                    },
5069                    redraw: function () {
5070                        drawSunshineSums(this);
5071                        drawHourlyLabels(this, 'sun');
5072                        drawNightShadows(this, 22, 'xl');
5073                        fixLabels(this);
5074                    }
5075                },
5076                type: 'variwide'
5077            },
5078            title: 'false',
5079            legend: {
5080                useHTML: true
5081            },
5082            xAxis: {
5083                type: 'datetime',
5084                tickInterval: 24 * 36e5,
5085                gridLineWidth: 1,
5086                gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
5087                gridZIndex: 2,
5088                minorTickInterval: 3 * 36e5,
5089                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
5090                minorGridWidth: 1,
5091                min: hccompact_xmin + (minimalSunZ / 2),
5092                max: hccompact_xmax - (minimalSunZ / 2),
5093                labels: {
5094                    useHTML: true,
5095                    align: 'center',
5096                    formatter: function () {
5097                        var date_format = getDynDayDateFormat(this.value, this.chart.plotWidth);
5098                        return Highcharts.dateFormat(date_format, this.value);
5099                    },
5100                    style: {
5101                        color: cssVar('--color-text')
5102                    }
5103                },
5104                tickLength: 0
5105            },
5106            yAxis: {
5107                title: {
5108                    text: false
5109                },
5110                floor: 0,
5111                labels: {
5112                    formatter: function () {
5113                        return Highcharts.numberFormat(1 / (60 / this.value) * 100, 0) + " %";
5114                    },
5115                    style: {
5116                        color: cssVar('--color-text')
5117                    }
5118                },
5119                min: 0,
5120                max: 80,
5121                gridLineWidth: 1,
5122                gridZIndex: 2,
5123                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
5124                showLastLabel: false,
5125                allowDecimals: false,
5126                minorTickInterval: 1,
5127                tickInterval: 30,
5128                gridLineColor: cssVar('--hc-xl-grid', '#EEF1F4')
5129                //tickAmount: 1
5130            },
5131            tooltip: {
5132                crosshairs: true,
5133                shared: true,
5134                valueSuffix: ' min',
5135                shape: 'square',
5136                useHTML: true,
5137                zIndex: 50,
5138                outside: false,
5139                positioner: tooltipPositioner,
5140                formatter: function (input) {
5141                    var point = this.points[0];
5142                    //console.log(point);
5143                    var hoursStr = `(${new Date(point.point.x).toLocaleString(displayLanguage, { timeStyle: "short" })} - ${new Date(point.point.timestamp).toLocaleString(displayLanguage, { timeStyle: "short" })})`;
5144
5145                    let timestamp = new Date(this.x);
5146                    var percentage = (1 / (60 / point.y)) * 100;
5147                    var hourmins = point.y * point.point.hours;
5148                    var useHours = hourmins > 60;
5149
5150                    if (useHours) {
5151                        hourmins = hourmins / 60;
5152                    }
5153
5154                    return `<span style="font-size:10px">${timestamp.toLocaleDateString(displayLanguage(), langOpts)} ${hoursStr}</span> 
5155                        <br/><span style="color:${point.series.color}">●</span> ${point.series.name}: 
5156                        <b>${Highcharts.numberFormat(hourmins, useHours ? 1 : 0)}</b> ${hccompact_units[ useHours ? 'sunhours' : 'sunmin' ]} (${Highcharts.numberFormat(percentage, 0)}%)`;
5157                }
5158            },
5159            credits: {enabled: false},
5160            exporting: {enabled: false},
5161            series: hccompact_sun_frontend,
5162            reflow: true
5163        });
5164    }   
5165
5166    if (typeof hccompact_data_rain != 'undefined') {
5167        var hccompact_rain_frontend = hccompact_data_rain.map(serie => ({
5168            ...serie,
5169            data: serie.data.map(point => ({ ...point, timestamp: point.x, x: point.x - point.z }))
5170        })).filter(serie => serie.data.length > 0);
5171
5172        var minimalRainZ = hccompact_rain_frontend.length === 0 ? 36e5 : Math.min(...hccompact_rain_frontend.map(serie => Math.min(...serie.data.map(point => point.z))));
5173
5174        $('#rain_graph').highcharts({
5175            chart: {
5176                scrollablePlotArea: {minWidth: getMinWidth()},
5177                marginBottom: 45,
5178                marginLeft:69,
5179                height: 120,
5180                type: "variwide",
5181                events: {
5182                	load: function(){
5183                	drawRainSums(this);
5184            			drawHourlyLabels(this,'rain');
5185            			drawNightShadows(this, 23, 'xl');
5186            			fixLabels(this);
5187            		},
5188                	redraw: function(){
5189                	drawRainSums(this);
5190            			drawHourlyLabels(this,'rain');
5191            			drawNightShadows(this, 23, 'xl');
5192            			fixLabels(this);
5193            		}
5194            	}
5195            },
5196            plotOptions:{
5197           		series: {
5198            	  	pointPadding: 0,
5199            	  	groupPadding: 0
5200     	       	},
5201     	       	variwide: {
5202                    color: cssVar('--hc-rain'),
5203                    borderColor: cssVar('--hc-rain'),
5204            		stacking: 'normal',
5205                    cropThreshold: 500,
5206                    pointPadding: 0,
5207                    groupPadding: 0,
5208                    borderWidth: 1,
5209                }
5210            },
5211            title: 'false',
5212            legend: { enabled: false },
5213            xAxis: {
5214                type: 'datetime',
5215                tickInterval: 24*36e5,
5216                gridLineWidth: 1,
5217                gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
5218                lineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
5219                gridZIndex:2,
5220                minorTickInterval: 3*36e5,
5221                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
5222                minorGridWidth: 1,
5223                endOnTick:false,
5224                min: hccompact_xmin + (minimalRainZ / 2),
5225                max: hccompact_xmax - (minimalRainZ / 2),
5226                dateTimeLabelFormats: {
5227                    hour: '%H:%M',
5228                    day: '<b>%a</b>, %e. %b'
5229                },
5230                labels: {
5231    				useHTML: true,
5232    				align: 'center',
5233    				formatter: function () {
5234    					var date_format = getDynDayDateFormat(this.value, this.chart.plotWidth);
5235                                        return Highcharts.dateFormat(date_format, this.value);
5236    				},
5237                    style: {
5238                        color: cssVar('--color-text')
5239                    }
5240    			},
5241                tickLength: 0 
5242            },
5243            yAxis: {
5244                title: {
5245                    text: false
5246                },
5247                floor: 0,
5248                labels: {
5249                    formatter: function() {
5250                        var digits = 0;
5251                        if (hccompact_units['rain'] == 'in') { digits=1; }
5252                        return Highcharts.numberFormat(this.value, digits)+" "+hccompact_units['rain'] + "/" + hccompact_units['sunhours']
5253                    },
5254                    style: {
5255                        color: cssVar('--color-text')
5256                    }
5257                },
5258                gridLineWidth: 1,
5259                gridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
5260                gridZIndex:2,
5261                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
5262                min: 0,
5263                softMax: hccompact_units['rain']=="mm" ? 2 : 0.2,
5264                maxPadding: 0.2,
5265                allowDecimals: hccompact_units['rain']=="mm" ? true : true,
5266                minorTickInterval: hccompact_units['rain']=="mm" ? 1 : 0.01,
5267                tickInterval: hccompact_units['rain']=="mm" ? 1 : 0.05,
5268            },
5269            tooltip: {
5270                crosshairs: true,
5271                shared: true, 
5272                valueSuffix: ' '+hccompact_units['rain'],
5273                 shape: 'square',
5274                useHTML: true,
5275                zIndex: 50,
5276                outside: false,
5277                positioner: tooltipPositioner,
5278                formatter: function () {
5279                    var point = this.points[0];
5280
5281                	var date_format = getDynDateFormat(this.x);
5282                	var digits = hccompact_units['rain'] == 'in' ? 2 : 1;
5283                    var hoursStr = `(${new Date(point.point.x).toLocaleString(displayLanguage, { timeStyle: "short" })} - ${new Date(point.point.timestamp).toLocaleString(displayLanguage, { timeStyle: "short" })})`;
5284
5285                    let sumStr = (point.point.hours > 1 ? Highcharts.numberFormat((Math.round(point.total * Math.pow(10, digits)) / Math.pow(10, digits)) * point.point.hours, digits) + " "+hccompact_units['rain']+" (~ " : "");
5286
5287                    var s = '<span style="font-size:10px">'+Highcharts.dateFormat(date_format, this.x) + hoursStr + '</span> ';
5288		            $.each(this.points, function () {
5289                        let sumStr = (point.point.hours > 1 ? Highcharts.numberFormat((Math.round(this.y * Math.pow(10, digits)) / Math.pow(10, digits)) * point.point.hours, digits) + " "+hccompact_units['rain']+" (~ " : "");
5290        		        s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ this.series.name + ': ' +
5291                            sumStr + '<b>'+ Highcharts.numberFormat(this.y,digits) + '</b> ' + ' ' +hccompact_units['rain'] + "/" + hccompact_units['sunhours']+ (sumStr.length > 0 ? ")" : "");
5292            		});
5293            		s+='<br/><span style="color:#000000">' + '●' + '</span> Total: '+sumStr +'<b>' + Highcharts.numberFormat(point.total,digits) + '</b> '+hccompact_units['rain'] + "/" + hccompact_units['sunhours'] + (sumStr.length > 0 ? ")" : "");
5294		            return ttCols(s, this);
5295        		}
5296            },
5297            credits: { enabled: false },
5298            exporting: { enabled: false },
5299            series: hccompact_rain_frontend,
5300            reflow: true
5301        });
5302    } 
5303
5304    if (typeof hccompact_data_rainsum != 'undefined') {
5305       $('#rainsum_graph').highcharts({
5306            chart: {
5307                scrollablePlotArea: {minWidth: getMinWidth()},
5308                marginBottom: 22,
5309                marginLeft:69,
5310                height: 90,
5311                events: {
5312                	load: function(){
5313            			drawNightShadows(this, 24, 'xl');
5314            		},
5315                	redraw: function(){
5316            			drawNightShadows(this, 24, 'xl');
5317            		}
5318            	}
5319            },
5320            title: 'false',
5321            legend: {
5322                useHTML: true
5323            },
5324            xAxis: {
5325                type: 'datetime',
5326                tickInterval: 24*36e5,
5327                gridLineWidth: 1,
5328                gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
5329                gridZIndex:2,
5330                minorTickInterval: 3*36e5,
5331                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
5332                minorGridWidth: 1,
5333                min: hccompact_xmin,
5334                max: hccompact_xmax,
5335                dateTimeLabelFormats: {
5336                    hour: '%H:%M',
5337                    day: '%e. %b'
5338                },
5339                labels: {enabled:false},
5340                tickLength: 0
5341            },
5342            yAxis: {
5343                title: {
5344                    text: false
5345                },
5346                labels: {
5347                    formatter: function() {
5348                        var digits = 0;
5349                        if (hccompact_units['rain'] == 'in') { digits=1; }
5350                        return Highcharts.numberFormat(this.value, digits)+" "+hccompact_units['rain']
5351                    },
5352                    style: {
5353                        color: cssVar('--color-text')
5354                    }
5355                },
5356                min:0,
5357                gridLineWidth: 1,
5358                gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
5359                gridZIndex:2,
5360                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
5361                softMax: 1, //hccompact_units['rain']=="mm" ? 1 : 0.1,
5362                allowDecimals: hccompact_units['rain']=="mm" ? false : true,
5363                minorTickInterval: hccompact_units['rain']=="mm" ? 1 : 0.02,
5364                //gridLineColor: '#C0C0C0',
5365                alignTicks: false,
5366                tickInterval: hccompact_units['rain']=="mm" ? 5 : 0.5
5367            },
5368            tooltip: {
5369                crosshairs: true,
5370                shared: true,
5371                valueSuffix: ' '+hccompact_units['rain'],
5372                 shape: 'square',
5373                useHTML: true,
5374                zIndex: 50,
5375                outside: false,
5376                positioner: tooltipPositioner,
5377                formatter: function () {
5378                	var date_format = getDynDateFormat(this.x);
5379                	var digits = 1;
5380                        if (hccompact_units['rain'] == 'in') { digits=2; }
5381                	var s = '<span style="font-size:10px">'+Highcharts.dateFormat(date_format, this.x)+ '</span> ';
5382		            $.each(this.points, function () {
5383        		        s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ this.series.name + ': ' +
5384                	    '<b>'+Highcharts.numberFormat((this.y).toFixed(digits),digits) + '</b> ' + ' ' +hccompact_units['rain'];
5385            		});
5386		            return ttCols(s, this);
5387        		}
5388            },
5389            credits: { enabled: false },
5390            exporting: { enabled: false },
5391            series: hccompact_data_rainsum,
5392            reflow: true
5393        });
5394    }
5395
5396    if (typeof hccompact_data_snowheight != 'undefined') {
5397       $('#snowheight_graph').highcharts({
5398            chart: {
5399                scrollablePlotArea: {minWidth: getMinWidth()},
5400                marginBottom: 22,
5401                marginLeft:69,
5402                height: 110,
5403                events: {
5404                	load: function(){
5405            			drawNightShadows(this, 32, 'xl');
5406            		},
5407                	redraw: function(){
5408            			drawNightShadows(this, 32, 'xl');
5409            		}
5410            	}
5411            },
5412            title: 'false',
5413            legend: {
5414                useHTML: true
5415            },
5416            xAxis: {
5417                type: 'datetime',
5418                tickInterval: 24*36e5,
5419                gridLineWidth: 1,
5420                gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
5421                gridZIndex:2,
5422                minorTickInterval: 3*36e5,
5423                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
5424                minorGridWidth: 1,
5425                min: hccompact_xmin,
5426                max: hccompact_xmax,
5427                dateTimeLabelFormats: {
5428                    hour: '%H:%M',
5429                    day: '%e. %b'
5430                },
5431                labels: {enabled:false},
5432                tickLength: 0
5433            },
5434            yAxis: {
5435                title: {
5436                    text: false
5437                },
5438                labels: {
5439                    formatter: function() {
5440                        var digits = 0;
5441                        //if (hccompact_units['snow'] == 'in') { digits=1; }
5442                        return Highcharts.numberFormat(this.value, digits)+" "+hccompact_units['snow']
5443                    },
5444                    style: {
5445                        color: cssVar('--color-text')
5446                    }
5447                },
5448                min:0,
5449                gridLineWidth: 1,
5450                gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
5451                gridZIndex:2,
5452                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
5453                softMax: hccompact_units['snow']=="cm" ? 5 : 2,
5454                allowDecimals: hccompact_units['snow']=="cm" ? false : true,
5455                minorTickInterval: hccompact_units['snow']=="cm" ? (
5456                        hccompact_snowmax > 100 ? 25 :
5457                            hccompact_snowmax > 50 ? 10 :
5458                                hccompact_snowmax > 20 ? 5 :
5459                                1
5460                        ) : ( 
5461                        hccompact_snowmax > 100 ? 10 :
5462                            hccompact_snowmax > 50 ? 5 :
5463                                hccompact_snowmax > 20 ? 2 :
5464                                0.5
5465                        ),
5466                //gridLineColor: '#C0C0C0',
5467                alignTicks: false,
5468                tickInterval: hccompact_units['snow']=="cm" ? (
5469                        hccompact_snowmax > 100 ? 50 :
5470                            hccompact_snowmax > 50 ? 20 :
5471                                hccompact_snowmax > 20 ? 10 :
5472                                5
5473                        ) : (
5474                        hccompact_snowmax > 100 ? 20 :
5475                            hccompact_snowmax > 50 ? 10 :
5476                                hccompact_snowmax > 20 ? 4 :
5477                                1
5478                        )
5479            },
5480            tooltip: {
5481                crosshairs: true,
5482                shared: true,
5483                valueSuffix: ' '+hccompact_units['snow'],
5484                 shape: 'square',
5485                useHTML: true,
5486                zIndex: 50,
5487                outside: false,
5488                positioner: tooltipPositioner,
5489                formatter: function () {
5490                	var date_format = getDynDateFormat(this.x);
5491                	
5492                        if (hccompact_units['snow'] == 'in') { digits=1; }
5493                	var s = '<span style="font-size:10px">'+Highcharts.dateFormat(date_format, this.x)+ '</span> ';
5494		            $.each(this.points, function () {
5495                                var digits = 0;
5496                                if (hccompact_units['snow'] == 'in') {
5497                                    digits = 1;
5498                                }
5499                                else {
5500                                    if (this.y > 0 && this.y < 2) { digits = 1; }
5501                                }
5502        		        s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ this.series.name + ': ' +
5503                	    '<b>'+Highcharts.numberFormat((this.y).toFixed(digits),digits) + '</b> ' + ' ' +hccompact_units['snow'];
5504            		});
5505		            return ttCols(s, this);
5506        		}
5507            },
5508            credits: { enabled: false },
5509            exporting: { enabled: false },
5510            series: hccompact_data_snowheight,
5511            reflow: true
5512        });
5513    }
5514
5515    if (typeof hccompact_data_rainpop != 'undefined') {
5516       $('#rainpop_graph').highcharts({
5517            chart: {
5518                scrollablePlotArea: {minWidth: getMinWidth()},
5519                marginBottom: 22,
5520                marginLeft:69,
5521                height: 100,
5522                events: {
5523                	load: function(){
5524                		drawNightShadows(this, 25, 'xl');
5525            			
5526            		},
5527                	redraw: function(){
5528                		drawNightShadows(this, 25, 'xl');
5529            			
5530            		}
5531            	},
5532            },
5533            title: 'false',
5534            legend: {
5535                useHTML: true   
5536            },
5537            xAxis: {
5538                type: 'datetime',
5539                tickInterval: 24*36e5,
5540                gridLineWidth: 1,
5541                gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
5542                gridZIndex:2,
5543                minorTickInterval: 3*36e5,
5544                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
5545                minorGridWidth: 1,
5546                min: hccompact_xmin,
5547                max: hccompact_xmax,
5548                dateTimeLabelFormats: {
5549                    hour: '%H:%M',
5550                    day: '%e. %b'
5551                },
5552                labels: {enabled:false},
5553                tickLength: 0,
5554                plotBands: (typeof hccompact_data_rainpopEmpty != 'undefined' ? hccompact_data_rainpopEmpty : [])
5555            },
5556            yAxis: {
5557                title: {
5558                    text: false
5559                },
5560                labels: {
5561                    formatter: function() {
5562                        return Highcharts.numberFormat(this.value, 0)+" %";
5563                    },
5564                    style: {
5565                        color: cssVar('--color-text')
5566                    }
5567                },
5568                gridLineWidth: 1,
5569                gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
5570                gridZIndex:2,
5571                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
5572                allowDecimals: false,
5573                minorTickInterval: 1,
5574                //gridLineColor: '#C0C0C0',
5575                maxPadding: 0,
5576                max: 101,
5577                endOnTick: false,
5578                tickInterval: 50
5579            },
5580            tooltip: {
5581                crosshairs: true,
5582                shared: true,
5583                valueSuffix: ' %',
5584                 shape: 'square',
5585                useHTML: true,
5586                zIndex: 50,
5587                outside: false,
5588                positioner: tooltipPositioner,
5589                formatter: function () { 
5590                	// fix for faulty highcharts tooltip recognition
5591                        var date_format = getDynDateFormat(this.x);
5592                        var date_format_from = getDynDateFormat(this.x-3*3600*1000);
5593                        var s = '<span style="font-size:10px;">'+hccompact_units['from']+' '+Highcharts.dateFormat(date_format_from, (this.x-3*3600*1000))+ '<br class="visible-xs-inline" /> '+hccompact_units['until']+' '+Highcharts.dateFormat(date_format, this.x)+'</span> ';
5594                	var c=0;
5595		            $.each(this.points, function () {
5596		            	s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ this.series.name + ': ' +
5597                	    	'<b>'+Highcharts.numberFormat(this.y,0) + '</b> ' + ' %';
5598            		});
5599		            return '<div class="highcharts-tooltip">' + ttCols(s, this) + '</div>';
5600        		}
5601            },
5602            credits: { enabled: false },
5603            exporting: { enabled: false },
5604            series: hccompact_data_rainpop, 
5605            reflow: true
5606        });
5607    }  
5608    
5609    if (typeof hccompact_data_humidity != 'undefined') {
5610        $('#humidity_graph').highcharts({
5611            chart: {
5612                scrollablePlotArea: {minWidth: getMinWidth()},
5613                marginBottom: 22,
5614                marginLeft:69,
5615                height: 75,
5616                type: 'area',
5617                events: {
5618                	load: function(){
5619            			drawNightShadows(this, 26, 'xl');
5620            		},
5621                	redraw: function(){
5622            			drawNightShadows(this, 26, 'xl');
5623            		}
5624            	}
5625            },
5626            title: 'false',
5627            legend: {
5628                useHTML: true   
5629            },
5630            xAxis: {
5631                type: 'datetime',
5632                tickInterval: 24*36e5,
5633                gridLineWidth: 1,
5634                gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
5635                gridZIndex:2,
5636                minorTickInterval: 3*36e5,
5637                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
5638                minorGridWidth: 1,
5639                min: hccompact_xmin,
5640                max: hccompact_xmax,
5641                dateTimeLabelFormats: {
5642                    hour: '%H:%M',
5643                    day: '%e. %b'
5644                },
5645                labels: {enabled:false},
5646                tickLength: 0
5647            },
5648            yAxis: {
5649                title: {
5650                    text: false
5651                },
5652                floor: 0,
5653                labels: {
5654                    formatter: function() {
5655                        return Highcharts.numberFormat(this.value,0)+" %";
5656                    },
5657                    style: {
5658                        color: cssVar('--color-text')
5659                    }
5660
5661                },
5662                gridLineWidth: 1,
5663                gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
5664                gridZIndex:2,
5665                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
5666                min:0,
5667                max:100,
5668                allowDecimals: false,
5669                minorTickInterval: 1,
5670                tickInterval: 25,
5671                //gridLineColor: '#C0C0C0'
5672                //tickAmount: 1
5673            },
5674            tooltip: {
5675                crosshairs: true,
5676                shared: true,
5677                valueSuffix: ' %',
5678                 shape: 'square',
5679                useHTML: true,
5680                zIndex: 50,
5681                outside: false,
5682                positioner: tooltipPositioner,
5683                formatter: function () { 
5684                	// fix for faulty highcharts tooltip recognition
5685                	var date_format = getDynDateFormat(this.x);
5686                	var s = '<span style="font-size:10px;">'+Highcharts.dateFormat(date_format, this.x)+ '</span> ';
5687                	var c=0;
5688                        $.each(this.points, function () {
5689                            c++;
5690                            s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ this.series.name + ': ' +
5691                            '<b>'+Highcharts.numberFormat(this.y,0) + '</b> ' + ' %';
5692            		});
5693                        return '<div class="highcharts-tooltip">' + ttCols(s, this) + '</div>';
5694                    }
5695            },
5696            plotOptions: {
5697	            area: {
5698	                fillColor: {
5699	                    linearGradient: {
5700	                        x1: 0,
5701	                        y1: 0,
5702	                        x2: 0,
5703	                        y2: 1
5704	                    },
5705	                    stops: [
5706	                        [0, cssVar('--hc-humidy_0')],
5707	                        [1, cssVar('--hc-humidy_1')]
5708	                    ]
5709	                },
5710	                marker: {
5711	                    radius: 2
5712	                },
5713	                lineWidth: 1,
5714	                states: {
5715	                    hover: {
5716	                        lineWidth: 1
5717	                    }
5718	                },
5719	                threshold: null
5720	            }
5721        	},
5722            credits: { enabled: false },
5723            exporting: { enabled: false },
5724            series: hccompact_data_humidity, 
5725            reflow: true
5726        });
5727    }  
5728
5729    if (typeof hccompact_data_clouds != 'undefined') {
5730        $('#clouds_graph').highcharts({
5731            chart: {
5732                scrollablePlotArea: {minWidth: getMinWidth()},
5733                marginBottom: 22,
5734                marginLeft:69,
5735                height: 90,
5736                type: 'heatmap',
5737                plotBorderWidth: 1
5738            },
5739            title: 'false',
5740            legend: { enabled : false  },
5741            xAxis: {
5742                type: 'datetime',
5743                tickInterval: 24*36e5,
5744                gridLineWidth: 1,
5745                gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
5746                gridZIndex:6,
5747                minorTickInterval: 3*36e5,
5748                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
5749                minorGridWidth: 36e5,
5750                min: hccompact_xmin + 0.5 * 36e5,
5751                max: hccompact_xmax - 0.5 * 36e5,
5752                dateTimeLabelFormats: {
5753                    hour: '%H:%M',
5754                    day: '%e. %b'
5755                },
5756                labels: {enabled:false},
5757                tickLength: 0
5758            },
5759            yAxis: {
5760                title: {
5761                    text: false
5762                },
5763                gridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
5764                gridZIndex:6,
5765                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
5766                categories: hccompact_units['levels'],
5767                tickInterval: 1,
5768                labels: {
5769                    style: {
5770                        color: cssVar('--color-text')
5771                    }
5772                }
5773            },
5774            tooltip: { enabled: false },
5775            colorAxis: {
5776            	dataClasses:[{
5777            		from    :0,		to      :12.5,    		color   : cssVar('--hc-cloudcolor_0')    	},{
5778            		from    :12.5,	to      :25,       		color   : cssVar('--hc-cloudcolor_1')    	},{
5779            		from    :25,	to      :37.5,     		color   : cssVar('--hc-cloudcolor_2')    	},{
5780            		from    :37.5,	to      :50,			color   : cssVar('--hc-cloudcolor_3')		},{
5781            		from    :50,	to      :62.5,			color   : cssVar('--hc-cloudcolor_4')		},{
5782            		from    :62.5,	to      :75,			color   : cssVar('--hc-cloudcolor_5')		},{
5783            		from    :75,	to      :87.5,			color   : cssVar('--hc-cloudcolor_6')		},{
5784            		from    :87.5,	to      :100,			color   : cssVar('--hc-cloudcolor_7')     }]
5785    		},
5786            credits: { enabled: false },
5787            exporting: { enabled: false },
5788            series: hccompact_data_clouds, 
5789            reflow: true
5790        });
5791    }
5792    
5793    if (typeof hccompact_data_visibility != 'undefined') {
5794        $('#visibility_graph').highcharts({
5795            chart: {
5796                scrollablePlotArea: {minWidth: getMinWidth()},
5797            	marginLeft:69,
5798            	height: 150,
5799							type: 'area',
5800							events: {
5801								load: function(){
5802									drawNightShadows(this, 27, 'xl');
5803								},
5804								redraw: function(){
5805									drawNightShadows(this, 27, 'xl');
5806								}
5807            	}
5808            },
5809            title: 'false',
5810            legend: {
5811                useHTML: true
5812            },
5813            xAxis: {
5814                type: 'datetime',
5815                tickInterval: 24*36e5,
5816                gridLineWidth: 1,
5817                gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
5818                gridZIndex:2,
5819                minorTickInterval: 3*36e5,
5820                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
5821                minorGridWidth: 1,
5822                min: hccompact_xmin,
5823                max: hccompact_xmax,
5824                dateTimeLabelFormats: {
5825                    hour: '%H:%M',
5826                    day: '%e. %b'
5827                },
5828                labels: {enabled:false},
5829                tickLength: 0
5830            },
5831            yAxis: {
5832                title: { 
5833                    text: false
5834                },
5835                labels: {
5836                    format: "{value} "+hccompact_units['visibility'],
5837                    style: {
5838                        color: cssVar('--color-text')
5839                    }
5840                },
5841                plotLines: [{
5842                    value: 1,
5843                    width: 2,
5844                    color: '#F7E631',
5845                    zIndex: 3
5846                }],
5847                gridLineWidth: 1,
5848                gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
5849                gridZIndex:2,
5850                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
5851                allowDecimals: false,
5852                minorTickInterval: 1,
5853                //gridLineColor: '#C0C0C0',
5854                maxPadding: 0,
5855                tickInterval: 1,
5856                endOnTick: false,
5857            },
5858            tooltip: {
5859                crosshairs: true,
5860                shared: true,
5861                valueSuffix: ' '+hccompact_units['visibility'],
5862                 shape: 'square',
5863                useHTML: true,
5864                zIndex: 50,
5865                outside: false,
5866                positioner: tooltipPositioner,
5867                formatter: function () {
5868                    var date_format = getDynDateFormat(this.x);
5869                    var s = '<span style="font-size:10px">'+Highcharts.dateFormat(date_format, this.x)+'</span> ';
5870		            $.each(this.points, function () {
5871                        s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ this.series.name + ': ' + '<b>'+Highcharts.numberFormat(this.y,1) + '</b> ' + ' ' +hccompact_units['visibility'];
5872                    });
5873                    return ttCols(s, this);
5874                }
5875            },
5876            plotOptions: {
5877	            	area: {
5878	                fillColor: {
5879	                    linearGradient: {
5880	                        x1: 0,
5881	                        y1: 0,
5882	                        x2: 0,
5883	                        y2: 1
5884	                    },
5885	                    stops: [
5886	                        [0, '#005288'],
5887	                        [1, '#7dbbea']
5888	                    ]
5889	                }
5890	           	 }
5891        		},
5892            credits: { enabled: false },
5893            exporting: { enabled: false },
5894            series: hccompact_data_visibility,
5895            reflow: true
5896        });
5897    }
5898    
5899    // landing page diagram
5900    if (typeof hclanding_data_temp != 'undefined') {
5901       $('#temp_graph').highcharts({
5902            chart: {
5903            	// marginLeft:69,
5904            	spacingBottom:40,
5905                height: 300,
5906                events: {
5907                	load: function(){
5908            			drawWeatherSymbols(this,hclanding_data_temp);
5909            			drawHourlyLabels(this,'landing');
5910            			drawNightShadows(this,28);
5911            			fixLabels(this,'landing');
5912            			drawWindArrows(this,'landing');
5913            		},
5914                	redraw: function(){
5915            			drawWeatherSymbols(this,hclanding_data_temp);
5916            			drawHourlyLabels(this,'landing');
5917            			drawNightShadows(this,28);
5918            			fixLabels(this,'landing');
5919            			drawWindArrows(this,'landing');
5920            		}
5921            	}
5922            },
5923            title: {
5924                text: undefined
5925            },
5926            legend: {
5927                enabled: false
5928            },
5929            xAxis: {
5930            	opposite: true,
5931            	offset: 0,
5932                type: 'datetime',
5933                tickInterval: 24*36e5,
5934                gridLineWidth: 1,
5935                gridLineColor: cssVar(' --hc-gridLineColor777777'),
5936                gridZIndex:2,
5937                minorTickInterval: 3*36e5,
5938                minorGridLineColor: cssVar('--hc-gridLineColorCCCCCC'),
5939                minorGridWidth: 1,
5940                min: hccompact_xmin,
5941                max: hccompact_xmax,
5942                dateTimeLabelFormats: {
5943                    hour: '%H:%M',
5944                    day: '<b>%a</b>, %e. %b'
5945                },
5946                labels: {
5947    				useHTML: true,
5948    				align: 'center',
5949    				formatter: function () {
5950    					var date_format = getDynDayDateFormat(this.value, this.chart.plotWidth);
5951                                        return Highcharts.dateFormat(date_format, this.value);
5952    				},
5953                    style: {
5954                        color: cssVar('--color-text')
5955                    }
5956    			},
5957                tickLength: 0
5958            },
5959            yAxis: [{
5960                title: { text: false },
5961                labels: {
5962                    format: "{value}"+hccompact_units['temp'],
5963                    style: {
5964                        color: cssVar('--color-text')
5965                    }
5966                },
5967                plotLines: [{
5968                    value: zeroline,
5969                    width: 2,
5970                    color: cssVar('hc-plotLines808080'),
5971                    zIndex: 2
5972                }],
5973                gridLineWidth: 1,
5974                //gridLineColor: cssVar('--hc-gridLineColor777777'),
5975                gridZIndex:2,
5976                zIndex: 15,
5977                minorGridLineColor: cssVar('--hc-gridLineColorCCCCCC'),
5978                allowDecimals: false,
5979                minorTickInterval: hccompact_units['temp']=="°C" ? 2 : 5,
5980                tickInterval: hccompact_units['temp']=="°C" ? 4 : 10,
5981                gridLineColor: cssVar('--hc-gridLineColorC0C0C0'),
5982                maxPadding: 0.12
5983            },{
5984                title: { text: false },
5985                floor: 0,
5986                labels: {
5987                    format: "{value}"+hccompact_units['rain'],
5988                    style: { color: cssVar('--hc-hclanding_data_temp_rain') }
5989                },
5990                min:0,
5991                softMax: hccompact_units['rain']=="mm" ? 4 : 0.2,
5992                allowDecimals: true,
5993                tickAmount:5,
5994                zIndex: 10,
5995                gridLineColor: 'transparent',
5996                minorGridLineColor: 'transparent',
5997                opposite:true,  
5998                type: 'bar'
5999            },{
6000                title: { text: false },
6001                labels: { enabled: false },
6002                gridLineWidth: 1,
6003                softMax: 20000,
6004                min: 0,
6005                gridZIndex:2,
6006                zIndex: 5,
6007                minorGridLineColor: cssVar('--hc-gridLineColorCCCCCC'),
6008                allowDecimals: false,
6009                gridLineColor: cssVar('--hc-gridLineColorC0C0C0'),
6010            }],
6011            plotOptions: {
6012                series: {
6013                    stacking: 'normal'
6014                }
6015            },
6016            tooltip: {
6017                crosshairs: true,
6018                shared: true,
6019                useHTML: true,
6020                 shape: 'square',
6021                useHTML: true,
6022                outside: false,
6023                positioner: tooltipPositioner,
6024                formatter: function () { 
6025                	// fix for faulty highcharts tooltip recognition
6026                	var date_format = getDynDateFormat(this.x);
6027                	var s = '<span style="font-size:10px;">'+Highcharts.dateFormat(date_format, this.x)+ '</span> ';
6028                	var c=0;
6029                    $.each(this.points, function () {
6030                        c++;
6031                        if (this.y != 0.0 || c == 1 || c == 2) {
6032                            if (c != 4 && c != 5 && c != 6 && c != 2 && c != 3) {
6033                                s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> ' + this.series.name + ': ';
6034                                s += '<b>' + Highcharts.numberFormat(this.y, 1) + '</b> ' + ' ';
6035                            } else if (c == 2) {
6036                                s += '<br/>' + '<span style="color:' + cssVar('--hc-tooltip_blue') + '">' + '●' + '</span> ' + this.series.name + ': ';
6037                                s += '<b>' + Highcharts.numberFormat(this.y, 1) + '</b> ' + ' ';
6038                            } else {
6039                                var digits = 0;
6040                                if (c == 3 || c == 4) {
6041                                    digits = (hccompact_units['rain'] === 'in' ? 2 : 1);
6042                                }
6043                                s += '<br/>' + '<span style="color:' + cssVar('--hc-tooltip_grey') + '">' + '●' + '</span> ' + this.series.name + ': ';
6044                                s += '<b>' + Highcharts.numberFormat(this.y, digits) + '</b> ' + ' ';
6045                            }
6046                            if (c == 1 || c == 2) {
6047                                s += hccompact_units['temp'];
6048                            } else if (c == 5 || c == 6) {
6049                                s += hccompact_units['wind'];
6050                            } else {
6051                                s += hccompact_units['rain'];
6052                            }
6053                        }
6054                    });
6055            		i=highcharts_symbols_timestamps[this.x];
6056		            return '<div class="highcharts-tooltip"><table><tr><td>' + ttCols(s, this, 48) + '</td><td><img src="/images/symbole/sym_'+hccompact_data_symbols[i]+'.svg" width=32></img></td></tr></table></div>';
6057        		}
6058            },
6059            credits: { enabled: false },
6060            exporting: { enabled: false },
6061            series: hclanding_data_temp,
6062            reflow: true
6063        });
6064    }
6065};
6066
6067var sort_range_value = [0, 0];
6068var sort_range_start = 0;
6069var sort_range_end = 0;
6070var sort_slider = null;
6071var setupSortRangeSlider = function() {
6072    if(typeof hcensemble_heat_timestamps === 'undefined' || hcensemble_heat_timestamps.length < 2) return;
6073
6074    if(isEnsembleDurationParameter() && !isEnsembleDailyParameter()) {
6075        var plotBandMin = hcensemble_heat_timestamps[0];
6076        plotBandMin -= hcensemble_heat_timestamps[1] - hcensemble_heat_timestamps[0];
6077        hcensemble_heat_timestamps.unshift(plotBandMin);
6078    } else if(isEnsembleDurationParameter() && isEnsembleDailyParameter()) {
6079        var lastIndex = hcensemble_heat_timestamps.length - 1;
6080        var plotBandMax = hcensemble_heat_timestamps[lastIndex];
6081        plotBandMax += hcensemble_heat_timestamps[lastIndex] - hcensemble_heat_timestamps[lastIndex - 1];
6082        hcensemble_heat_timestamps.push(plotBandMax);
6083    }
6084
6085    sort_range_start = 0;
6086    sort_range_end = hcensemble_heat_timestamps.length - 1;
6087
6088    var el_start = $('#sort-range-slider-container').attr('data-start-ts');
6089    var el_end = $('#sort-range-slider-container').attr('data-end-ts');
6090    var isFullRange = $('#sort-range-slider-container').attr('data-full-range') == 1;
6091
6092    var timezone = $('#real-user-timezone').attr('data-value');
6093
6094    if(!isFullRange) {
6095        var newStartTs = 0;
6096        var newEndTs = 0;
6097        var newStartIndex = 0;
6098        var newEndIndex = 0;
6099    
6100        hcensemble_heat_timestamps.forEach(function(ts, index) {
6101    
6102            if(el_start != 'start') {
6103                if(Math.abs(ts - el_start) < Math.abs(newStartTs - el_start)) {
6104                    newStartTs = ts;
6105                    newStartIndex = index;
6106                }
6107            }
6108    
6109            if(el_end != 'end') {
6110                if(Math.abs(ts - el_end) < Math.abs(newEndTs - el_end)) {
6111                    newEndTs = ts;
6112                    newEndIndex = index;
6113                }
6114            }
6115    
6116        });
6117
6118        sort_range_value = [newStartIndex, newEndIndex];
6119
6120    } else {
6121        sort_range_value = [sort_range_start, sort_range_end];
6122    }
6123
6124    var moment_from_value = function(val) {
6125        if(val > sort_range_end)
6126            val = sort_range_end
6127        if(val < sort_range_start)
6128            val = sort_range_start
6129
6130        return moment(hcensemble_heat_timestamps[val]);
6131    }
6132
6133    var time_format = getTimezoneFormat('time');
6134    var date_format = getTimezoneFormat('shortdate', true);
6135
6136    var tooltipFix = function() {
6137        //Fix tooltip position
6138        var margin = 10;
6139
6140        var arrowPosX = $('#sort-range-slider').parent().find('.tooltip-main .tooltip-arrow').offset().left + $('#sort-range-slider').parent().find('.tooltip-main .tooltip-arrow').outerWidth() / 2;
6141        var tooltipWidth = $('#sort-range-slider').parent().find('.tooltip-main .tooltip-inner').outerWidth();
6142
6143        var windowWidth = $(window).width();
6144
6145        if(arrowPosX < tooltipWidth / 2 + margin) {
6146            var translate = tooltipWidth / 2 - arrowPosX + margin;
6147            $('#sort-range-slider').parent().find('.tooltip-main .tooltip-inner').css('transform', 'translateX('+translate+'px)');
6148        }
6149
6150        if(windowWidth - arrowPosX < tooltipWidth / 2 + margin) {
6151            var translate = -(tooltipWidth / 2 - (windowWidth - arrowPosX) + margin);
6152            $('#sort-range-slider').parent().find('.tooltip-main .tooltip-inner').css('transform', 'translateX('+translate+'px)');
6153        }
6154    }
6155
6156    var formatter = function(value) {
6157
6158        if(Array.isArray(value)) {
6159            var start_moment = moment_from_value(value[0]);
6160            var end_moment = moment_from_value(value[1]);
6161    
6162            var format = date_format + ' ' + time_format;
6163            var tooltip = '';
6164            if(end_moment > start_moment) {
6165                tooltip = start_moment.tz(timezone).format(format) + ' - ' + end_moment.tz(timezone).format(format);
6166            }
6167            else {
6168                tooltip = end_moment.tz(timezone).format(format) + ' - ' + start_moment.tz(timezone).format(format);
6169            }
6170
6171            return tooltip;
6172        } else {
6173            var moment_val = moment_from_value(value);
6174            return moment_val.tz(timezone).format('lll');
6175        }
6176    }
6177    var isSliding = false;
6178    var onSlideStart = function(event) {
6179        // sort_range_value[0] = sort_range_start;
6180        // sort_range_value[1] = sort_range_end;
6181        isSliding = true;
6182        onSlide(event, true);
6183    };
6184
6185    var onSlide = function(event, start) {
6186        //Update global vars
6187        var oldValue = sort_range_value;
6188        sort_range_value = event.value;
6189
6190        if(sort_range_value[0] != oldValue[0] || sort_range_value[1] != oldValue[1] || start) {
6191
6192            tooltipFix();
6193
6194            var start_moment = moment_from_value(sort_range_value[0]);
6195            var end_moment = moment_from_value(sort_range_value[1]);
6196            sortRangeUpdatePlotBands(start_moment, end_moment);
6197        }
6198
6199    };
6200
6201    var onSlideStop = function(event) {
6202        isSliding = false;
6203        if(!$('#sort-range-slider-container').is(':hover'))
6204            sortRangeUpdatePlotBands(false);
6205
6206        $('#forecast-sort-selector .mod-fc-ensemble-sort.btn-active').trigger('click');
6207    };
6208
6209
6210    sort_slider = $('#sort-range-slider').bootstrapSlider({
6211        range: true,
6212        min: sort_range_start,
6213        max: sort_range_end,
6214        value: sort_range_value,
6215        formatter: formatter,
6216    });
6217
6218    sort_slider.on('slide', onSlide);
6219    sort_slider.on('slideStart', onSlideStart);
6220    sort_slider.on('slideStop', onSlideStop);
6221
6222
6223    $('#sort-range-slider-container').hover(function() { onSlide({value: sort_range_value}, true); }, function() { if(!isSliding) sortRangeUpdatePlotBands(false); });
6224
6225}
6226
6227var sortRangeUpdatePlotBands = function(start_moment, end_moment) {
6228    if(!$('#ensemble_graph').length) return;
6229    var chart = $('#ensemble_graph').highcharts();
6230    var xAxis = chart.xAxis[0];
6231    var opacity = 1;
6232    if(xAxis) {
6233        if(start_moment) {
6234            xAxis.options.plotBands[0].to = +start_moment;
6235            xAxis.options.plotBands[1].from = +end_moment;
6236            xAxis.plotLinesAndBands[0].options.to = +start_moment;
6237            xAxis.plotLinesAndBands[1].options.from = +end_moment;
6238        } else {
6239            opacity = 0;
6240        }
6241
6242        xAxis.plotLinesAndBands[0].svgElem.animate({opacity: opacity});
6243        xAxis.plotLinesAndBands[1].svgElem.animate({opacity: opacity});
6244
6245        xAxis.plotLinesAndBands[0].render();
6246        xAxis.plotLinesAndBands[1].render();
6247    } 
6248}
6249
6250var showSortRangeSlider = function() {
6251    if(!$('#forecast-sort-selector .mod-fc-ensemble-sort.btn-active[data-value="none"]').length) {
6252        $('#forecast-sort-range-selector').fadeIn(300);
6253    } else {
6254        $('#forecast-sort-range-selector').fadeOut(300);
6255    }
6256}
6257
6258var plotGraphEnsembleLong = function() {
6259    if(!$('#ensemble_graph').length || typeof hcensemble_unit === 'undefined') return;
6260
6261    var timezone_id_local = typeof timezone_id !== 'undefined' ? timezone_id : null;
6262    Highcharts.setOptions({
6263        global: {
6264            timezone: timezone_id_local || $('#real-user-timezone').attr('data-value') || 'UTC'
6265        },
6266        lang: typeof hc_user_settings_lang !== 'undefined' ? hc_user_settings_lang : default_lang_settings
6267    });
6268    
6269    var hcensemble_yminortick=0.1;
6270    var hcensemble_ytick=1.0;
6271    var hcensemble_positive=0;
6272
6273    if     (hcensemble_unit==  "°C")hcensemble_yminortick=2.5;
6274    else if(hcensemble_unit==  "K")hcensemble_yminortick=2.5;
6275    else if(hcensemble_unit==  "°F")hcensemble_yminortick=5.0;
6276    else if(hcensemble_unit==  "mm")hcensemble_yminortick=1.0;
6277    else if(hcensemble_unit==  "cm")hcensemble_yminortick=1.0;
6278    else if(hcensemble_unit==  "in")hcensemble_yminortick=0.05;
6279    else if(hcensemble_unit== "hPa")hcensemble_yminortick=0.5;
6280    else if(hcensemble_unit=="mbar")hcensemble_yminortick=0.5;
6281    else if(hcensemble_unit=="m/s")hcensemble_yminortick=0.5;
6282    else if(hcensemble_unit=="inHg")hcensemble_yminortick=0.05;
6283    else if(hcensemble_unit=="km/h")hcensemble_yminortick=5;
6284    else if(hcensemble_unit=="kph")hcensemble_yminortick=5;
6285    else if(hcensemble_unit=="J/kg")hcensemble_yminortick=10;
6286    else if(hcensemble_unit== "mph")hcensemble_yminortick=5;
6287    else if(hcensemble_unit== "kn")hcensemble_yminortick=5;
6288    else if(hcensemble_unit== "dBz")hcensemble_yminortick=5;
6289    else if(hcensemble_unit== "%")hcensemble_yminortick=10;
6290
6291    if     (hcensemble_unit==   "mm")hcensemble_positive=1;
6292    else if(hcensemble_unit==   "cm")hcensemble_positive=1;
6293    else if(hcensemble_unit==   "in")hcensemble_positive=1;
6294    else if(hcensemble_unit== "km/h")hcensemble_positive=1;
6295    else if(hcensemble_unit== "kph")hcensemble_positive=1;
6296    else if(hcensemble_unit== "m/s")hcensemble_positive=1;
6297    else if(hcensemble_unit== "kn")hcensemble_positive=1;
6298    else if(hcensemble_unit== "Bft")hcensemble_positive=1;
6299    else if(hcensemble_unit== "J/kg")hcensemble_positive=1;
6300    else if(hcensemble_unit=="kg/m²")hcensemble_positive=1;
6301    else if(hcensemble_unit==  "mph")hcensemble_positive=1;
6302    else if(hcensemble_unit==  "dBz")hcensemble_positive=1;
6303
6304    if     (hcensemble_unit==  "°C")hcensemble_ytick=5;
6305    else if(hcensemble_unit==  "K")hcensemble_ytick=5;
6306    else if(hcensemble_unit==  "°F")hcensemble_ytick=10;
6307    else if(hcensemble_unit==  "mm")hcensemble_ytick=5.0;
6308    else if(hcensemble_unit==  "cm")hcensemble_ytick=1.0;
6309    else if(hcensemble_unit==  "in")hcensemble_ytick=0.1;
6310    else if(hcensemble_unit== "mph")hcensemble_ytick=10;
6311    else if(hcensemble_unit=="mbar")hcensemble_ytick=5;
6312    else if(hcensemble_unit=="m/s")hcensemble_ytick=5;
6313    else if(hcensemble_unit=="inHg")hcensemble_ytick=0.1;
6314    else if(hcensemble_unit=="km/h")hcensemble_ytick=15;
6315    else if(hcensemble_unit=="kph")hcensemble_ytick=15;
6316    else if(hcensemble_unit=="J/kg")hcensemble_ytick=50;
6317    else if(hcensemble_unit== "mph")hcensemble_ytick=10;
6318    else if(hcensemble_unit== "kn")hcensemble_ytick=10;
6319    else if(hcensemble_unit== "dBz")hcensemble_ytick=15;
6320    else if(hcensemble_unit== "%")hcensemble_ytick=20;
6321    var zeroline = 0;
6322    if(hcensemble_unit==  "°F") {
6323        zeroline = 32;
6324    }
6325    else if(hcensemble_unit=="K") {
6326        zeroline = 273.15;
6327    }
6328
6329    var highcharts_options= function(plot) {
6330        var ev = null;
6331        if (plot === true) {
6332            ev = {
6333                        load: function(){
6334                                if(!isEnsembleDailyParameter()) drawHourlyLabels(this,'ensemble');
6335                                if(!hcensembleheat_data && !isEnsembleDailyParameter()) drawNightShadows(this,30,'xl');
6336
6337                                var shouldFixLabels = true;
6338                                if(hcensembleheat_data) {
6339                                    if(isEnsembleDailyParameter() && !isEnsembleDurationParameter()) shouldFixLabels = false;
6340                                } else {
6341                                    if(isEnsembleDailyParameter()) shouldFixLabels = false;
6342                                }
6343
6344                                if(shouldFixLabels) fixLabels(this,'ensemble');
6345                        },
6346                        redraw: function(){
6347                                if(!isEnsembleDailyParameter()) drawHourlyLabels(this,'ensemble');
6348                                if(!hcensembleheat_data && !isEnsembleDailyParameter()) drawNightShadows(this,30,'xl');
6349
6350                                var shouldFixLabels = true;
6351                                if(hcensembleheat_data) {
6352                                    if(isEnsembleDailyParameter() && !isEnsembleDurationParameter()) shouldFixLabels = false;
6353                                } else {
6354                                    if(isEnsembleDailyParameter()) shouldFixLabels = false;
6355                                }
6356                                
6357                                if(shouldFixLabels) fixLabels(this,'ensemble');                        
6358                        }
6359                };
6360        }
6361        else {
6362            ev = {
6363                        load: function(){
6364                                fixLabels(this,'ensemble');
6365                        },
6366                        redraw: function(){
6367                                fixLabels(this,'ensemble');
6368                        }
6369                };
6370        }
6371
6372        var scrollablePlotArea = {};
6373        if(ensemble_model == 'ecmwf-46') {
6374            scrollablePlotArea.minWidth = 1600*3;
6375        }
6376        else if(ensemble_model == 'euro' || ensemble_model == 'ecmwf-aifs' || ensemble_model == 'usa' || ensemble_model == 'gem') {
6377            scrollablePlotArea.minWidth = 1600;
6378        }
6379        else if (ensemble_model == 'icon-eu' || ensemble_model == 'icon-world') {
6380            scrollablePlotArea.minWidth = 1600/3;
6381        }
6382
6383        hc_config = {
6384            chart: {
6385                marginLeft:75,
6386                spacingLeft:0,
6387                spacingBottom: 30,
6388                height: 320,
6389                events: ev,
6390                scrollablePlotArea: scrollablePlotArea
6391            },
6392            title: 'false',
6393            legend: {
6394                'enabled' : false
6395                /*useHTML: true,
6396                itemWidth: 100,
6397                align: 'left',
6398                width: 505,*/
6399            },
6400            plotOptions: {
6401                    heatmap: {
6402                        states: {
6403                            inactive: {
6404                                opacity: 1
6405                            }
6406                        },
6407                        pointPlacement: isEnsembleDurationParameter() && !isEnsembleDailyParameter() ? -0.5 : (isEnsembleDailyParameter() && isEnsembleDurationParameter() ? 'between' : 'on')
6408                    }
6409            },
6410            xAxis: {
6411                opposite:true,
6412                type: 'datetime',
6413                tickInterval: 24*36e5,
6414                // XL-Optik: Tagesgrenze als EINE dezente Linie, Raster hinter
6415                // den Daten statt darueber (frueher gridZIndex 2).
6416                gridLineWidth: 1,
6417                lineWidth: 0,
6418                lineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
6419                gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
6420                gridZIndex: 1,
6421                // Das 3h-Raster bleibt - bei Ensembles ist die Stundenorientierung
6422                // Teil der Information -, wird aber auf den hellen XL-Ton gesetzt.
6423                minorTickInterval: !isEnsembleDailyParameter() ? 3*36e5 : null,
6424                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
6425                minorGridLineWidth: 1,
6426                minorGridWidth: 1,
6427                min: hccompact_xmin,
6428                max: hccompact_xmax,
6429                dateTimeLabelFormats: {
6430                    hour: getDynHourDateFormat(),
6431                    day: getDynDayDateFormat()
6432                },
6433                labels: {
6434                    useHTML: true,
6435                    align: 'center',
6436                    formatter: function () {
6437                            var date_format = getDynDayDateFormat(this.value, this.chart.plotWidth);
6438                            return Highcharts.dateFormat(date_format, this.value);
6439                    },
6440                    style: {
6441                      color: cssVar('--hc-xl-label', '#79838D'),
6442                      fontSize: '12px'
6443                    }
6444                },
6445                tickLength: 0
6446            },
6447            yAxis: {
6448                title: {
6449                    text: false
6450                },
6451                labels: {
6452                    formatter: function() {
6453                        var digits=0;
6454                        if (hcensemble_unit === 'in') { digits=1; }
6455                        if (hcensemble_unit === 'inHg') { digits=1; }
6456                        return Highcharts.numberFormat(this.value,digits)+(hcensemble_unit === 'mbar' ? "":" ")+hcensemble_unit;
6457                    },
6458                    style: {
6459                        color: cssVar('--hc-xl-label', '#79838D'),
6460                        fontSize: '12px'
6461                    }
6462
6463                },
6464                plotLines: [{
6465                    value: zeroline,
6466                    width: 1,
6467                    color: cssVar('--hc-xl-zeroline', '#C3CAD1'),
6468                    zIndex: 2
6469                }],
6470                gridLineWidth: 1,
6471                gridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
6472                gridZIndex: 1,
6473                lineWidth: 0,
6474                // Waagerechte Zwischenlinien entfallen wie in XL - sie waren
6475                // reines Rauschen. Die Tick-Abstaende selbst bleiben unberuehrt.
6476                minorGridLineWidth: 0,
6477                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
6478                allowDecimals: false,
6479                minorTickInterval: hcensemble_yminortick,
6480                tickInterval: hcensemble_ytick,
6481            },
6482            tooltip: {
6483                crosshairs: true,
6484                shared: true,
6485                useHTML: true,
6486                shape: 'square',
6487                useHTML: true,
6488                positioner: function (w,h,p) {
6489                    this.chart.pointer.chartPosition = null;
6490                    return { x: -100, y: 0 };
6491                },
6492                formatter: function () {
6493                    // fix for faulty highcharts tooltip recognition
6494                    var date_format = getDynDateFormat(this.x);
6495                    var x_ts = this.x
6496                    if(isEnsembleDailyParameter()) {
6497                        date_format = getDynDayLongFormat(x_ts);
6498                    }
6499                    var s = '<span style="font-size:10px;">'+Highcharts.dateFormat(date_format, x_ts)+ '</span> ';
6500                    var c=0;
6501                    var max=-9e30;
6502                    var min= 9e30;
6503                    var mean=0;
6504                    var mean_run=null;
6505                    var main=null;
6506                    var high=0;
6507                    var low=0;
6508                    var count=0;
6509                    var p=null;
6510                    $.each(this.points, function () {
6511                        if(this.point.series.name=="Percentile"){p=this.point;}
6512                        if(this.point.series.name=="Mean"){mean_run=this.y;}
6513                        if(this.point.series.name!="Main"){
6514                            if(typeof this.point.low!=undefined)if(this.point.low<min)min=this.point.low;
6515                            if(typeof this.point.high!=undefined)if(this.point.high>max)max=this.point.high;
6516                            if(this.y<min)min=this.y;
6517                            if(this.y>max)max=this.y;
6518                            mean+=this.y;
6519                            count++;
6520                        }else{
6521                            main=this.y;
6522                        }
6523                    });
6524                    if (count>0) { mean=mean/count; }
6525                    if(p!=null){high=p.high;low=p.low; }
6526                    var digits = 0;
6527
6528                    if( hcensemble_unit=="mm" ||
6529                        hcensemble_unit=="cm" ||
6530                        hcensemble_unit=="hPa" ||
6531                        hcensemble_unit=="mbar" ||
6532                        hcensemble_unit=="m/s" ||
6533                        hcensemble_unit=="K" ||
6534                        hcensemble_unit=="°C" ||
6535                        ensemble_param == 'sonnenscheindauer24h' ){
6536                        digits = 1;
6537                    }
6538                    else if( hcensemble_unit=="in" ||
6539                            hcensemble_unit=="inHg" ){
6540                        digits = 2;
6541                    }
6542                    else if (ensemble_param === 'supercellindex') { digits=2; }
6543
6544                    var s1,s2,s3;
6545                    var s = '<span style="font-size:10px;">'+Highcharts.dateFormat(date_format, x_ts)+ '</span> <br/>';
6546                    var s0="";
6547                    if(displayLanguage()=="EN") {
6548                        if(main!=null){s0 = '<span style="font-size:12px;color:var(--color-text-black);"><span style="color:black;">&#9632;</span> Main run:</span> ' + '<b>'+Highcharts.numberFormat(main,digits) + '</b> ' + ' ' + hcensemble_unit + '<br/>';}
6549                        if(main!=null){s1 = '<span style="font-size:12px;color:var(--color-text);">'+(mean_run !== null ? '<span style="font-size:12px;color:#004a97">&#9679;</span> ':'')+'Ensemble mean:</span> '    + '<b>&nbsp;'+Highcharts.numberFormat(mean_run !== null ? mean_run:mean,digits) + '</b> ' + ' ' + hcensemble_unit + '<br/>';}
6550                        else          {s1 = '<span style="font-size:12px;color:var(--color-text);">'+(mean_run !== null ? '<span style="font-size:12px;color:#004a97">&#9679;</span> ':'')+'Ensemble mean:</span> '    + '<b>&nbsp;'+Highcharts.numberFormat(mean_run !== null ? mean_run:mean,digits) + '</b> ' + ' ' + hcensemble_unit + '<br/>';}
6551                        s2 = '<td>' + '<span style="font-size:12px;color:var(--hc-max-red);">Maximum:</span> ' + '</td><td><b>&nbsp;'+Highcharts.numberFormat(max,digits) + '</b> ' + ' ' + hcensemble_unit + '</td>';
6552                        s3 = '<td>' + '<span style="font-size:12px;color:#337ab7">Minimum:</span> ' + '</td><td><b>&nbsp;'+Highcharts.numberFormat(min,digits) + '</b> ' + ' ' + hcensemble_unit + '</td>';
6553                    }else{
6554                        if(main!=null){s0 = '<span style="font-size:12px;color:var(--color-text-black);"><span style="color:black;">&#9632;</span> Hauptlauf:</span> ' + '<b>'+Highcharts.numberFormat(main,digits) + '</b> ' + ' ' + hcensemble_unit + '<br/>';}
6555                        if(main!=null){s1 = '<span style="font-size:12px;color:var(--color-text);">'+(mean_run !== null ? '<span style="font-size:12px;color:#004a97">&#9679;</span> ':'')+'Ensemble Mittelwert:</span> ' + '<b>&nbsp;'+Highcharts.numberFormat(mean_run !== null ? mean_run:mean,digits) + '</b> ' + ' ' + hcensemble_unit + '<br/>';}
6556                        else          {s1 = '<span style="font-size:12px;color:var(--color-text);">'+(mean_run !== null ? '<span style="font-size:12px;color:#004a97">&#9679;</span> ':'')+' Ensemble Mittelwert:</span> ' + '<b>&nbsp;'+Highcharts.numberFormat(mean_run !== null ? mean_run:mean,digits) + '</b> ' + ' ' + hcensemble_unit + '<br/>';}
6557                        s2 = '<td>' + '<span style="font-size:12px;color:var(--hc-max-red);">Maximum:</span> '    + '</td><td><b>&nbsp;'+Highcharts.numberFormat(max,digits) + '</b> ' + ' ' + hcensemble_unit + '</td>';
6558                        s3 = '<td>' + '<span style="font-size:12px;color:#337ab7">Minimum:</span> '    + '</td><td><b>&nbsp;'+Highcharts.numberFormat(min,digits) + '</b> ' + ' ' + hcensemble_unit + '</td>';
6559                    }
6560                    if(typeof hcensemble_percentiles =='undefined' || typeof this.points[2]=== 'undefined')
6561                        $('#ensemble-tooltip').html('<div class="highcharts-tooltip">' +s+s0+s1+'<table><tr>'+s2+'</tr><tr>'+s3+ '</tr></table></div>');
6562                    else{
6563                        s2 += '<td>&nbsp;&nbsp;&nbsp;<span style="font-size:12px;color:var(--hc-max-red);">90% Percentile:</span> ' + '</td><td><b>&nbsp;'+Highcharts.numberFormat(high,digits) + '</b> ' + ' ' + hcensemble_unit + '</td>';
6564                        s3 += '<td>&nbsp;&nbsp;&nbsp;<span style="font-size:12px;color:#337ab7">10% Percentile:</span> ' + '</td><td><b>&nbsp;'+Highcharts.numberFormat(low,digits) + '</b> ' + ' ' + hcensemble_unit + '</td>';
6565                        $('#ensemble-tooltip').html('<div class="highcharts-tooltip2">' +s+s0+s1+'<table><tr>'+s2+'</tr><tr>'+s3+ '</tr></table></div>');
6566                    }
6567                    //return '<div class="highcharts-tooltip"></div>';
6568                    return '';
6569                }
6570            },
6571            credits: { enabled: false },
6572            exporting: {
6573                enabled: highcharts_exporting,
6574                allowHTML: true,
6575                filename: (
6576                    (document.querySelector('.panel-heading > span.title')?.innerText || '') + '_' + (document.querySelector('#ensemble-run')?.getAttribute('data-run') || '')).replace(/ü/g, 'ue').replace(/[^\w\s]/g, '').replace(/\s+/g, '_'),
6577                buttons: {
6578                    contextButton: {
6579                        menuItems: ["downloadPNG", "downloadSVG"],
6580                        symbolStroke: cssVar('--color-text'),
6581                        theme: {
6582                            fill: cssVar('--background-body'),
6583                            stroke: cssVar('--background-body'),
6584                            style: {
6585                                color: cssVar('--color-text'),
6586                                fontWeight: 'bold'
6587                            },
6588                            states: {
6589                                hover: {
6590                                    fill: cssVar('--background-body'),
6591                                    style: { color: cssVar('--background-body') }
6592                                },
6593                                select: {
6594                                    fill: cssVar('--background-body'),
6595                                    style: { color: cssVar('--background-body') }
6596                                }
6597                            }
6598                        }
6599                    }
6600                },
6601                chartOptions: {
6602                    chart: {
6603                        events: {
6604                            load: function() {
6605                                return;
6606                            },
6607                            redraw: function() {
6608                                return;
6609                            }
6610                        },
6611                        backgroundColor: cssVar('--background-body')
6612                    },
6613                    credits: {
6614                        enabled: true,
6615                        text: window.location.hostname.split('.').slice(-2).join('.'),
6616                        position: {
6617                            align: 'right',
6618                            verticalAlign: 'bottom',
6619                            x: -10,
6620                            y: -5
6621                        },
6622                        style: {
6623                            fontSize: '8px',
6624                            color: cssVar('--hc-label-textcolor')
6625                        }
6626                    },
6627                    title:  {
6628                        text: document.querySelector('.panel-heading > span.title')?.innerText+' ('+document.querySelector('#ensemble-run')?.getAttribute('data-run')+')',
6629                        align: 'left',
6630                        x: 5,
6631                        style: {
6632                            fontSize: '11px',
6633                            'color': cssVar('--color-text')
6634                        }
6635                    },
6636                    subtitle: {
6637                        text:document.getElementById('myHeadline')?.textContent,
6638                        align: 'left',
6639                        x: 5,
6640                        style: {
6641                            fontSize: '11px',
6642                            'color': cssVar('--color-text')
6643                        }
6644                    },
6645                    xAxis: {
6646                        labels: {
6647                            formatter: function () {
6648                                return Highcharts.dateFormat('%e.%m.', this.value);
6649                            },
6650                            style: {
6651                                fontSize: '7px',
6652                                'color': cssVar('--color-text')
6653                            },
6654                            x: 18,
6655                            y: -5
6656                        },
6657
6658                        tickInterval: 24 * 36e5 // Täglicher Tick-Intervall
6659                    },
6660                    yAxis: {
6661                        labels: {
6662                            style: {
6663                                fontSize: '8px',
6664                                'color': cssVar('--color-text')
6665                            },
6666                        }
6667                    }
6668                }
6669            },
6670            navigation: {
6671                buttonOptions: {
6672                    verticalAlign: 'bottom',
6673                    y: 25
6674                },
6675                contextButton: {
6676                    menuItems: ['downloadPNG', 'downloadSVG', 'separator', 'label']
6677                }
6678            },
6679            series: xlEnsembleSeries(hcensemblelong_data),
6680            reflow: true
6681        };
6682
6683        if(ensemble_param == 'relfeuchte' || ensemble_param == 'relfeuchte700' || ensemble_param == 'bedeckungsgrad') {
6684            hc_config.yAxis.min = 0;
6685            hc_config.yAxis.floor = 0;
6686            hc_config.yAxis.max = 100;
6687            hc_config.yAxis.ceiling = 100;
6688        }
6689
6690        return hc_config;
6691    };
6692
6693    if (typeof hcensemblelong_data != 'undefined' && hcensemblelong_data !== null) {
6694
6695        var ho=null;
6696        ho = highcharts_options(true);
6697        if(hcensemble_positive===1){  ho.yAxis.min=0; ho.yAxis.softMax=1;}
6698        if (ensemble_param === 'supercellindex') {  ho.yAxis.max=1; ho.yAxis.min=-1; }
6699        $('#ensemble_graph').highcharts(ho);
6700
6701        var ensembleChart = $('#ensemble_graph').highcharts();
6702
6703        if(ensembleChart.yAxis[0].dataMax === ensembleChart.yAxis[0].dataMin && ensembleChart.yAxis[0].dataMax === 0) {
6704            ensembleChart.update({
6705                yAxis: {
6706                    softMin: 0,
6707                    softMax: 0.0001
6708                }
6709            }, true, false, false);
6710        }
6711    }
6712    else if(typeof hcensembleheat_data != 'undefined' && hcensembleheat_data !== null) {
6713        var ho=null;
6714        ho = highcharts_options(true);
6715
6716        sortEnsembleHeatmapData();
6717
6718        var category_count = (hc_sorted_heat_cat.length - 1);
6719        var max_category_count = 53;
6720        var step = Math.ceil(category_count / max_category_count);
6721
6722        ho.chart.type = 'heatmap';
6723        ho.chart.height = Math.ceil((category_count / step) * 8 + 200);
6724        ho.chart.marginLeft = undefined;
6725        ho.chart.spacingBottom = 15;
6726        ho.chart.animation = {
6727            duration: 70
6728        };
6729
6730        if(ho.chart.scrollablePlotArea.minWidth) {
6731            ho.chart.scrollablePlotArea.minWidth *= 0.9375;
6732        }
6733
6734        if(isEnsembleDailyParameter()) {
6735            ho.chart.scrollablePlotArea.minWidth = hcensemble_heat_timestamps.length * 95;
6736        }
6737
6738        ho.xAxis.gridZIndex = 4;
6739        ho.xAxis.gridLineColor = 'rgba(0,0,0,0.2)';
6740        ho.xAxis.minorGridLineColor = 'rgba(0,0,0,0.1)';
6741
6742        var plotBandMin = hcensemble_heat_timestamps[0];
6743        var plotBandMax = hcensemble_heat_timestamps[sort_range_end];
6744        ho.xAxis.min = plotBandMin;
6745        ho.xAxis.max = plotBandMax;
6746        ho.xAxis.plotBands = [
6747            {
6748                borderColor: 'rgba(0,0,0,0.4)',
6749                borderWidth: 1,
6750                color: 'rgba(0,0,0,0.4)',
6751                from: plotBandMin,
6752                to: hcensemble_heat_timestamps[sort_range_value[0]],
6753                zIndex: 4
6754            },
6755            {
6756                borderColor: 'rgba(0,0,0,0.4)',
6757                borderWidth: 1,
6758                color: 'rgba(0,0,0,0.4)',
6759                from: hcensemble_heat_timestamps[sort_range_value[1]],
6760                to: plotBandMax,
6761                zIndex: 4
6762            }
6763        ];
6764
6765        ho.yAxis = {
6766            title: 'false',
6767            type: 'category',
6768            categories: hc_sorted_heat_cat,
6769            reversed: true,
6770            floor: 0,
6771            ceiling: hc_sorted_heat_cat.length - 1,
6772            gridLineColor: cssVar('--hc-gridLineColore6e6e6'),
6773            labels: {
6774                step: step,
6775                style: {
6776                    fontSize: '9px'
6777                    ,'color': cssVar('--color-text')
6778                }
6779            }
6780        };
6781        ho.legend.enabled = true;
6782        ho.legend.useHTML = true;
6783        ho.legend.width = 300;
6784        ho.legend.symbolWidth = 300;
6785        ho.legend.title = {text: $('#myHeadline').text() + (hcensemble_unit !== '' ? '(' + hcensemble_unit + ')' : ''), style: {fontSize: '11px','color': cssVar('--color-text')}};
6786        ho.colorAxis = ensembleColorAxis();
6787        ho.series = hc_sorted_heat_data;
6788        ho.tooltip = {
6789            shared: true,
6790            split: true,
6791            useHTML: true,
6792            padding: 4,
6793            outside: false,
6794            formatter: function () {
6795                var s = '<div style="margin-left: 8px;">'
6796                var x_ts = this.point.x
6797                var date_format = getDynDateFormat(x_ts);
6798                if(isEnsembleDailyParameter()) {
6799                    date_format = getDynDayLongFormat(x_ts);
6800                }
6801
6802                var member = hc_sorted_heat_cat_long[this.point.y];
6803                s += '<span style="font-size:10px;">'+Highcharts.dateFormat(date_format, x_ts)+ '</span> ';
6804
6805                var digits = 0;
6806
6807                if( hcensemble_unit=="mm" ||
6808                    hcensemble_unit=="cm" ||
6809                    hcensemble_unit=="hPa" ||
6810                    hcensemble_unit=="mbar" ||
6811                    hcensemble_unit=="m/s" ||
6812                    hcensemble_unit=="K" ||
6813                    hcensemble_unit=="°C" ||
6814                    ensemble_param=='sonnenscheindauer24h' ) {
6815                    digits = 1;
6816                }
6817                else if( hcensemble_unit=="in" ||
6818                        hcensemble_unit=="inHg" ){
6819                    digits = 2;
6820                }
6821                else if (ensemble_param === 'supercellindex') { digits=2; }
6822
6823                var val = Highcharts.numberFormat(this.point.value, digits);
6824
6825                s += '<br/>' + '<span style="color:' + this.point.color + '">' + '●' + '</span> '+ member + ': ' +
6826                '<b>'+ val + '</b> ' + hcensemble_unit;
6827                s += '</div>';
6828                return s;
6829            }
6830        };
6831
6832        $('#ensemble_graph').highcharts(ho);
6833
6834        setTimeout(function() {
6835            sortRangeUpdatePlotBands(false);
6836        }, 1000);
6837    }
6838    addGlobalChartScrollHint(document.querySelector('.panel-body' +
6839        ''));
6840};
6841
6842var isEnsembleDurationParameter = function(param) {
6843    if(!param) param = ensemble_param;
6844
6845    return $.inArray(ensemble_param, ['mintemperatur', 'maxtemperatur', 'niederschlag', 'niederschlag24h', 'schnee24h', 'niederschlagssumme', 'windboeen', 'wind', 'wind850', 'sonnenscheindauer24h']) !== -1;
6846}
6847
6848var isEnsembleDailyParameter = function(param) {
6849    if(!param) param = ensemble_param;
6850
6851    return $.inArray(ensemble_param, ['sonnenscheindauer24h', 'niederschlag24h', 'schnee24h']) !== -1;
6852}
6853
6854var hc_sorted_heat_data = [];
6855var hc_sorted_heat_cat = [];
6856var hc_sorted_heat_cat_long = [];
6857var sortEnsembleHeatmapData = function() {
6858    var sort = $('#forecast-sort-selector').attr('data-value') || 'none';
6859
6860    var series_array = hcensembleheat_data;
6861
6862    if(sort == 'none') {
6863        hc_sorted_heat_data = $.extend(true, [], hcensembleheat_data);
6864        hc_sorted_heat_cat = hcensemble_heat_categories;
6865        hc_sorted_heat_cat_long = hcensemble_heat_categories_long;
6866        return; 
6867    }
6868
6869    var poolSortValues = function(member_values) {
6870        if(member_values == null) return null;
6871        if(sort == 'avg') {
6872            return member_values.reduce(function(prev, cur) { return prev+cur.val; }, member_values[0].val) / member_values.length;
6873        }
6874        if(sort == 'min') {
6875            // Für Parameter wo es kontextuell Sinn macht, ist die Min-Sortierung der niedrigste Max-Wert anstelle des absoluten Min-Wertes
6876            if($.inArray(ensemble_param, ['niederschlag', 'niederschlagssumme', 'schnee', 'mlcape', 'reflektivitaet']) !== -1) {
6877                return -member_values.reduce(function(prev, cur) { return Math.max(prev,cur.val); }, member_values[0].val);
6878            } else {
6879                return -member_values.reduce(function(prev, cur) { return Math.min(prev,cur.val); }, member_values[0].val);
6880            }
6881        }
6882        if(sort == 'max') {
6883            return member_values.reduce(function(prev, cur) { return Math.max(prev,cur.val); }, member_values[0].val);
6884        }
6885    }
6886
6887    var member_array = [];
6888    var gapIndex = hcensemble_heat_categories.indexOf(''); // Gap Category
6889    member_array[gapIndex] = null;
6890
6891    var start_sort_ts = hcensemble_heat_timestamps[sort_range_value[0]];
6892    var end_sort_ts = hcensemble_heat_timestamps[sort_range_value[1]];
6893    var lessEquals = isEnsembleDurationParameter() && !isEnsembleDailyParameter();
6894    var greaterEquals = isEnsembleDurationParameter() && isEnsembleDailyParameter();
6895
6896    if((lessEquals || greaterEquals) && start_sort_ts == end_sort_ts){
6897        var count = hcensemble_heat_timestamps.length;
6898        if(sort_range_value[1] + 1 < count) {
6899            end_sort_ts = hcensemble_heat_timestamps[sort_range_value[1] + 1];
6900        } else {
6901            start_sort_ts = hcensemble_heat_timestamps[sort_range_value[0] - 1];
6902        }
6903    }
6904
6905    if($.isArray(series_array)) {
6906        series_array.forEach(function(series, sindex) {
6907            if($.isArray(series.data)) {
6908                series.data.forEach(function(data, dindex) {
6909                    var ts = data[0] || 0;
6910                    var y = data[1] || 0;
6911                    var val = data[2] || 0;
6912
6913                    if(lessEquals) {
6914                        if(ts <= start_sort_ts || ts > end_sort_ts) return;
6915                    } else if(greaterEquals) {
6916                        if(ts < start_sort_ts || ts >= end_sort_ts) return;
6917                    } else {
6918                        if(ts < start_sort_ts || ts > end_sort_ts) return;
6919                    }
6920
6921                    if(y < gapIndex) {
6922                        member_array[y] = null;
6923                        return;
6924                    } 
6925                        
6926                    if(typeof member_array[y] === 'undefined') member_array[y] = [];
6927                    
6928                    member_array[y].push({y: y, val: val});
6929                });
6930            }
6931        });
6932    }
6933
6934    var member_sorted = member_array.map(poolSortValues);
6935    var keys = keys = Object.keys(member_sorted);
6936    keys.sort(function(a,b) {
6937        if(member_sorted[b] === null && member_sorted[a] === null) return 0;
6938        if(member_sorted[a] === null && member_sorted[b] !== null) return -1;
6939        if(member_sorted[a] !== null && member_sorted[b] === null) return 1;
6940
6941        return member_sorted[b]-member_sorted[a]
6942    });
6943
6944    var member_sorted = member_sorted.filter(function (el) {
6945        return el != null;
6946    });
6947
6948    hc_sorted_heat_cat = [];
6949    hc_sorted_heat_cat_long = [];
6950    keys.forEach(function(index) {
6951        index = +index;
6952        if(typeof hcensemble_heat_categories[index] !== 'undefined') {
6953            hc_sorted_heat_cat.push(hcensemble_heat_categories[index]);
6954        }
6955        if(typeof hcensemble_heat_categories_long[index] !== 'undefined') {
6956            hc_sorted_heat_cat_long.push(hcensemble_heat_categories_long[index]);
6957        }
6958    });
6959
6960    hc_sorted_heat_data = [];
6961    if($.isArray(series_array)) {
6962        series_array.forEach(function(series, sindex) {
6963            hc_sorted_heat_data[sindex] = $.extend({}, series);
6964            hc_sorted_heat_data[sindex].data = [];
6965            if($.isArray(series.data)) {
6966                series.data.forEach(function(data, dindex) {
6967                    var ts = data[0] || 0;
6968                    var y = data[1] || 0;
6969                    var val = data[2] || 0;
6970
6971                    var sortedIndex = keys.indexOf(""+y);                    
6972                    hc_sorted_heat_data[sindex].data.push([ts, sortedIndex, val]);
6973                });
6974            }
6975        });
6976    }
6977}
6978
6979var ensembleColorAxis = function() {
6980
6981    //Special Funktion um die Ticks bei log-Farbachsen zu bestimmen
6982    var log2lin = function(num)  {
6983        const isNegative = num < 0;
6984
6985        let adjustedNum = Math.abs(num);
6986
6987        if (adjustedNum < 10) {
6988            adjustedNum += (10 - adjustedNum) / 10;
6989        }
6990
6991        const result = Math.log(adjustedNum) / Math.LN10;
6992        return isNegative ? -result : result;
6993    };
6994
6995    var axis_min = null;
6996    var axis_max = null;
6997    var log = false;
6998    var ticks = undefined;
6999    var tickInterval = undefined;
7000
7001    if     (hcensemble_unit==  "°C") { axis_min=-40; axis_max=50; ticks = [-30, -20, -10, 0, 10, 20, 30, 40]; }
7002    else if(hcensemble_unit==  "K") { axis_min=233.15; axis_max=323.15; }
7003    else if(hcensemble_unit==  "°F") { axis_min=-40; axis_max=122; ticks = [-22, -4, 14, 32, 50, 68, 86, 104]; }
7004    else if(hcensemble_unit== "hPa") { axis_min=900; axis_max=1062; ticks = [910, 930, 950, 970, 990, 1010, 1030, 1050]; }
7005    else if(hcensemble_unit=="mbar") { axis_min=900; axis_max=1062; ticks = [910, 930, 950, 970, 990, 1010, 1030, 1050]; }
7006    else if(hcensemble_unit=="inHg") { axis_min=26.58; axis_max=31.36; }
7007    else if(hcensemble_unit=="%") { axis_min=0; axis_max=100; }
7008
7009    var stops = null;
7010    if($.inArray(ensemble_param, ['mintemperatur', 'maxtemperatur', 'temperatur', 'taupunkt', 'temperatur1000', 'temperatur925', 'temperatur850', 'temperatur700', 'feuchtkugeltemperatur']) !== -1) {
7011        stops = [
7012            [0, '#ff6eff'],
7013            [0.21, '#32007f'],
7014            [0.22, '#00287f'],
7015            [0.31, '#1392ff'],
7016            [0.44, '#d9ecff'],
7017            [0.45, '#b1f1d6'],
7018            [0.51, '#07a127'],
7019            [0.62, '#f3fb01'],
7020            [0.71, '#f46d0b'],
7021            [0.78, '#af0f14'],
7022            [0.81, '#640000'],
7023            [0.89, '#fff0f0'],
7024            [1, '#6d6d6d'],
7025        ];
7026    }
7027    if($.inArray(ensemble_param, ['relfeuchte', 'relfeuchte700']) !== -1) {
7028        stops = [
7029            [0, '#ff9226'],
7030            [0.3, '#ffee32'],
7031            [0.6, '#9ac825'],
7032            [0.8, '#36a318'],
7033            [1, '#4a3f7c'],
7034        ];
7035    }
7036    else if($.inArray(ensemble_param, ['niederschlag', 'niederschlagssumme', 'niederschlag24h', 'schnee24h']) !== -1) {
7037
7038        if(hcensemble_unit==  "mm") { ticks = [log2lin(0.5), log2lin(2), log2lin(5), log2lin(10), log2lin(20), log2lin(50), log2lin(100)]; }
7039        else if(hcensemble_unit==  "in") { ticks = [log2lin(0.02), log2lin(0.2), log2lin(0.4), log2lin(0.6), log2lin(1), log2lin(1.5), log2lin(2), log2lin(3), log2lin(4)]; }
7040
7041        if(ensemble_model == 'rapid-id2' && ensemble_param == 'niederschlag') {
7042            if(hcensemble_unit==  "mm") { axis_min=0; axis_max=125; }
7043            else if(hcensemble_unit==  "in") { axis_min=0; axis_max=5; }
7044        } else if(ensemble_param == 'niederschlag' || ensemble_param == 'niederschlag24h' || ensemble_param == 'schnee24h') {
7045            if(hcensemble_unit==  "mm") { axis_min=0; axis_max=300; ticks.push(log2lin(200)); }
7046            else if(hcensemble_unit==  "in") { axis_min=0; axis_max=12; ticks = [log2lin(0.04), log2lin(0.5), log2lin(1), log2lin(1.5), log2lin(2), log2lin(3), log2lin(4), log2lin(6), log2lin(8), log2lin(10)]; }
7047        }
7048        else {
7049            if(hcensemble_unit==  "mm") { axis_min=0; axis_max=500; ticks.push(log2lin(200), log2lin(350)); }
7050            else if(hcensemble_unit==  "in") { axis_min=0; axis_max=20; ticks = [log2lin(0.04), log2lin(0.5), log2lin(1), log2lin(2), log2lin(3), log2lin(4), log2lin(6), log2lin(8), log2lin(10), log2lin(15)]; }
7051        }
7052        log = true;
7053
7054        var logMax = log2lin(axis_max);
7055        var stopMult = function(num) {
7056            return log2lin(num) / logMax;
7057        };
7058        var mult = axis_max / 125;
7059        stops = [
7060            [stopMult(0*mult), '#f0f0f0'],
7061            [stopMult(0.1*mult), '#b4d7ff'],
7062            [stopMult(4*mult), '#00367f'],
7063            [stopMult(5*mult), '#148f1b'],
7064            [stopMult(7*mult), '#fff42b'],
7065            [stopMult(10*mult), '#f06000'],
7066            [stopMult(20*mult), '#bf0000'],
7067            [stopMult(30*mult), '#64007f'],
7068            [stopMult(80*mult), '#f9e6ff'],
7069            [stopMult(125*mult), '#969696'],
7070        ];
7071    
7072    }
7073    else if(ensemble_param == 'schnee') {
7074        if(hcensemble_unit==  "cm") { axis_min=0; axis_max=400; ticks = [log2lin(0.5), log2lin(2), log2lin(5), log2lin(10), log2lin(20), log2lin(50), log2lin(100), log2lin(200), log2lin(300)]; }
7075        else if(hcensemble_unit==  "in") { axis_min=0; axis_max=160; ticks = [log2lin(0.2), log2lin(0.8), log2lin(2), log2lin(4), log2lin(8), log2lin(20), log2lin(40), log2lin(80), log2lin(120)]; }
7076
7077        log = true;
7078
7079        var logMax = log2lin(axis_max);
7080        var stopMult = function(num) {
7081            return log2lin(num) / logMax;
7082        };
7083        var mult = axis_max / 400;
7084        stops = [
7085            [stopMult(0*mult), '#f8f8f8'],
7086            [stopMult(0.9*mult), '#aaaac8'],
7087            [stopMult(1*mult), '#75baff'],
7088            [stopMult(9*mult), '#00327f'],
7089            [stopMult(10*mult), '#4b007f'],
7090            [stopMult(30*mult), '#c200fb'],
7091            [stopMult(60*mult), '#f4ceff'],
7092            [stopMult(150*mult), '#df093f'],
7093            [stopMult(400*mult), '#460000'],
7094        ];
7095
7096    } else if(ensemble_param == 'luftdruck') {
7097        var stopMult = function(num) {
7098            return (num - 900) / (1062 - 900);
7099        };
7100        stops = [
7101            [0, '#ff6eff'],
7102            [stopMult(962), '#32007f'],
7103            [stopMult(963), '#00287f'],
7104            [stopMult(978), '#00528f'],
7105            [stopMult(990), '#c7e4ff'],
7106            [stopMult(1002), '#07a127'],
7107            [stopMult(1020), '#f3fb01'],
7108            [stopMult(1032), '#e83709'],
7109            [stopMult(1044), '#780000'],
7110            [stopMult(1058), '#fff0f0'],
7111            [1, '#c5c5c5'],
7112        ];
7113    } else if(ensemble_param == 'geopotential') {
7114        if     (hcensemble_unit==  "m") { axis_min=4640; axis_max=6100; ticks = [4700, 5000, 5200, 5400, 5600, 5800, 6050]; }
7115        else if(hcensemble_unit==  "ft") { axis_min=15223; axis_max=20013; ticks = [15400, 16400, 17100, 17700, 18400, 19000, 19850]; }
7116
7117        var stopMult = function(num) {
7118            return (num - 4640) / (6100 - 4640);
7119        };
7120        stops = [
7121            [0, '#ff6eff'],
7122            [stopMult(5060), '#32007f'],
7123            [stopMult(5080), '#00287f'],
7124            [stopMult(5200), '#00528f'],
7125            [stopMult(5320), '#0082ef'],
7126            [stopMult(5500), '#d9ecff'],
7127            [stopMult(5520), '#aaf682'],
7128            [stopMult(5660), '#f4d90b'],
7129            [stopMult(5780), '#dc2708'],
7130            [stopMult(5980), '#640000'],
7131            [1, '#ffb4b4'],
7132        ];
7133    }
7134    else if($.inArray(ensemble_param, ['windboeen', 'wind', 'wind850']) !== -1) {
7135        if(hcensemble_unit=="m/s") { 
7136            axis_min=0; axis_max=51; tickInterval=4;
7137            var stopMult = function(num) { return (num - axis_min) / (axis_max - axis_min); };
7138
7139            stops = [
7140                [0, '#ffffff'],
7141                [stopMult(9), '#3c96f5'],
7142                [stopMult(12), '#1eb41e'],
7143                [stopMult(18), '#c8ffbe'],
7144                [stopMult(19.5), '#fffaaa'],
7145                [stopMult(24), '#ffa000'],
7146                [stopMult(25.5), '#ff6000'],
7147                [stopMult(31.5), '#a50000'],
7148                [stopMult(33), '#a900ba'],
7149                [stopMult(38.5), '#ffffff'],
7150                [1, '#643c32'],
7151            ];
7152        } else if(hcensemble_unit == 'Bft') {
7153            axis_min=0.5; axis_max=12.5; tickInterval=1;
7154            var stopMult = function(num) { return (num - axis_min) / (axis_max - axis_min); };
7155
7156            stops = [
7157                [0, '#7d7d7d'],
7158                [stopMult(4), '#68ac06'],
7159                [stopMult(6), '#b5d000'],
7160                [stopMult(8), '#ffe204'],
7161                [stopMult(9), '#f4880b'],
7162                [stopMult(10), '#ff3131'],
7163                [stopMult(11), '#ff3891'],
7164                [stopMult(12), '#ff8cbf'],
7165                [1, '#ff8cbf'],
7166            ];
7167        } else {
7168            if(hcensemble_unit=="km/h" || hcensemble_unit=="kph") { axis_min=0; axis_max=299.9; tickInterval = 30; }
7169            else if(hcensemble_unit== "mph") { axis_min=0; axis_max=186; tickInterval = 15; }
7170            else if(hcensemble_unit== "kn") { axis_min=0; axis_max=162; tickInterval = 15;}
7171
7172            var stopMult = function(num) {
7173                return (num - 0) / (300 - 0);
7174            };
7175
7176            stops = [
7177                [0, '#449900'],
7178                [stopMult(50), '#fafc22'],
7179                [stopMult(80), '#fb7929'],
7180                [stopMult(100), '#fc2256'],
7181                [stopMult(130), '#fc22f6'],
7182                [stopMult(200), '#ffffff'],
7183                [1, '#6969ff'],
7184            ];
7185        }
7186    } else if(ensemble_param == 'reflektivitaet') {
7187        axis_min=0; axis_max=71; tickInterval=5;
7188
7189        var stopMult = function(num) {
7190            return (num - axis_min) / (axis_max - axis_min);
7191        };
7192        stops = [
7193            [0, '#5f5f5f'],
7194            [stopMult(10), '#00e2ee'],
7195            [stopMult(19.99), '#0000f6'],
7196            [stopMult(20), '#00f700'],
7197            [stopMult(34.99), '#008f00'],
7198            [stopMult(35), '#ffff00'],
7199            [stopMult(40), '#e7b400'],
7200            [stopMult(45), '#ff6400'],
7201            [stopMult(50), '#ff0000'],
7202            [stopMult(59.99), '#9e0000'],
7203            [stopMult(60), '#ffc8ff'],
7204            [stopMult(70), '#8c008c'],
7205            [1, '#8c008c'],
7206        ];
7207    } else if(ensemble_param == 'supercellindex') {
7208        axis_min=-0.6; axis_max=1;
7209
7210        var stopMult = function(num) {
7211            return (num - axis_min) / (axis_max - axis_min);
7212        };
7213        stops = [
7214            [0, '#00367f'],
7215            [stopMult(-0.05), '#d2e9ff'],
7216            [stopMult(0), '#ffffff'],
7217            [stopMult(0.05), '#63ed07'],
7218            [stopMult(0.1), '#97c90e'],
7219            [stopMult(0.2), '#e8dc00'],
7220            [stopMult(0.3), '#fff42b'],
7221            [stopMult(0.4), '#ffa66a'],
7222            [stopMult(0.5), '#f84e78'],
7223            [stopMult(0.6), '#f71e54'],
7224            [stopMult(0.7), '#bf0000'],
7225            [stopMult(0.8), '#880000'],
7226            [stopMult(0.9), '#64007f'],
7227            [1, '#c200fb'],
7228        ];
7229    } else if(ensemble_param == 'mlcape') {
7230        axis_min=10.1; axis_max=12000;
7231        ticks = [log2lin(10), log2lin(20), log2lin(40), log2lin(100), log2lin(200), log2lin(400), log2lin(1000), log2lin(2000), log2lin(4000), log2lin(8000)];
7232        log = true;
7233
7234        var stopMult = function(num) {
7235            return (log2lin(num) - log2lin(axis_min)) / (log2lin(axis_max) - log2lin(axis_min));
7236        };
7237        // stopMult = function(num) {
7238        //     return (num - axis_min) / (axis_max - axis_min);
7239        // };
7240        stops = [
7241            [0, '#1e7800'],
7242            [stopMult(400), '#fafc22'],
7243            [stopMult(1000), '#fb7929'],
7244            [stopMult(1400), '#fc222f'],
7245            [stopMult(2400), '#fc22f6'],
7246            [stopMult(5000), '#fedffd'],
7247            [stopMult(8000), '#6969ff'],
7248            [1, '#6969ff'],
7249        ];
7250    } else if(ensemble_param == 'sonnenscheindauer24h') {
7251        axis_min=0; axis_max= hcensemble_max_sunshine || null;
7252
7253        stops = [
7254            [0, '#4c473b'], [0.5, '#d9aa36'], [1, '#fff72e'],
7255        ];
7256
7257        if(hcensemble_max_sunshine === 0) {
7258            stops = [
7259                [0, '#4c473b'], [1, '#4c473b'],
7260            ];
7261        }
7262    } else if(ensemble_param == 'bedeckungsgrad') {
7263        axis_min=0; axis_max= 100;
7264
7265        stops = [
7266            [0, '#ffea00'], [0.4, '#a29617'], [0.6, '#7d7520'], [1, '#323232'],
7267        ];
7268    } else if(ensemble_param == 'dirstrahlung' || ensemble_param == 'diffstrahlung') {
7269        axis_min=0; axis_max= 500;
7270
7271        if(typeof hcensemble_data_max !== 'undefined') {
7272            if(hcensemble_data_max > 500) axis_max = 700;
7273            if(hcensemble_data_max > 700) axis_max = 900;
7274            if(hcensemble_data_max > 900) axis_max = 1000;
7275        }
7276
7277        stops = [
7278            [0, '#4c473b'], [0.5, '#d9aa36'], [1, '#fff72e'],
7279        ];
7280    }
7281
7282    var colorAxis = {
7283        stops: stops,
7284        min: axis_min,
7285        max: axis_max,
7286        startOnTick: false,
7287        endOnTick: false,
7288        tickPositions: ticks,
7289        tickInterval: tickInterval,
7290        gridLineColor: cssVar('--hc-gridLineColorCCCCCC'),
7291        labels: {
7292            format: '{value}',
7293            style: {
7294                fontSize: "9px",
7295                'color': cssVar('--color-text')
7296            }
7297        },
7298        type: log ? 'logarithmic' : 'linear',
7299        allowNegativeLog: true
7300    };
7301
7302    if(!ticks) colorAxis.tickPixelInterval = 50;
7303
7304    // console.log(colorAxis);
7305    return colorAxis;
7306}
7307
7308var loadGraphEnsembleLong = function() {
7309	ajaxLoaderShow();
7310	var params = { 
7311		'city_id' : $('#city-id').val(), 
7312		'model' : ensemble_model,
7313                'model_view' : $('#forecast-view-selector').attr('data-value'),
7314		'param' : ensemble_param
7315	};
7316    hcensemblelong_data = null;
7317    hcensembleheat_data = null;
7318	$.get(get_url_path()+'/ajax/ensemble', params, function (data) {
7319                    $('#ensemble-response').html(data);
7320                    ajaxLoaderHide();
7321                    $('#myHeadline').css("visibility", 'visible');
7322                    $('#forecast-ensemble-parameters').css("visibility", 'visible');
7323                    setupSortRangeSlider();
7324                    plotGraphEnsembleLong();
7325                    showSortRangeSlider();
7326                    setAccListener();
7327                   });
7328};
7329
7330var plotWeatherTrend14days = function() {
7331    if (typeof hccompact_data_14days_maxmin != 'undefined') {
7332        var tempsize = 16;
7333        if ($('body').width()<768) {
7334            tempsize = 10;
7335        }
7336        var zeroline = 0;
7337        if(hccompact_units['temp']==  "°F") {
7338            zeroline = 32;
7339        }
7340        else if(hccompact_units['temp']=="K") {
7341            zeroline = 273.15;
7342        }
7343        Highcharts.chart('trend-14days', {
7344            chart: {
7345                type: 'line',
7346                height: 360,
7347                marginTop: 30,
7348                events: {
7349                        load: function(){
7350                                drawBlocksForWindSymbols(this);
7351                                //drawWindArrows(this);
7352                        },
7353                        redraw: function(){
7354                                drawBlocksForWindSymbols(this);
7355                                //drawWindArrows(this);
7356                        }
7357                }
7358            },
7359            title: false,
7360            xAxis: [{
7361                categories: hccompact_data_14days_xaxis,
7362                tickInterval: 1,
7363                gridLineWidth: 1,
7364                gridLineColor: cssVar('--hc-gridLineColorCCCCCC'),
7365                gridZIndex:2,
7366                offset: 0
7367            },{
7368                categories: hccompact_data_14days_xaxis2,
7369                tickInterval: 1,
7370                gridLineWidth: 1,
7371                gridLineColor: cssVar('--hc-gridLineColorCCCCCC'),
7372                gridZIndex:3,
7373                opposite:true,
7374                offset: 0,
7375                plotBands: hccompact_data_14days_weekend
7376            }],
7377            yAxis: {
7378                title: false,
7379                labels: {
7380                    enabled: false
7381                },
7382                max: hccompact_data_14days_yhigh+5,
7383                min: hccompact_data_14days_ylow,
7384                plotLines: [{
7385                    value: zeroline,
7386                    width: 2,
7387                    color: '#808080',
7388                    zIndex: 2
7389                }],
7390            },
7391            tooltip: {
7392                        crosshairs: true,
7393                        shared: true,
7394                        useHTML: true,
7395                        outside: false,
7396                        positioner: tooltipPositioner,
7397                        formatter: function() {
7398                            var s = [];
7399                            var counter=0;
7400                            var durchlauf=1;
7401                            var tmaxmin='';
7402                            var windtext='';
7403                            var counter=0;
7404                            var img = '', rain='',maxminv='';
7405                            s.push('<div class="w14-bg">');
7406                            $.each(this.points, function(i, p) {
7407                                if (counter===0 && typeof hccompact_data_14days_gusts[a] !== 'undefined'
7408                                        && typeof hccompact_data_14days_gusts_raw[a] !== 'undefined') {
7409                                    var a=this.series.data.indexOf( this.point );
7410                                    img = getWindSymbol(hccompact_data_14days_gusts_raw[a]);
7411                                    if (img.length>0) {
7412                                        if (displayFCUnitV() == 'kmh') {
7413                                            b = Math.round(Math.ceil(b/5)*5);
7414                                        }
7415                                        else {
7416                                            b = Math.round(b);
7417                                        }
7418                                        var einheit = $('#w-14days-data').attr('data-gunit');
7419                                        windtext = $('#w-14days-data').attr('data-gusts')+' '+b+(einheit === 'Bft' ? ' ':'')+einheit;
7420                                    }
7421                                }
7422                                if (counter===0 && typeof hccompact_data_14days_rsym !== 'undefined') {
7423                                    var a=this.series.data.indexOf( this.point );
7424                                    var b=hccompact_data_14days_tsym[a];
7425                                    var c=hccompact_data_14days_rsym[a];
7426                                    if (b !== 'null') {
7427                                        rain = b;
7428                                    }
7429                                    else if (c !== 'null') {
7430                                        rain = c;
7431                                    }
7432                                }
7433                                counter++;
7434                            });
7435
7436                            if (img.length>0 || rain.length>0) {
7437                                s.push('<div class="w14-s">');
7438                                if (rain.length>0) {
7439                                    s.push('<img src="/images/symbole/'+rain+'" alt="" /> ');
7440                                }
7441                                if (img.length>0) {
7442                                    s.push('<img src="/images/symbole/'+img+'" alt="'+windtext+'" />');
7443                                }
7444                                s.push('</div>');
7445                            }
7446
7447                            counter=0;
7448                            $.each(this.points, function(i, p) {
7449                                if (counter===0) {
7450                                    s.push('<div class="w14-date">'+p.x +'</div>');
7451                                    s.push('<div class="clearfix"></div>');
7452                                }
7453                                if (durchlauf === 1 || durchlauf === 2) {
7454                                    var a=this.series.data.indexOf( this.point );
7455                                    $.each(hccompact_data_14days_maxmin, function(j,q) {
7456                                        if (j === durchlauf) {
7457                                            if (typeof q.data !== 'undefined' && typeof q.data[a] !== 'undefined' && q.data[a] !== null) {
7458                                                if (durchlauf === 1) {
7459                                                    tmaxmin=$('#w-14days-data').attr('data-max'); //'Höchsttemperatur';
7460                                                    maxminv='max';
7461                                                }
7462                                                else {
7463                                                    tmaxmin=$('#w-14days-data').attr('data-min'); //'Tiefsttemperatur';
7464                                                    maxminv='min';
7465                                                }
7466                                                s.push('<div class="w14-tmaxmin">'+tmaxmin+': <span class="w-t'+maxminv+'-v">'+Highcharts.numberFormat(q.data[a],0)+hccompact_units['temp']+'</span></div>');
7467                                            }
7468                                        }
7469                                    });
7470                                    durchlauf++;
7471                                }
7472                                var min_max=-999, min_min=1000;
7473                                if (p.point.low < min_min) { min_min=p.point.low; }
7474                                if (p.point.high < min_min) { min_min=p.point.high; }
7475                                if (p.point.low > min_max) { min_max=p.point.low; }
7476                                if (p.point.high > min_max) { min_max=p.point.high; }
7477                                if (min_max !== -999 && min_min !== 1000) {
7478                                    s.push('<div class="w14-tmaxmin-range">'+p.series.name +' '+$('#w-14days-data').attr('data-from')+' '+Highcharts.numberFormat(min_min,0) +hccompact_units['temp']+' '+$('#w-14days-data').attr('data-to')+' ' +Highcharts.numberFormat(min_max,0) +hccompact_units['temp']+ '</div>');
7479                                }
7480                                counter++;
7481                            });
7482                            if (windtext.length>0) {
7483                                s.push(windtext);
7484                            }
7485                            counter=0;
7486                            $.each(this.points, function(i, p) {
7487                                if (counter===0 && typeof hccompact_data_14days_prob !== 'undefined') {
7488                                    var a=this.series.data.indexOf( this.point );
7489                                    if (hccompact_data_14days_word[a].length>0) {
7490                                        s.push('<div class="w14-prob">' +
7491                                                hccompact_data_14days_word[a] +'</div>');
7492                                    }
7493                                }
7494                                counter++;
7495                            });
7496                            s.push('</div>');
7497
7498                            return '<div class="highcharts-tooltip highcharts-tooltip-14">' + s.join('') + '</div>';
7499                        }
7500            },
7501            plotOptions: {
7502                line: {
7503                    dataLabels: {
7504                        enabled: true,
7505                        formatter: function () {
7506                            return Highcharts.numberFormat(this.y,0)+(hccompact_units['temp'] == 'K' ? '':'°');
7507                        },
7508                        style: {
7509                            fontSize: tempsize,
7510                            'color': cssVar('--color-text')
7511                        }
7512                    },
7513                    enableMouseTracking: false
7514                }
7515            },
7516            credits: { enabled: false },
7517            exporting: { enabled: false },
7518            series: hccompact_data_14days_maxmin
7519        });
7520    }
7521};
7522
7523var plotWeatherTrend14daysV2 = function() {
7524    if (typeof hc_data_14days_maxmin != 'undefined') {
7525        var tempsize = 16;
7526        if ($('body').width()<768) {
7527            tempsize = 10;
7528        }
7529        var zeroline = 0;
7530        if(hccompact_units['temp']==  "°F") {
7531            zeroline = 32;
7532        }
7533        else if(hccompact_units['temp']=="K") {
7534            zeroline = 273.15;
7535        }
7536        plotWeatherTrend14daysV2short(62);
7537
7538        var hc_axis_height = 0;
7539        Highcharts.chart('trend-14days-sun', {
7540            chart: {
7541                type: 'column',
7542                height: 220,
7543                marginTop:20,
7544                marginLeft:62,
7545                events: {
7546                        load: function(){
7547                                //yAxis Scaling
7548                                var topSpacing = 42+16+8;
7549                                var bottomSpacing = 4;
7550
7551                                hc_axis_height = this.plotHeight - topSpacing - bottomSpacing;
7552                                this.yAxis[0].update({height: hc_axis_height, top: topSpacing}, true);
7553                                drawBlocksForSunSymbolsV2(this);
7554                        },
7555                        redraw: function(){
7556                                //yAxis Scaling
7557                                var topSpacing = 42+16+8;
7558                                var bottomSpacing = 4;
7559
7560                                var yAxisHeight = this.plotHeight - topSpacing - bottomSpacing;
7561                                if(yAxisHeight !== hc_axis_height) {
7562                                    hc_axis_height = yAxisHeight;
7563                                    this.yAxis[0].update({height: hc_axis_height, top: topSpacing}, true);
7564                                }
7565                                drawBlocksForSunSymbolsV2(this);
7566                        }
7567                }
7568            },
7569            title: false,
7570            xAxis: [{
7571                categories: hc_data_14days_xaxis,
7572                tickInterval: 1,
7573                gridLineWidth: 1,
7574                gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
7575                lineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
7576                lineWidth: 1,
7577
7578                gridZIndex: 1,
7579                plotBands: hc_data_14days_weekend,
7580                labels: {
7581                    style: {
7582                        color: cssVar('--color-text')
7583                    }
7584                }
7585            }],
7586            yAxis: [{
7587                title: false,
7588                tickInterval: hc_data_14days_sun_high,
7589                minorTickInterval: 1,
7590                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
7591                gridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
7592
7593                // maxPadding: 0.5,
7594                //tickLength: 10,
7595                // max: hc_data_14days_sun_high,
7596                ceiling: hc_data_14days_sun_high,
7597                // endOnTick: false,
7598                // min: 0,
7599                floor: 0,
7600                top: 42+16+8,
7601                height: '55%',
7602                labels: {
7603                    formatter: function () {
7604                        return Highcharts.numberFormat(this.value, 0)+hccompact_units['sunhours'];
7605                    },
7606                    x: -7,
7607                    style: {
7608                        color: cssVar('--color-text')
7609                    }
7610                }
7611
7612            }, {
7613                title: false,
7614                opposite: true,
7615                labels: { enabled: false },
7616                tickAmount: 2,
7617                min: 0,
7618                gridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
7619                gridLineWidth: 1,
7620                max: hc_data_14days_sun_high
7621            }],
7622            credits: { enabled: false },
7623            exporting: { enabled: false },
7624            tooltip: tooltip14DaysTrendSun,
7625            series: hc_data_14days_sun
7626        });
7627
7628        var hc_axis_height = 0;
7629        Highcharts.chart('trend-14days-rain', {
7630            chart: {
7631                type: 'column',
7632                height: 230,
7633                marginTop:20,
7634                marginLeft:62,
7635                events: {
7636                        load: function(){
7637                            //yAxis Scaling
7638                                var topSpacing = 17+16+8;
7639                                var bottomSpacing = 4;
7640
7641                                hc_axis_height = this.plotHeight - topSpacing - bottomSpacing;
7642                                this.yAxis[0].update({height: hc_axis_height, top: topSpacing}, true);
7643                                drawBlocksForRainSymbolsV2(this);
7644                        },
7645                        redraw: function(){
7646                            //yAxis Scaling
7647                                var topSpacing = 17+16+8;
7648                                var bottomSpacing = 4;
7649
7650                                var yAxisHeight = this.plotHeight - topSpacing - bottomSpacing;
7651                                if(yAxisHeight !== hc_axis_height) {
7652                                    hc_axis_height = yAxisHeight;
7653                                    this.yAxis[0].update({height: hc_axis_height, top: topSpacing}, true);
7654                                }
7655                                drawBlocksForRainSymbolsV2(this);
7656                        }
7657                }
7658            },
7659            title: false,
7660            xAxis: [{
7661                categories: hc_data_14days_xaxis,
7662                tickInterval: 1,
7663                gridLineWidth: 1,
7664                gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
7665                gridZIndex: 1,
7666
7667                lineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
7668                lineWidth: 1,
7669                offset: 0,
7670                plotBands: hc_data_14days_weekend,
7671                labels: {
7672                    style: {
7673                        color: cssVar('--color-text')
7674                    }
7675                }
7676            }],
7677            yAxis: [{
7678                title: false,
7679                tickInterval: (hc_data_14days_rain_high <= 20 ? 5 : ((hc_data_14days_rain_high > 300 ? 100 : (hc_data_14days_rain_high > 120 ? 50 : 10)))),
7680                minorTickInterval: "auto",
7681                max: hc_data_14days_rain_high,
7682                floor: 0,
7683                top: 17+16+8,
7684                height: '55%',
7685                gridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
7686                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
7687                labels: {
7688                    formatter: function () {
7689                        var digits = 0;
7690                        if (hccompact_units['rain'] == 'in') { digits=1; }
7691                        return Highcharts.numberFormat(this.value, digits)+hccompact_units['rain'];
7692                    },
7693                    x: -7,
7694                    style: {
7695                        color: cssVar('--color-text')
7696                    }
7697                }
7698            }, {
7699                title: false,
7700                opposite: true,
7701                labels: { enabled: false },
7702                tickAmount: 2,
7703                min: 0,
7704                max: hc_data_14days_rain_high,
7705            }],
7706            credits: { enabled: false },
7707            exporting: { enabled: false },
7708            tooltip: tooltip14DaysTrendRain,
7709            series: hc_data_14days_rain
7710        });
7711
7712        var hc_axis_height = 0;
7713        Highcharts.chart('trend-14days-gusts', {
7714            chart: {
7715                type: 'column',
7716                height: 220,
7717                marginTop:20,
7718                marginLeft:62,
7719                events: {
7720                        load: function(){
7721                            //yAxis Scaling
7722                                var topSpacing = 20;
7723                                var bottomSpacing = 4;
7724
7725                                hc_axis_height = this.plotHeight - topSpacing - bottomSpacing;
7726                                this.yAxis[0].update({height: hc_axis_height, top: topSpacing}, true);
7727                                drawBlocksForGustSymbolsV2(this);
7728                        },
7729                        redraw: function(){
7730                            //yAxis Scaling
7731                                var topSpacing = 20;
7732                                var bottomSpacing = 4;
7733
7734                                var yAxisHeight = this.plotHeight - topSpacing - bottomSpacing;
7735                                if(yAxisHeight !== hc_axis_height) {
7736                                    hc_axis_height = yAxisHeight;
7737                                    this.yAxis[0].update({height: hc_axis_height, top: topSpacing}, true);
7738                                }
7739                                drawBlocksForGustSymbolsV2(this);
7740                        }
7741                }
7742            },
7743            title: false,
7744            xAxis: [{
7745                categories: hc_data_14days_xaxis,
7746                tickInterval: 1,
7747                gridLineWidth: 1,
7748                gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
7749                lineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
7750                lineWidth: 1,
7751                gridZIndex: 1,
7752                offset: 0,
7753                labels: {
7754                    style: {
7755                        color: cssVar('--color-text')
7756                    }
7757                },
7758                plotBands: hc_data_14days_weekend
7759            }],
7760            yAxis: [{
7761                title: false,
7762                tickInterval: hccompact_units['wind'] == 'Bft' ? 3 : (hc_data_14days_gusts_high <= 20 ? 5 : ((hc_data_14days_gusts_high > 300 ? 100 : (hc_data_14days_gusts_high >= 100 ? 50 : 20)))),
7763                minorTickInterval: hccompact_units['wind'] == 'Bft' ? 1 : "auto",
7764                max: hccompact_units['wind'] == 'Bft' ? 13 : hc_data_14days_gusts_high,
7765                min: 0,
7766                floor: 0,
7767                top: 20,
7768                gridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
7769                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
7770                height: '55%',
7771                labels: {
7772                    formatter: function () {
7773                        var digits = 0;
7774                        return hccompact_units['wind'] == 'Bft' ? (this.value <= 12 ? Highcharts.numberFormat(this.value, digits)+hccompact_units['wind'] : '') : Highcharts.numberFormat(this.value, digits)+hccompact_units['wind'];
7775                    },
7776                    x: -7,
7777                    style: {
7778                        color: cssVar('--color-text')
7779                    }
7780                }
7781            }, {
7782                title: false,
7783                opposite: true,
7784                labels: { enabled: false },
7785                tickAmount: 2,
7786                min: 0,
7787                max: hc_data_14days_gusts_high,
7788            }],
7789            credits: { enabled: false },
7790            exporting: { enabled: false },
7791            tooltip: tooltip14DaysTrendGusts,
7792            series: hc_data_14days_wind
7793        });
7794    }
7795};
7796
7797var plotWeatherTrend14daysV2short = function(mLeft) {
7798    var hc_axis_height = 0;
7799    if (typeof hc_data_14days_maxmin != 'undefined') {
7800        var tempsize = 16;
7801        if ($('body').width()<768) {
7802            tempsize = 10;
7803        }
7804        var zeroline = 0;
7805        if(hccompact_units['temp']==  "°F") {
7806            zeroline = 32;
7807        }
7808        else if(hccompact_units['temp']=="K") {
7809            zeroline = 273.15;
7810        }
7811        var mLabels = { enabled: false };
7812        if (typeof mLeft == 'undefined') {
7813            mLeft=0;
7814        }
7815        else {
7816            mLabels = {
7817                format: '{value}'+hccompact_units['temp'],
7818                x: -7,
7819                style: {
7820                    color: cssVar('--color-text')
7821                }
7822            };
7823        }
7824        Highcharts.chart('trend-14days', {
7825            chart: {
7826
7827                type: 'line',
7828                height: 360,
7829                marginTop: 22,
7830                marginLeft: mLeft,
7831                events: {
7832                        load: function(){
7833                            //yAxis Scaling
7834                            var topSpacing = 22;
7835                            var bottomSpacing = 16;
7836
7837                            hc_axis_height = this.plotHeight - topSpacing - bottomSpacing;
7838                            this.yAxis[0].update({height: hc_axis_height, top: topSpacing}, true);
7839                            drawBlocksFor14DaysTrendV2short(this);
7840                        },
7841                        redraw: function(){
7842                            var topSpacing = 22;
7843                            var bottomSpacing = 16;
7844
7845                            var yAxisHeight = this.plotHeight - topSpacing - bottomSpacing;
7846                            if(yAxisHeight !== hc_axis_height) {
7847                                hc_axis_height = yAxisHeight;
7848                                this.yAxis[0].update({height: hc_axis_height, top: topSpacing}, true);
7849                            }
7850                            drawBlocksFor14DaysTrendV2short(this);
7851                        },
7852                    render: function() {
7853                        // Vorherige Linie entfernen, falls vorhanden
7854                        if (this.customLeftBorder) this.customLeftBorder.destroy();
7855
7856                        // Neue Linie zeichnen
7857                        this.customLeftBorder = this.renderer.path([
7858                            'M', this.plotLeft, this.plotTop,
7859                            'L', this.plotLeft, this.plotTop + this.plotHeight
7860                        ])
7861                            .attr({
7862                                stroke: cssVar('--hc-xl-dayline', '#DCE2E8'),
7863                                'stroke-width': 1,
7864                                zIndex: 5
7865                            })
7866                            .add();
7867                    }
7868                }
7869            },
7870            title: false,
7871            xAxis: [{
7872                categories: hc_data_14days_xaxis,
7873                labels: {
7874                    style: {color : cssVar('--color-text')}
7875                },
7876                tickInterval: 1,
7877                gridLineWidth: 1,
7878                lineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
7879                lineWidth: 1,
7880                gridLineColor: cssVar('--hc-xl-dayline', '#DCE2E8'),
7881                gridZIndex: 1,
7882                offset: 0,
7883
7884                plotBands: hc_data_14days_weekend
7885            }],
7886            yAxis: [{
7887                title: false,
7888                labels: { enabled: false },
7889                max: hc_data_14days_yhigh,
7890                min: hc_data_14days_ylow,
7891                gridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
7892                minorGridLineColor: cssVar('--hc-xl-grid', '#EEF1F4'),
7893                tickInterval: hccompact_units['temp'] == '°F' ? 10: 5,
7894                minorTickInterval: hccompact_units['temp'] == '°F' ? 'auto': 1,
7895                plotLines: [{
7896                    value: zeroline,
7897                    width: 1,
7898                    color: cssVar('--hc-xl-zeroline', '#C3CAD1'),
7899                    zIndex: 2
7900                }],
7901                top: 22,
7902                height: '55%',
7903                labels: mLabels
7904            },
7905            {
7906                title: false,
7907                opposite: true,
7908                labels: { enabled: false },
7909            }],
7910            tooltip: tooltip14DaysTrend,
7911            plotOptions: {
7912                line: {
7913                    dataLabels: {
7914                        enabled: true,
7915                        formatter: function () {
7916                            return Highcharts.numberFormat(this.y,0)+(hccompact_units['temp'] == 'K' ? '':'°');
7917                        },
7918                        style: {
7919                            fontSize: tempsize,
7920                            'color': cssVar('--color-text')
7921                        }
7922                    },
7923                    enableMouseTracking: false
7924                }
7925            },
7926            credits: { enabled: false },
7927            exporting: { enabled: false },
7928            series: hc_data_14days_maxmin
7929        });
7930
7931    }
7932};
7933
7934var getDateForTitle = function(timeserie) {
7935     fromyear = new Date(timeserie[0].data[0][0]).getFullYear();
7936     untilyear = new Date(timeserie[0]['data'][timeserie[0]['data'].length - 1][0]).getFullYear();
7937     if (fromyear != untilyear) {
7938         frommonth = new Date(timeserie[0].data[0][0]).getMonth() +1;
7939         untilmonth = new Date(timeserie[0]['data'][timeserie[0]['data'].length - 1][0]).getMonth() +1;
7940         return frommonth+"/"+fromyear+" - "+untilmonth+"/"+untilyear+" ";
7941     } else {
7942         return fromyear+" ";
7943     }
7944}
7945var plotKlimaVergleich = function() {
7946
7947    var exportConfig = {
7948        enabled: highcharts_exporting
7949    };
7950
7951    var themedExportConfig = {
7952        enabled: highcharts_exporting,
7953        allowHTML: true,
7954        buttons: {
7955            contextButton: {
7956                symbolStroke: cssVar('--color-text'),
7957                theme: {
7958                    fill: cssVar('--background-body'),
7959                    stroke: cssVar('--background-body'),
7960                    style: {
7961                        color: cssVar('--color-text'),
7962                        fontWeight: 'bold'
7963                    },
7964                    states: {
7965                        hover: {
7966                            fill: cssVar('--background-body'),
7967                            style: { color: cssVar('--background-body') }
7968                        },
7969                        select: {
7970                            fill: cssVar('--background-body'),
7971                            style: { color: cssVar('--background-body') }
7972                        }
7973                    }
7974                }
7975            }
7976        },
7977        chartOptions: {
7978            title: {
7979                style: {
7980                    color: cssVar('--color-text')
7981                }
7982            },
7983            chart: {
7984                events: {
7985                    load: function () {
7986                        return;
7987                    },
7988                    redraw: function () {
7989                        return;
7990                    }
7991                },
7992                backgroundColor: cssVar('--background-body')
7993            },
7994        }
7995    };
7996
7997    if (typeof station_rr24_acc_data != 'undefined') {
7998        $('#klimavergleich-chart-rr24h').highcharts({
7999            chart: {
8000                height: 320//,
8001            },
8002            title: {text: ($('#klimavergleich-chart-rr24h').prev('label').length > 0) ? $('#klimavergleich-chart-rr24h').prev('label').text()+getDateForTitle(station_rr24_acc_data) : 'Chart'},
8003            legend: {
8004                useHTML: true   
8005            },
8006            xAxis: [{
8007                type: 'datetime',
8008                dateTimeLabelFormats: {
8009                    hour: false,
8010                    day: '%b %Y'
8011                },
8012                labels:{
8013                	useHTML: true,
8014    				align: 'center',
8015                	formatter: function () {
8016                                    return Highcharts.dateFormat('%b %Y', this.value);
8017    				}
8018                }
8019            },{
8020                type: 'datetime',
8021                dateTimeLabelFormats: {
8022                    hour: '%H:%M',
8023                    day: '%e. %b'
8024                },
8025                labels:{
8026                	useHTML: true,
8027    				align: 'center',
8028                	formatter: function () {
8029                		var date_format;
8030  						var day = Highcharts.dateFormat("%e", this.value);
8031   						var hour = Highcharts.dateFormat("%H", this.value);
8032    						if(hour%24==0)
8033    							date_format='%e. %b';
8034    						else
8035    							date_format='%H:%M';
8036    				  		return Highcharts.dateFormat(date_format, this.value);
8037    				}
8038                }
8039            }],
8040            yAxis: [{
8041                title: {
8042                    text: 'Monatssummen'
8043                },
8044                floor: 0,
8045                labels: {
8046                    format: "{value} mm"
8047                },
8048                min:0,
8049                softMax: 10,
8050                allowDecimals: false,
8051                minorTickInterval: 1,
8052                //gridLineColor: '#C0C0C0',
8053                tickAmount: 6
8054            },{
8055                title: {
8056                    text: 'Akkumulierter Niederschlag'
8057                },
8058                floor: 0,
8059                labels: {
8060                    format: "{value} mm"
8061                },
8062                opposite: true,
8063                min:0,
8064                softMax: 10,
8065                allowDecimals: false,
8066                minorTickInterval: 1,
8067                //gridLineColor: '#C0C0C0',
8068                tickAmount: 6
8069            }],
8070            tooltip: {
8071                crosshairs: true,
8072                shared: true,
8073                valueSuffix: ' mm',
8074                 shape: 'square',
8075                useHTML: true,
8076                zIndex: 50,
8077                /*positioner: function (w,h,p) {
8078                	if(p.plotX/this.chart.chartWidth>0.5)
8079                    	return { x: 65, y: 0 };
8080                    else
8081                    	return { x: this.chart.chartWidth-w-10, y: 0 };
8082                },*/
8083                formatter: function () { 
8084                	var date_format;
8085                	date_format="%A, den %e.%B";
8086                	var s = '<span style="font-size:10px">'+Highcharts.dateFormat(date_format, this.x)+ '</span> ';
8087		            this.points.sort( ordertooltip );
8088		            $.each(this.points, function () {
8089        		        s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ this.series.name + ': ' +
8090                	    '<b>'+Math.round(this.y*10)/10 + '</b> ' + ' mm';
8091            		});
8092		            return s;
8093        		}
8094            },
8095            credits: { enabled: false },
8096            exporting: { exportConfig },
8097            series: station_rr24_acc_data, 
8098            reflow: true
8099        });
8100    }
8101
8102    if (typeof station_kvrr24sum_data != 'undefined') {
8103        $('#klimavergleich-chart-single-rr24sum').highcharts({
8104            chart: {
8105                height: 400//,
8106            },
8107            title: {
8108                text:  ($('#klimavergleich-chart-single-rr24sum').prev('label').length > 0) ? $('#klimavergleich-chart-single-rr24sum').prev('label').text() + getDateForTitle(station_kvrr24sum_data) : 'Chart'
8109            },
8110            legend: {
8111                useHTML: true,
8112                itemStyle: {
8113                    color: cssVar('--hc-label-textcolor'),
8114                },
8115            },
8116            xAxis: {
8117                type: 'datetime',
8118                dateTimeLabelFormats: {
8119                    hour: '%H:%M',
8120                    day: '%e. %b'
8121                },
8122                labels:{
8123                	useHTML: true,
8124    				align: 'center',
8125                	formatter: function () {
8126                		var date_format;
8127  						var day = Highcharts.dateFormat("%e", this.value);
8128   						var hour = Highcharts.dateFormat("%H", this.value);
8129    						if(hour%24==0)
8130    							date_format='%e. %b';
8131    						else
8132    							date_format='%H:%M';
8133    				  		return Highcharts.dateFormat(date_format, this.value);
8134    				},
8135                    style: {
8136                        color: cssVar('--color-text'),
8137                    },
8138                },
8139                tickLength: 7,
8140                lineColor: cssVar('--hc-lineColor-bright'),
8141                tickColor: cssVar('--hc-lineColor-bright'),
8142            },
8143            yAxis: {
8144                title: false,
8145                floor: 0,
8146                labels: {
8147                    format: "{value} mm",
8148                    style: {
8149                        color: cssVar('--color-text'),
8150                    }
8151                },
8152                min:0,
8153                softMax: 100,
8154                allowDecimals: false,
8155                minorTickInterval: 10,
8156                //gridLineColor: '#C0C0C0',
8157                gridLineColor: cssVar('--hc-gridLineColor-bright'),
8158                minorGridLineColor: cssVar('--hc-minorGridLineColor-bright'),
8159                tickAmount: 6
8160            },
8161            tooltip: {
8162                crosshairs: true,
8163                shared: true,
8164                valueSuffix: ' mm',
8165                 shape: 'square',
8166                useHTML: true,
8167                zIndex: 50,
8168                /*positioner: function (w,h,p) {
8169                	if(p.plotX/this.chart.chartWidth>0.5)
8170                    	return { x: 65, y: 0 };
8171                    else
8172                    	return { x: this.chart.chartWidth-w-10, y: 0 };
8173                },*/
8174                formatter: function () {
8175                	var date_format;
8176                	date_format="%A, den %e.%B";
8177                	var s = '<span style="font-size:10px">'+Highcharts.dateFormat(date_format, this.x)+ '</span> ';
8178		            //this.points.sort( ordertooltip );
8179		            $.each(this.points, function () {
8180                                if (this.series.name !== 'arearange' && this.series.name !== 'arearange2' && this.series.name !== 'arearange3') {
8181                                    var anzeigename = this.series.name;
8182                                        anzeigename = anzeigename.replace('aktuell', Highcharts.dateFormat('%d.
8182%m.%Y', this.x));
8183                                    s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ anzeigename + ': ' +
8184                                        '<b>'+Math.round(this.y*10)/10 + '</b> ' + ' mm';
8185                                }
8186                            });
8187		            return s;
8188        		}
8189            },
8190            credits: { enabled: false },
8191            exporting: themedExportConfig,
8192            series: station_kvrr24sum_data,
8193            reflow: true
8194        });
8195    }
8196
8197    if (typeof station_kvrr24mon_data != 'undefined') {
8198        $('#klimavergleich-chart-single-rr24mon').highcharts({
8199            chart: {
8200                height: 400//,
8201            },
8202            title: {text:($('#klimavergleich-chart-single-rr24mon').prev('label').length > 0) ? $('#klimavergleich-chart-single-rr24mon').prev('label').text()+getDateForTitle(station_kvrr24mon_data) : 'Chart'},
8203            legend: {
8204                useHTML: true,
8205                itemStyle: {
8206                    color: cssVar('--hc-label-textcolor'),
8207                },
8208            },
8209            xAxis: {
8210                type: 'datetime',
8211                dateTimeLabelFormats: {
8212                    hour: false,
8213                    day: '%b %Y'
8214                },
8215                labels:{
8216                	useHTML: true,
8217    				align: 'center',
8218                	formatter: function () {
8219                                    return Highcharts.dateFormat('%b %Y', this.value);
8220    				},
8221                    style: {
8222                        color: cssVar('--color-text'),
8223                    },
8224                },
8225                tickLength: 7,
8226                lineColor: cssVar('--hc-lineColor-bright'),
8227                tickColor: cssVar('--hc-lineColor-bright'),
8228            },
8229            yAxis: {
8230                title: false,
8231                labels: {
8232                    format: "{value} mm",
8233                    style: {
8234                        color: cssVar('--color-text'),
8235                    }
8236                },
8237                floor: 0,
8238                min:0,
8239                softMax: 50,
8240                allowDecimals: false,
8241                minorTickInterval: 5,
8242                //gridLineColor: '#C0C0C0',
8243                gridLineColor: cssVar('--hc-gridLineColor-bright'),
8244                minorGridLineColor: cssVar('--hc-minorGridLineColor-bright'),
8245                tickAmount: 6
8246            },
8247            plotOptions: {
8248                column: {
8249                    borderColor: cssVar('--hc-bar-stroke-color'),
8250                }
8251            },
8252            tooltip: {
8253                crosshairs: true,
8254                shared: true,
8255                valueSuffix: ' mm',
8256                 shape: 'square',
8257                useHTML: true,
8258                zIndex: 50,
8259                /*positioner: function (w,h,p) {
8260                	if(p.plotX/this.chart.chartWidth>0.5)
8261                    	return { x: 65, y: 0 };
8262                    else
8263                    	return { x: this.chart.chartWidth-w-10, y: 0 };
8264                },*/
8265                formatter: function () {
8266                    var todayHint= Highcharts.dateFormat('%B %Y', this.x) == Highcharts.dateFormat('%B %Y', new Date())
8267                        ? ' ('+simpleTrans('partialData')+')'
8268                        : '';
8269                    var s = '<span style="font-size:10px">' + Highcharts.dateFormat('%B %Y', this.x) + todayHint +  '</span> ';
8270                    $.each(this.points, function () {
8271                        var anzeigename = this.series.name;
8272                        anzeigename = anzeigename.replace('aktuell', Highcharts.dateFormat('%B %Y', this.x));
8273                        s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> ' + anzeigename + ': ' +
8274                            '<b>' + Math.round(this.y * 10) / 10 + '</b> ' + ' mm' + todayHint;
8275                    });
8276                    return s;
8277        		}
8278            },
8279            credits: { enabled: false },
8280            exporting: themedExportConfig,
8281            series: station_kvrr24mon_data,
8282            reflow: true
8283        });
8284    }
8285
8286    if (typeof station_kvrr24mondiff_data != 'undefined') {
8287        $('#klimavergleich-chart-single-rr24mondiff').highcharts({
8288            chart: {
8289                height: 320//,
8290            },
8291            title: {text: ($('#klimavergleich-chart-single-rr24mondiff').prev('label').length > 0) ? $('#klimavergleich-chart-single-rr24mondiff').prev('label').text()+" "+getDateForTitle(station_kvrr24mondiff_data) : 'Chart'},
8292            legend: {
8293                useHTML: true,
8294                itemStyle: {
8295                    color: cssVar('--hc-label-textcolor'),
8296                },
8297            },
8298            xAxis: {
8299                type: 'datetime',
8300                dateTimeLabelFormats: {
8301                    hour: false,
8302                    day: '%b %Y'
8303                },
8304                labels:{
8305                    useHTML: true,
8306                    align: 'center',
8307                    formatter: function () {
8308                        return Highcharts.dateFormat('%b %Y', this.value);
8309                    },
8310                    style: {
8311                        color: cssVar('--color-text'),
8312                    },
8313                },
8314                tickLength: 7,
8315                lineColor: cssVar('--hc-lineColor-bright'),
8316                tickColor: cssVar('--hc-lineColor-bright'),
8317            },
8318            yAxis: {
8319                title: false,
8320                labels: {
8321                    format: "{value} mm",
8322                    style: {
8323                        color: cssVar('--color-text'),
8324                    }
8325                },
8326                softMin: -50,
8327                softMax:  50,
8328                allowDecimals: false,
8329                minorTickInterval: 5,
8330                //gridLineColor: '#C0C0C0',
8331                gridLineColor: cssVar('--hc-gridLineColor-bright'),
8332                minorGridLineColor: cssVar('--hc-minorGridLineColor-bright'),
8333                tickAmount: 6
8334            },
8335            plotOptions: {
8336                column: {
8337                    borderColor: cssVar('--hc-bar-stroke-color'),
8338                }
8339            },
8340            tooltip: {
8341                crosshairs: true,
8342                shared: true,
8343                valueSuffix: ' mm',
8344                 shape: 'square',
8345                useHTML: true,
8346                zIndex: 50,
8347                /*positioner: function (w,h,p) {
8348                	if(p.plotX/this.chart.chartWidth>0.5)
8349                    	return { x: 65, y: 0 };
8350                    else
8351                    	return { x: this.chart.chartWidth-w-10, y: 0 };
8352                },*/
8353                formatter: function () {
8354                    var todayHint= Highcharts.dateFormat('%B %Y', this.x) == Highcharts.dateFormat('%B %Y', new Date())
8355                        ? ' ('+simpleTrans('partialData')+')'
8356                        : '';var s = '<span style="font-size:10px">'+Highcharts.dateFormat('%B %Y', this.x)+ todayHint + '</span> ';
8357		            $.each(this.points, function () {
8358                                var plus = '';
8359                                if (this.y>0) { plus= '+'; }
8360                                var anzeigename = this.series.name;
8361                                    anzeigename = anzeigename.replace('aktuell', Highcharts.dateFormat('%B %Y', this.x));
8362
8363        		        s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ anzeigename + ': ' +
8364                	    '<b>'+plus+Math.round(this.y*10)/10 + '</b> ' + ' mm' + todayHint;
8365            		});
8366		            return s;
8367        		}
8368            },
8369            credits: { enabled: false },
8370            exporting: themedExportConfig,
8371            series: station_kvrr24mondiff_data,
8372            reflow: true
8373        });
8374    }
8375
8376
8377    if (typeof station_tmp2m_acc_data != 'undefined') {
8378        $('#klimavergleich-chart-tmp2m').highcharts({
8379            chart: {
8380                height: 320//,
8381            },
8382            title: {text: ($('#klimavergleich-chart-tmp2m').prev('label').length > 0) ? $('#klimavergleich-chart-tmp2m').prev('label').text()+" "+getDateForTitle(station_tmp2m_acc_data) : 'Chart'},
8383            legend: {
8384                useHTML: true   
8385            },
8386            xAxis: [{
8387                type: 'datetime',
8388                dateTimeLabelFormats: {
8389                    hour: false,
8390                    day: '%b %Y'
8391                },
8392                labels:{
8393                	useHTML: true,
8394    				align: 'center',
8395                	formatter: function () {
8396                                    return Highcharts.dateFormat('%b %Y', this.value);
8397    				}
8398                }
8399            },{
8400                type: 'datetime',
8401                dateTimeLabelFormats: {
8402                    hour: '%H:%M',
8403                    day: '%e. %b'
8404                },
8405                labels:{
8406                	useHTML: true,
8407    				align: 'center',
8408                	formatter: function () {
8409                		var date_format;
8410  						var day = Highcharts.dateFormat("%e", this.value);
8411   						var hour = Highcharts.dateFormat("%H", this.value);
8412    						if(hour%24==0)
8413    							date_format='%e. %b';
8414    						else
8415    							date_format='%H:%M';
8416    				  		return Highcharts.dateFormat(date_format, this.value);
8417    				}
8418                }
8419            }],
8420            yAxis: [{
8421                title: {
8422                    text: 'Grünlandtemperatursumme'
8423                },
8424                floor: 0,
8425                labels: {
8426                    format: "{value}"
8427                },
8428                opposite: true,
8429                min:0,
8430                softMax: 400,
8431                allowDecimals: false,
8432                minorTickInterval: 1,
8433                //gridLineColor: '#C0C0C0',
8434                tickAmount: 6
8435            },{
8436                title: {
8437                    text: 'Durchschnittstemperatur'
8438                },
8439                //floor: 0,
8440                labels: {
8441                    format: "{value}°C"
8442                },
8443                softMin:0,
8444                softMax: 20,
8445                allowDecimals: false,
8446                minorTickInterval: 1,
8447                //gridLineColor: '#C0C0C0',
8448                tickAmount: 6
8449            }],
8450            tooltip: {
8451                crosshairs: true,
8452                shared: true,
8453                valueSuffix: '°C',
8454                 shape: 'square',
8455                useHTML: true,
8456                zIndex: 50,
8457                /*positioner: function (w,h,p) {
8458                	if(p.plotX/this.chart.chartWidth>0.5)
8459                    	return { x: 65, y: 0 };
8460                    else
8461                    	return { x: this.chart.chartWidth-w-10, y: 0 };
8462                },*/
8463                formatter: function () { 
8464                	var date_format;
8465                	date_format="%A, den %e.%B";
8466                	var s = '<span style="font-size:10px">'+Highcharts.dateFormat(date_format, this.x)+ '</span> ';
8467		            this.points.sort( ordertooltip );
8468		            $.each(this.points, function () {
8469        		        s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ this.series.name + ': ' +
8470                	    '<b>'+Math.round(this.y*10)/10 + '</b> ' + '°C';
8471            		});
8472		            return s;
8473        		}
8474            },
8475            credits: { enabled: false },
8476            exporting: { exportConfig },
8477            series: station_tmp2m_acc_data, 
8478            reflow: true
8479        });
8480    }
8481
8482    if (typeof station_kvtmean_data != 'undefined') {
8483        $('#klimavergleich-chart-single-tmean').highcharts({
8484            chart: {
8485                height: 400//,
8486            },
8487            title: {text:($('#klimavergleich-chart-single-tmean').prev('label').length > 0) ? $('#klimavergleich-chart-single-tmean').prev('label').text()+" "+getDateForTitle(station_kvtmean_data) : 'Chart'},
8488            legend: {
8489                useHTML: true,
8490                itemStyle: {
8491                    color: cssVar('--hc-label-textcolor'),
8492                },
8493            },
8494            xAxis: {
8495                type: 'datetime',
8496                dateTimeLabelFormats: {
8497                    hour: '%H:%M',
8498                    day: '%e. %b'
8499                },
8500                labels:{
8501                	useHTML: true,
8502    				align: 'center',
8503                	formatter: function () {
8504                		var date_format;
8505  						var day = Highcharts.dateFormat("%e", this.value);
8506   						var hour = Highcharts.dateFormat("%H", this.value);
8507    						if(hour%24==0)
8508    							date_format='%e. %b';
8509    						else
8510    							date_format='%H:%M';
8511    				  		return Highcharts.dateFormat(date_format, this.value);
8512    				},
8513                    style: {
8514                        color: cssVar('--color-text'),
8515                    },
8516                },
8517                tickLength: 7,
8518                lineColor: cssVar('--hc-lineColor-bright'),
8519                tickColor: cssVar('--hc-lineColor-bright'),
8520            },
8521            yAxis: {
8522                title: false,
8523                //floor: 0,
8524                labels: {
8525                    format: "{value}°C",
8526                    style: {
8527                        color: cssVar('--color-text'),
8528                    }
8529                },
8530                softMin:-20,
8531                softMax: 30,
8532                allowDecimals: false,
8533                minorTickInterval: 1,
8534                tickInterval: 5,
8535                //gridLineColor: '#C0C0C0',
8536                //tickAmount: 6
8537                gridLineColor: cssVar('--hc-gridLineColor-bright'),
8538                minorGridLineColor: cssVar('--hc-minorGridLineColor-bright'),
8539            },
8540            tooltip: {
8541                crosshairs: true,
8542                shared: true,
8543                valueSuffix: '°C',
8544                 shape: 'square',
8545                useHTML: true,
8546                zIndex: 50,
8547                /*positioner: function (w,h,p) {
8548                	if(p.plotX/this.chart.chartWidth>0.5)
8549                    	return { x: 65, y: 0 };
8550                    else
8551                    	return { x: this.chart.chartWidth-w-10, y: 0 };
8552                },*/
8553                formatter: function () {
8554                	var date_format;
8555                	date_format="%A, den %e.%B";
8556                	var s = '<span style="font-size:10px">'+Highcharts.dateFormat(date_format, this.x)+ '</span> ';
8557		            $.each(this.points, function () {
8558                                if (this.series.name !== 'arearange' && this.series.name !== 'arearange2' && this.series.name !== 'arearange3') {
8559                                    var anzeigename = this.series.name;
8560                                    anzeigename = anzeigename.replace('aktuell', Highcharts.dateFormat('%d.
8560%m.%Y', this.x));
8561                                    s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ anzeigename + ': ' +
8562                                    '<b>'+Math.round(this.y*10)/10 + '</b> ' + '°C';
8563                                }
8564            		});
8565		            return s;
8566        		}
8567            },
8568            credits: { enabled: false },
8569            exporting: themedExportConfig,
8570            series: station_kvtmean_data,
8571            reflow: true
8572        });
8573    }
8574
8575    if (typeof station_kvmon_data != 'undefined') {
8576        $('#klimavergleich-chart-single-tmean-month').highcharts({
8577            chart: {
8578                height: 400//,
8579            },
8580            title: {
8581                text: ($('#klimavergleich-chart-single-tmean-month').prev('label').length > 0) ? $('#klimavergleich-chart-single-tmean-month').prev('label').text()+" "+getDateForTitle(station_kvmon_data) : 'Chart'
8582            },
8583            legend: {
8584                useHTML: true,
8585                itemStyle: {
8586                    color: cssVar('--hc-label-textcolor'),
8587                },
8588            },
8589            xAxis: {
8590                type: 'datetime',
8591                dateTimeLabelFormats: {
8592                    hour: '%H:%M',
8593                    day: '%e. %b'
8594                },
8595                labels:{
8596                	useHTML: true,
8597    				align: 'center',
8598                	formatter: function () {
8599    				  		return Highcharts.dateFormat("%b %Y", this.value);
8600    				},
8601                    style: {
8602                        color: cssVar('--color-text'),
8603                    },
8604                },
8605                tickLength: 7,
8606                lineColor: cssVar('--hc-lineColor-bright'),
8607                tickColor: cssVar('--hc-lineColor-bright'),
8608            },
8609            yAxis: {
8610                title: false,
8611                //floor: 0,
8612                labels: {
8613                    format: "{value}°C",
8614                    style: {
8615                        color: cssVar('--color-text'),
8616                    }
8617                },
8618                softMin: 0,
8619                softMax: 30,
8620                allowDecimals: false,
8621                minorTickInterval: 5,
8622                tickInterval: 5,
8623                //gridLineColor: '#C0C0C0',
8624                //tickAmount: 6
8625                gridLineColor: cssVar('--hc-gridLineColor-bright'),
8626                minorGridLineColor: cssVar('--hc-minorGridLineColor-bright'),
8627            },
8628            plotOptions: {
8629                column: {
8630                    borderColor: cssVar('--hc-bar-stroke-color'),
8631                }
8632            },
8633            tooltip: {
8634                crosshairs: true,
8635                shared: true,
8636                valueSuffix: '°C',
8637                 shape: 'square',
8638                useHTML: true,
8639                zIndex: 50,
8640                /*positioner: function (w,h,p) {
8641                	if(p.plotX/this.chart.chartWidth>0.5)
8642                    	return { x: 65, y: 0 };
8643                    else
8644                    	return { x: this.chart.chartWidth-w-10, y: 0 };
8645                },*/
8646                formatter: function () {
8647                    var todayHint= Highcharts.dateFormat('%B %Y', this.x) == Highcharts.dateFormat('%B %Y', new Date())
8648                        ? ' ('+simpleTrans('partialData')+')'
8649                        : '';
8650                	var s = '<span style="font-size:10px">'+Highcharts.dateFormat("%B %Y", this.x)+ todayHint + '</span> ';
8651		            $.each(this.points, function () {
8652                                if (this.series.name !== 'arearange') {
8653                                    var anzeigename = this.series.name;
8654                                    anzeigename = anzeigename.replace('aktuell', Highcharts.dateFormat('%B %Y', this.x));
8655                                    s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ anzeigename + ': ' +
8656                                    '<b>'+Math.round(this.y*10)/10 + '</b> ' + '°C' + todayHint;
8657                                }
8658            		});
8659		            return s;
8660        		}
8661            },
8662            credits: { enabled: false },
8663            exporting: themedExportConfig,
8664            series: station_kvmon_data,
8665            reflow: true
8666        });
8667    }
8668
8669    if (typeof station_kvmon_data_diff != 'undefined') {
8670        $('#klimavergleich-chart-single-anomaly-month').highcharts({
8671            chart: {
8672                height: 260//,
8673            },
8674            title: {text:($('#klimavergleich-chart-single-anomaly-month').prev('label').length > 0) ? $('#klimavergleich-chart-single-anomaly-month').prev('label').text()+" "+getDateForTitle(station_kvmon_data_diff) : 'Chart'},
8675            legend: {
8676                useHTML: true,
8677                itemStyle: {
8678                    color: cssVar('--hc-label-textcolor'),
8679                },
8680            },
8681            xAxis: {
8682                type: 'datetime',
8683                dateTimeLabelFormats: {
8684                    hour: '%H:%M',
8685                    day: '%e. %b'
8686                },
8687                labels:{
8688                	useHTML: true,
8689    				align: 'center',
8690                	formatter: function () {
8691    				  		return Highcharts.dateFormat("%b %Y", this.value);
8692    				},
8693                    style: {
8694                        color: cssVar('--color-text'),
8695                    },
8696                },
8697                tickLength: 7,
8698                lineColor: cssVar('--hc-lineColor-bright'),
8699                tickColor: cssVar('--hc-lineColor-bright'),
8700            },
8701            yAxis: {
8702                title: false,
8703                //floor: 0,
8704                labels: {
8705                    format: "{value}°C",
8706                    style: {
8707                        color: cssVar('--color-text'),
8708                    },
8709                },
8710                softMin: -5,
8711                softMax: 5,
8712                allowDecimals: false,
8713                minorTickInterval: 1,
8714                tickInterval: 5,
8715                //gridLineColor: '#C0C0C0',
8716                //tickAmount: 6
8717                gridLineColor: cssVar('--hc-gridLineColor-bright'),
8718                minorGridLineColor: cssVar('--hc-minorGridLineColor-bright'),
8719            },
8720            plotOptions: {
8721                column: {
8722                    borderColor: cssVar('--hc-bar-stroke-color'),
8723                }
8724            },
8725            tooltip: {
8726                crosshairs: true,
8727                shared: true,
8728                valueSuffix: '°C',
8729                 shape: 'square',
8730                useHTML: true,
8731                zIndex: 50,
8732                /*positioner: function (w,h,p) {
8733                	if(p.plotX/this.chart.chartWidth>0.5)
8734                    	return { x: 65, y: 0 };
8735                    else
8736                    	return { x: this.chart.chartWidth-w-10, y: 0 };
8737                },*/
8738                formatter: function () {
8739                    var todayHint= Highcharts.dateFormat('%B %Y', this.x) == Highcharts.dateFormat('%B %Y', new Date())
8740                        ? ' ('+simpleTrans('partialData')+')'
8741                        : '';	var s = '<span style="font-size:10px">'+Highcharts.dateFormat("%B %Y", this.x)+ todayHint + '</span> ';
8742		            $.each(this.points, function () {
8743                                if (this.series.name !== 'arearange') {
8744                                    var plus = '';
8745                                    if (this.y>0) { plus= '+'; }
8746                                    var anzeigename = this.series.name;
8747                                    anzeigename = anzeigename.replace('aktuell', Highcharts.dateFormat('%B %Y', this.x));
8748                                    s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ anzeigename + ': ' +
8749                                    '<b>'+plus+Math.round(this.y*10)/10 + '</b> ' + '°C' + todayHint;
8750                                }
8751            		});
8752		            return s;
8753        		}
8754            },
8755            credits: { enabled: false },
8756            exporting: themedExportConfig,
8757            series: station_kvmon_data_diff,
8758            reflow: true
8759        });
8760    }
8761
8762    if (typeof station_kvtmax_data != 'undefined') {
8763        $('#klimavergleich-chart-single-tmax').highcharts({
8764            chart: {
8765                height: 400//,
8766            },
8767            title: {text:($('#klimavergleich-chart-single-tmax').prev('label').length > 0) ? $('#klimavergleich-chart-single-tmax').prev('label').text()+" "+getDateForTitle(station_kvtmax_data) : 'Chart'},
8768            legend: {
8769                useHTML: true,
8770                itemStyle: {
8771                    color: cssVar('--hc-label-textcolor'),
8772                },
8773            },
8774            xAxis: {
8775                type: 'datetime',
8776                dateTimeLabelFormats: {
8777                    hour: '%H:%M',
8778                    day: '%e. %b'
8779                },
8780                labels:{
8781                	useHTML: true,
8782    				align: 'center',
8783                	formatter: function () {
8784                		var date_format;
8785  						var day = Highcharts.dateFormat("%e", this.value);
8786   						var hour = Highcharts.dateFormat("%H", this.value);
8787    						if(hour%24==0)
8788    							date_format='%e. %b';
8789    						else
8790    							date_format='%H:%M';
8791    				  		return Highcharts.dateFormat(date_format, this.value);
8792    				},
8793                    style: {
8794                        color: cssVar('--color-text'),
8795                    },
8796                },
8797                tickLength: 7,
8798                lineColor: cssVar('--hc-lineColor-bright'),
8799                tickColor: cssVar('--hc-lineColor-bright'),
8800            },
8801            yAxis: {
8802                title: false,
8803                //floor: 0,
8804                labels: {
8805                    format: "{value}°C",
8806                    style: {
8807                        color: cssVar('--color-text'),
8808                    }
8809                },
8810                softMin:-15,
8811                softMax: 35,
8812                allowDecimals: false,
8813                minorTickInterval: 5,
8814                tickInterval: 5,
8815                //gridLineColor: '#C0C0C0',
8816                //tickAmount: 6
8817                gridLineColor: cssVar('--hc-gridLineColor-bright'),
8818                minorGridLineColor: cssVar('--hc-minorGridLineColor-bright'),
8819            },
8820            tooltip: {
8821                crosshairs: true,
8822                shared: true,
8823                valueSuffix: '°C',
8824                 shape: 'square',
8825                useHTML: true,
8826                zIndex: 50,
8827                /*positioner: function (w,h,p) {
8828                	if(p.plotX/this.chart.chartWidth>0.5)
8829                    	return { x: 65, y: 0 };
8830                    else
8831                    	return { x: this.chart.chartWidth-w-10, y: 0 };
8832                },*/
8833                formatter: function () {
8834                	var date_format;
8835                	date_format="%A, den %e.%B";
8836                	var s = '<span style="font-size:10px">'+Highcharts.dateFormat(date_format, this.x)+ '</span> ';
8837		            $.each(this.points, function () {
8838                                if (this.series.name !== 'arearange') {
8839                                    var anzeigename = this.series.name;
8840                                    anzeigename = anzeigename.replace('aktuell', Highcharts.dateFormat('%d.
8840%m.%Y', this.x));
8841                                    s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ anzeigename + ': ' +
8842                                '<b>'+Math.round(this.y*10)/10 + '</b> ' + '°C';
8843                                }
8844            		});
8845		            return s;
8846        		}
8847            },
8848            credits: { enabled: false },
8849            exporting: themedExportConfig,
8850            series: station_kvtmax_data,
8851            reflow: true
8852        });
8853    }
8854
8855    if (typeof station_kvtmin_data != 'undefined') {
8856        $('#klimavergleich-chart-single-tmin').highcharts({
8857            chart: {
8858                height: 400//,
8859            },
8860            title: {text:($('#klimavergleich-chart-single-tmin').prev('label').length > 0) ? $('#klimavergleich-chart-single-tmin').prev('label').text()+" "+getDateForTitle(station_kvtmin_data) : 'Chart'},
8861            legend: {
8862                useHTML: true,
8863                itemStyle: {
8864                    color: cssVar('--hc-label-textcolor'),
8865                },
8866            },
8867            xAxis: {
8868                type: 'datetime',
8869                dateTimeLabelFormats: {
8870                    hour: '%H:%M',
8871                    day: '%e. %b'
8872                },
8873                labels:{
8874                	useHTML: true,
8875    				align: 'center',
8876                	formatter: function () {
8877                		var date_format;
8878  						var day = Highcharts.dateFormat("%e", this.value);
8879   						var hour = Highcharts.dateFormat("%H", this.value);
8880    						if(hour%24==0)
8881    							date_format='%e. %b';
8882    						else
8883    							date_format='%H:%M';
8884    				  		return Highcharts.dateFormat(date_format, this.value);
8885    				},
8886                    style: {
8887                        color: cssVar('--color-text'),
8888                    },
8889                },
8890                tickLength: 7,
8891                lineColor: cssVar('--hc-lineColor-bright'),
8892                tickColor: cssVar('--hc-lineColor-bright'),
8893            },
8894            yAxis: {
8895                title: false,
8896                //floor: 0,
8897                labels: {
8898                    format: "{value}°C",
8899                    style: {
8900                        color: cssVar('--color-text'),
8901                    }
8902                },
8903                softMin:-25,
8904                softMax: 25,
8905                allowDecimals: false,
8906                minorTickInterval: 5,
8907                tickInterval: 5,
8908                //gridLineColor: '#C0C0C0',
8909                //tickAmount: 6
8910                gridLineColor: cssVar('--hc-gridLineColor-bright'),
8911                minorGridLineColor: cssVar('--hc-minorGridLineColor-bright'),
8912            },
8913            tooltip: {
8914                crosshairs: true,
8915                shared: true,
8916                valueSuffix: '°C',
8917                 shape: 'square',
8918                useHTML: true,
8919                zIndex: 50,
8920                /*positioner: function (w,h,p) {
8921                	if(p.plotX/this.chart.chartWidth>0.5)
8922                    	return { x: 65, y: 0 };
8923                    else
8924                    	return { x: this.chart.chartWidth-w-10, y: 0 };
8925                },*/
8926                formatter: function () {
8927                	var date_format;
8928                	date_format="%A, den %e.%B";
8929                	var s = '<span style="font-size:10px">'+Highcharts.dateFormat(date_format, this.x)+ '</span> ';
8930		            $.each(this.points, function () {
8931                                if (this.series.name !== 'arearange') {
8932                                    var anzeigename = this.series.name;
8933                                    anzeigename = anzeigename.replace('aktuell', Highcharts.dateFormat('%d.%m.%Y', this.x));
8934                                    s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ anzeigename + ': ' +
8935                                    '<b>'+Math.round(this.y*10)/10 + '</b> ' + '°C';
8936                                }
8937            		});
8938		            return s;
8939        		}
8940            },
8941            credits: { enabled: false },
8942            exporting: themedExportConfig,
8943            series: station_kvtmin_data,
8944            reflow: true
8945        });
8946    }
8947
8948    if (typeof station_s24h_acc_data != 'undefined') {
8949        $('#klimavergleich-chart-s24h').highcharts({
8950            chart: {
8951                height: 320//,
8952            },
8953            title: {text:($('#klimavergleich-chart-s24h').prev('label').length > 0) ? $('#klimavergleich-chart-s24h').prev('label').text()+" "+getDateForTitle(station_s24h_acc_data) : 'Chart'},
8954            legend: {
8955                useHTML: true
8956            },
8957            xAxis: [{
8958                type: 'datetime',
8959                dateTimeLabelFormats: {
8960                    hour: false,
8961                    day: '%b %Y'
8962                },
8963                labels:{
8964                	useHTML: true,
8965    				align: 'center',
8966                	formatter: function () {
8967                                    return Highcharts.dateFormat('%b %Y', this.value);
8968    				}
8969                }
8970            },{
8971                type: 'datetime',
8972                dateTimeLabelFormats: {
8973                    hour: '%H:%M',
8974                    day: '%e. %b'
8975                },
8976                labels:{
8977                	useHTML: true,
8978    				align: 'center',
8979                	formatter: function () {
8980                		var date_format;
8981  						var day = Highcharts.dateFormat("%e", this.value);
8982   						var hour = Highcharts.dateFormat("%H", this.value);
8983    						if(hour%24==0)
8984    							date_format='%e. %b';
8985    						else
8986    							date_format='%H:%M';
8987    				  		return Highcharts.dateFormat(date_format, this.value);
8988    				}
8989                }
8990            }],
8991            yAxis: [{
8992                title: {
8993                    text: 'Sonnenstunden Monatssumme'
8994                },
8995                floor: 0,
8996                labels: {
8997                    format: "{value}h"
8998                },
8999                min:0,
9000                softMax: 200,
9001                allowDecimals: false,
9002                minorTickInterval: 1,
9003                //gridLineColor: '#C0C0C0',
9004                tickAmount: 6
9005            },{
9006                title: {
9007                    text: 'Sonnenstunden'
9008                },
9009                //floor: 0,
9010                labels: {
9011                    format: "{value}h"
9012                },
9013                opposite: true,
9014                floor:0,
9015                min: 0,
9016                softMax: 10,
9017                allowDecimals: false,
9018                minorTickInterval: 1,
9019                //gridLineColor: '#C0C0C0',
9020                tickAmount: 6
9021            }],
9022            tooltip: {
9023                crosshairs: true,
9024                shared: true,
9025                valueSuffix: '°C',
9026                 shape: 'square',
9027                useHTML: true,
9028                zIndex: 50,
9029                /*positioner: function (w,h,p) {
9030                	if(p.plotX/this.chart.chartWidth>0.5)
9031                    	return { x: 65, y: 0 };
9032                    else
9033                    	return { x: this.chart.chartWidth-w-10, y: 0 };
9034                },*/
9035                formatter: function () {
9036                	var date_format;
9037                	date_format="%A, den %e.%B";
9038                	var s = '<span style="font-size:10px">'+Highcharts.dateFormat(date_format, this.x)+ '</span> ';
9039		            this.points.sort( ordertooltip );
9040		            $.each(this.points, function () {
9041        		        s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ this.series.name + ': ' +
9042                	    '<b>'+Math.round(this.y*10)/10 + '</b> ' + 'h';
9043            		});
9044		            return s;
9045        		}
9046            },
9047            credits: { enabled: false },
9048            exporting: { exportConfig },
9049            series: station_s24h_acc_data,
9050            reflow: true
9051        });
9052    }
9053
9054    if (typeof station_kvs24sum_data != 'undefined') {
9055        $('#klimavergleich-chart-single-s24sum').highcharts({
9056            chart: {
9057                height: 400//,
9058            },
9059            title: {text:($('#klimavergleich-chart-single-s24sum').prev('label').length > 0) ? $('#klimavergleich-chart-single-s24sum').prev('label').text()+" "+getDateForTitle(station_kvs24sum_data) : 'Chart'},
9060            legend: {
9061                useHTML: true,
9062                itemStyle: {
9063                    color: cssVar('--hc-label-textcolor'),
9064                },
9065            },
9066            xAxis: {
9067                type: 'datetime',
9068                dateTimeLabelFormats: {
9069                    hour: '%H:%M',
9070                    day: '%e. %b'
9071                },
9072                labels:{
9073                	useHTML: true,
9074    				align: 'center',
9075                	formatter: function () {
9076                		var date_format;
9077  						var day = Highcharts.dateFormat("%e", this.value);
9078   						var hour = Highcharts.dateFormat("%H", this.value);
9079    						if(hour%24==0)
9080    							date_format='%e. %b';
9081    						else
9082    							date_format='%H:%M';
9083    				  		return Highcharts.dateFormat(date_format, this.value);
9084    				},
9085                    style: {
9086                        color: cssVar('--color-text'),
9087                    },
9088                },
9089                tickLength: 7,
9090                lineColor: cssVar('--hc-lineColor-bright'),
9091                tickColor: cssVar('--hc-lineColor-bright'),
9092            },
9093            yAxis: {
9094                title: false,
9095                //floor: 0,
9096                labels: {
9097                    format: "{value}h",
9098                    style: {
9099                        color: cssVar('--color-text'),
9100                    }
9101                },
9102                floor:0,
9103                min: 0,
9104                softMax: 200,
9105                allowDecimals: false,
9106                minorTickInterval: 50,
9107                //gridLineColor: '#C0C0C0',
9108                tickAmount: 6,
9109                gridLineColor: cssVar('--hc-gridLineColor-bright'),
9110                minorGridLineColor: cssVar('--hc-minorGridLineColor-bright'),
9111            },
9112            tooltip: {
9113                crosshairs: true,
9114                shared: true,
9115                valueSuffix: '°C',
9116                 shape: 'square',
9117                useHTML: true,
9118                zIndex: 50,
9119                /*positioner: function (w,h,p) {
9120                	if(p.plotX/this.chart.chartWidth>0.5)
9121                    	return { x: 65, y: 0 };
9122                    else
9123                    	return { x: this.chart.chartWidth-w-10, y: 0 };
9124                },*/
9125                formatter: function () {
9126                	var date_format;
9127                	date_format="%A, den %e.%B";
9128                	var s = '<span style="font-size:10px">'+Highcharts.dateFormat(date_format, this.x)+ '</span> ';
9129		            $.each(this.points, function () {
9130                                if (this.series.name !== 'arearange' && this.series.name !== 'arearange2' && this.series.name !== 'arearange3') {
9131                                    var anzeigename = this.series.name;
9132                                        anzeigename = anzeigename.replace('aktuell', Highcharts.dateFormat('%d.
9132%m.%Y', this.x));
9133                                    s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ anzeigename + ': ' +
9134                                        '<b>'+Math.round(this.y*10)/10 + '</b> ' + ' h';
9135                                }
9136                            });
9137		            return s;
9138        		}
9139            },
9140            credits: { enabled: false },
9141            exporting: themedExportConfig,
9142            series: station_kvs24sum_data,
9143            reflow: true
9144        });
9145    }
9146
9147    if (typeof station_kvs24mon_data != 'undefined') {
9148        $('#klimavergleich-chart-single-s24mon').highcharts({
9149            chart: {
9150                height: 400//,
9151            },
9152            title: {text:($('#klimavergleich-chart-single-s24mon').prev('label').length > 0) ? $('#klimavergleich-chart-single-s24mon').prev('label').text()+" "+getDateForTitle(station_kvs24mon_data) : 'Chart'},
9153            legend: {
9154                useHTML: true,
9155                itemStyle: {
9156                    color: cssVar('--hc-label-textcolor'),
9157                },
9158            },
9159            xAxis: {
9160                type: 'datetime',
9161                dateTimeLabelFormats: {
9162                    hour: false,
9163                    day: '%b %Y'
9164                },
9165                labels:{
9166                	useHTML: true,
9167    				align: 'center',
9168                	formatter: function () {
9169                                    return Highcharts.dateFormat('%b %Y', this.value);
9170    				},
9171                    style: {
9172                        color: cssVar('--color-text'),
9173                    },
9174                },
9175                tickLength: 7,
9176                lineColor: cssVar('--hc-lineColor-bright'),
9177                tickColor: cssVar('--hc-lineColor-bright'),
9178            },
9179            yAxis: {
9180                title: false,
9181                floor: 0,
9182                labels: {
9183                    format: "{value}h",
9184                    style: {
9185                        color: cssVar('--color-text'),
9186                    }
9187                },
9188                min:0,
9189                softMax: 200,
9190                allowDecimals: false,
9191                minorTickInterval: 10,
9192                //gridLineColor: '#C0C0C0',
9193                tickAmount: 6,
9194                gridLineColor: cssVar('--hc-gridLineColor-bright'),
9195                minorGridLineColor: cssVar('--hc-minorGridLineColor-bright'),
9196            },
9197            plotOptions: {
9198                column: {
9199                    borderColor: cssVar('--hc-bar-stroke-color'),
9200                }
9201            },
9202            tooltip: {
9203                crosshairs: true,
9204                shared: true,
9205                valueSuffix: '°C',
9206                 shape: 'square',
9207                useHTML: true,
9208                zIndex: 50,
9209                /*positioner: function (w,h,p) {
9210                	if(p.plotX/this.chart.chartWidth>0.5)
9211                    	return { x: 65, y: 0 };
9212                    else
9213                    	return { x: this.chart.chartWidth-w-10, y: 0 };
9214                },*/
9215                formatter: function () {
9216                    var todayHint= Highcharts.dateFormat('%B %Y', this.x) == Highcharts.dateFormat('%B %Y', new Date())
9217                        ? ' ('+simpleTrans('partialData')+')'
9218                        : '';
9219                    var s = '<span style="font-size:10px">'+Highcharts.dateFormat('%B %Y', this.x)+ todayHint + '</span> ';
9220		            $.each(this.points, function () {
9221                                var anzeigename = this.series.name;
9222                                    anzeigename = anzeigename.replace('aktuell', Highcharts.dateFormat('%B %Y', this.x));
9223        		        s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ anzeigename + ': ' +
9224                	    '<b>'+Math.round(this.y*10)/10 + '</b> ' + 'h' + todayHint;
9225            		});
9226		            return s;
9227        		}
9228            },
9229            credits: { enabled: false },
9230            exporting: themedExportConfig,
9231            series: station_kvs24mon_data,
9232            reflow: true
9233        });
9234    }
9235
9236    if (typeof station_kvs24mondiff_data != 'undefined') {
9237        $('#klimavergleich-chart-single-s24mondiff').highcharts({
9238            chart: {
9239                height: 320//,
9240            },
9241            title: {text:($('#klimavergleich-chart-single-s24mondiff').prev('label').length > 0) ? $('#klimavergleich-chart-single-s24mondiff').prev('label').text()+" "+getDateForTitle(station_kvs24mondiff_data) : 'Chart'},
9242            legend: {
9243                useHTML: true,
9244                itemStyle: {
9245                    color: cssVar('--hc-label-textcolor'),
9246                },
9247            },
9248            xAxis: {
9249                type: 'datetime',
9250                dateTimeLabelFormats: {
9251                    hour: false,
9252                    day: '%b %Y'
9253                },
9254                labels:{
9255                	useHTML: true,
9256    				align: 'center',
9257                	formatter: function () {
9258                                    return Highcharts.dateFormat('%b %Y', this.value);
9259    				},
9260                    style: {
9261                        color: cssVar('--color-text'),
9262                    },
9263                },
9264                tickLength: 7,
9265                lineColor: cssVar('--hc-lineColor-bright'),
9266                tickColor: cssVar('--hc-lineColor-bright'),
9267            },
9268            yAxis: {
9269                title: false,
9270                labels: {
9271                    format: "{value}h",
9272                    style: {
9273                        color: cssVar('--color-text'),
9274                    }
9275                },
9276                softMin:-20,
9277                softMax: 20,
9278                allowDecimals: false,
9279                minorTickInterval: 5,
9280                //gridLineColor: '#C0C0C0',
9281                tickAmount: 6,
9282                gridLineColor: cssVar('--hc-gridLineColor-bright'),
9283                minorGridLineColor: cssVar('--hc-minorGridLineColor-bright'),
9284            },
9285            plotOptions: {
9286                column: {
9287                    borderColor: cssVar('--hc-bar-stroke-color'),
9288                }
9289            },
9290            tooltip: {
9291                crosshairs: true,
9292                shared: true,
9293                valueSuffix: '°C',
9294                 shape: 'square',
9295                useHTML: true,
9296                zIndex: 50,
9297                /*positioner: function (w,h,p) {
9298                	if(p.plotX/this.chart.chartWidth>0.5)
9299                    	return { x: 65, y: 0 };
9300                    else
9301                    	return { x: this.chart.chartWidth-w-10, y: 0 };
9302                },*/
9303                formatter: function () {
9304                    var todayHint= Highcharts.dateFormat('%B %Y', this.x) == Highcharts.dateFormat('%B %Y', new Date())
9305                        ? ' ('+simpleTrans('partialData')+')'
9306                        : '';
9307                    var s = '<span style="font-size:10px">'+Highcharts.dateFormat('%B %Y', this.x)+ todayHint + '</span> ';
9308		            $.each(this.points, function () {
9309                                var plus = '';
9310                                if (this.y>0) { plus = '+'; }
9311        		        var anzeigename = this.series.name;
9312                                    anzeigename = anzeigename.replace('aktuell', Highcharts.dateFormat('%B %Y', this.x));
9313        		        s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ anzeigename + ': ' +
9314                	    '<b>'+plus+Math.round(this.y*10)/10 + '</b> ' + 'h' + todayHint;
9315            		});
9316		            return s;
9317        		}
9318            },
9319            credits: { enabled: false },
9320            exporting: themedExportConfig,
9321            series: station_kvs24mondiff_data,
9322            reflow: true
9323        });
9324    }
9325};
9326
9327
9328var plotVHStationen = function() {
9329    if (typeof vhstation_rr_data != 'undefined' && vhstation_rr_data) {
9330        $('#vh-stationen-chart').highcharts({
9331            chart: {
9332                height: 360,
9333                events: {
9334                	load: function(){
9335                        if ($('#btn-vhs-mode-minutes').hasClass('btn-active') || $('#btn-vhs-mode-hour').hasClass('btn-active')) {
9336                            drawNightShadows(this,1);
9337                        }
9338            		},
9339                	redraw: function(){
9340                        if ($('#btn-vhs-mode-minutes').hasClass('btn-active') || $('#btn-vhs-mode-hour').hasClass('btn-active')) {
9341                            drawNightShadows(this,1);
9342                        }
9343            		}
9344            	}
9345            },
9346            title: 'false',
9347            legend: {
9348                useHTML: true   
9349            },
9350            xAxis: [{
9351                type: 'datetime',
9352                dateTimeLabelFormats: {
9353                    hour: '%H:%M',
9354                    day: '%e. %b'
9355                },
9356                labels:{
9357                	useHTML: true,
9358                        align: 'center',
9359                	formatter: function () {
9360                            return Highcharts.dateFormat(getVHStationDateFormat(this.value), this.value);
9361                        }
9362                },
9363                minPadding: 0.025
9364            }],
9365            yAxis: [{
9366                title: false,
9367                floor: 0,
9368                labels: {
9369                    format: "{value} mm"
9370                },
9371                min:0,
9372                softMax: 5,
9373                allowDecimals: false,
9374                minorTickInterval: 1,
9375                //gridLineColor: '#C0C0C0',
9376                tickAmount: 6
9377            }],
9378            tooltip: {
9379                crosshairs: true,
9380                shared: true,
9381                valueSuffix: ' mm',
9382                 shape: 'square',
9383                useHTML: true,
9384                zIndex: 50,
9385                formatter: function () { 
9386                	var date_format;
9387                	date_format="%A, den %e.%B, %H:%M Uhr";
9388                	var s = '<span style="font-size:10px">'+Highcharts.dateFormat(getVHStationDateFormat(this.x, true), this.x)+ '</span> ';
9389		            this.points.sort( ordertooltip );
9390		            $.each(this.points, function () {
9391        		        s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ this.series.name + ': ' +
9392                	    '<b>'+Math.round(this.y*10)/10 + '</b> ' + ' mm';
9393            		});
9394		            return s;
9395        		}
9396            },
9397            credits: { enabled: false },
9398            exporting: { enabled: false },
9399            series: vhstation_rr_data, 
9400            reflow: true
9401        });
9402    }
9403    
9404    if (typeof vhstation_tl_data != 'undefined' && vhstation_tl_data) {
9405        $('#vh-stationen-chart').highcharts({
9406            chart: {
9407                height: 360,//,
9408                events: {
9409                	load: function(){
9410                            if ($('#btn-vhs-mode-minutes').hasClass('btn-active') || $('#btn-vhs-mode-hour').hasClass('btn-active')) {
9411            			drawNightShadows(this,1);
9412                            }
9413            		},
9414                	redraw: function(){
9415                            if ($('#btn-vhs-mode-minutes').hasClass('btn-active') || $('#btn-vhs-mode-hour').hasClass('btn-active')) {
9416            			drawNightShadows(this,1);
9417                            }
9418            		}
9419            	}
9420            },
9421            title: 'false',
9422            legend: {
9423                useHTML: true   
9424            },
9425            xAxis: [{
9426                type: 'datetime',
9427                dateTimeLabelFormats: {
9428                    hour: '%H:%M',
9429                    day: '%e. %b'
9430                },
9431                labels:{
9432                	useHTML: true,
9433    				align: 'center',
9434                	formatter: function () {
9435                            return Highcharts.dateFormat(getVHStationDateFormat(this.value), this.value);
9436                        }
9437                }
9438            }],
9439            yAxis: [{
9440                title: {
9441                    text: 'Temperaturen'
9442                },
9443                //floor: 0,
9444                labels: {
9445                    format: "{value} °C"
9446                },
9447                softMin:0,
9448                // softMax: 20,
9449                // allowDecimals: false,
9450                // minorTickInterval: 1,
9451                // //gridLineColor: '#C0C0C0',
9452                // tickAmount: 6
9453                minTickInterval: 5,
9454                minorTickInterval: 'auto',
9455                minPadding: 0.12,
9456                maxPadding: 0.12,
9457                minRange: 5
9458            },{
9459                title: {
9460                    text: 'Relative Luftfeuchtigkeit'
9461                },
9462                //floor: 0,
9463                labels: {
9464                    format: "{value}%"
9465                },
9466                opposite: true,
9467                min:0,
9468                max: 100,
9469                allowDecimals: false,
9470            }],
9471            tooltip: {
9472                crosshairs: true,
9473                shared: true,
9474                valueSuffix: '°C',
9475                 shape: 'square',
9476                useHTML: true,
9477                zIndex: 50,
9478                formatter: function () { 
9479                	var date_format;
9480                	date_format="%A, den %e.%B, %H:%M Uhr";
9481                	var s = '<span style="font-size:10px">'+Highcharts.dateFormat(getVHStationDateFormat(this.x, true), this.x)+ '</span> ';
9482		            this.points.sort( ordertooltip );
9483		            $.each(this.points, function () {
9484                                var unit = '°C';
9485                                if (this.series.name == 'Relative Luftfeuchtigkeit') {
9486                                    unit = '%';
9487                                }
9488        		        s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ this.series.name + ': ' +
9489                	    '<b>'+Math.round(this.y*10)/10 + '</b> ' + unit;
9490            		});
9491		            return s;
9492        		}
9493            },
9494            plotOptions: {
9495	            area: {
9496	                fillColor: {
9497	                    linearGradient: {
9498	                        x1: 0,
9499	                        y1: 0,
9500	                        x2: 0,
9501	                        y2: 1
9502	                    },
9503	                    stops: [
9504	                        [0, '#d4ebfc'],
9505                                [1, '#e5f2fc']
9506	                    ]
9507	                },
9508	                marker: {
9509	                    radius: 2
9510	                },
9511	                lineWidth: 1,
9512	                states: {
9513	                    hover: {
9514	                        lineWidth: 1
9515	                    }
9516	                },
9517	                threshold: null
9518	            }
9519        	},
9520            credits: { enabled: false },
9521            exporting: { enabled: false },
9522            series: vhstation_tl_data, 
9523            reflow: true
9524        });
9525    }
9526    
9527    if (typeof vhstation_tl_data2 != 'undefined' && vhstation_tl_data2) {
9528        $('#vh-stationen-chart').highcharts({
9529            chart: {
9530                height: 360,//,
9531                events: {
9532                	load: function(){
9533                            if ($('#btn-vhs-mode-minutes').hasClass('btn-active') || $('#btn-vhs-mode-hour').hasClass('btn-active')) {
9534            			drawNightShadows(this,1);
9535                            }
9536            		},
9537                	redraw: function(){
9538                            if ($('#btn-vhs-mode-minutes').hasClass('btn-active') || $('#btn-vhs-mode-hour').hasClass('btn-active')) {
9539            			drawNightShadows(this,1);
9540                            }
9541            		}
9542            	}
9543            },
9544            title: 'false',
9545            legend: {
9546                useHTML: true   
9547            },
9548            xAxis: [{
9549                type: 'datetime',
9550                dateTimeLabelFormats: {
9551                    hour: '%H:%M',
9552                    day: '%e. %b'
9553                },
9554                labels:{
9555                	useHTML: true,
9556    				align: 'center',
9557                	formatter: function () {
9558                            return Highcharts.dateFormat(getVHStationDateFormat(this.value), this.value);
9559                        }
9560                }
9561            }],
9562            yAxis: [{
9563                title: {
9564                    text: 'Temperaturen'
9565                },
9566                //floor: 0,
9567                labels: {
9568                    format: "{value} °C"
9569                },
9570                // softMin:0,
9571                // softMax: 20,
9572                // allowDecimals: false,
9573                // minorTickInterval: 1,
9574                // //gridLineColor: '#C0C0C0',
9575                tickInterval: 10,
9576                minorTickInterval: 'auto',
9577                minPadding: 0.01,
9578                maxPadding: 0.01,
9579                minRange: 5
9580            }],
9581            tooltip: {
9582                crosshairs: true,
9583                shared: true,
9584                valueSuffix: '°C',
9585                 shape: 'square',
9586                useHTML: true,
9587                zIndex: 50,
9588                formatter: function () { 
9589                	var date_format;
9590                	date_format="%A, den %e.%B, %H:%M Uhr";
9591                	var s = '<span style="font-size:10px">'+Highcharts.dateFormat(getVHStationDateFormat(this.x, true), this.x)+ '</span> ';
9592		            this.points.sort( ordertooltip );
9593		            $.each(this.points, function () {
9594                                var unit = '°C';
9595                                if (this.series.name == 'Relative Luftfeuchtigkeit') {
9596                                    unit = '%';
9597                                }
9598        		        s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ this.series.name + ': ' +
9599                	    '<b>'+Math.round(this.y*10)/10 + '</b> ' + unit;
9600            		});
9601		            return s;
9602        		}
9603            },
9604            plotOptions: {
9605	            area: {
9606	                fillColor: {
9607	                    linearGradient: {
9608	                        x1: 0,
9609	                        y1: 0,
9610	                        x2: 0,
9611	                        y2: 1
9612	                    },
9613	                    stops: [
9614	                        [0, '#d4ebfc'],
9615                                [1, '#e5f2fc']
9616	                    ]
9617	                },
9618	                marker: {
9619	                    radius: 2
9620	                },
9621	                lineWidth: 1,
9622	                states: {
9623	                    hover: {
9624	                        lineWidth: 1
9625	                    }
9626	                },
9627	                threshold: null
9628	            }
9629        	},
9630            credits: { enabled: false },
9631            exporting: { enabled: false },
9632            series: vhstation_tl_data2, 
9633            reflow: true
9634        });
9635    }
9636    
9637    if (typeof vhstation_wind_data !== 'undefined' && vhstation_wind_data) {
9638       $('#vh-stationen-chart').highcharts({
9639            chart: {
9640//            	marginLeft:69,
9641                height: 360, 
9642                events: {
9643                	load: function(){
9644                            if ($('#btn-vhs-mode-minutes').hasClass('btn-active') || $('#btn-vhs-mode-hour').hasClass('btn-active')) {            			
9645                                drawNightShadows(this,1);
9646                            }
9647                            drawWindArrowsVH(this);
9648            		},
9649                	redraw: function(){
9650                            //drawBlocksForWindArrows(this);
9651                            if ($('#btn-vhs-mode-minutes').hasClass('btn-active') || $('#btn-vhs-mode-hour').hasClass('btn-active')) {            			
9652                                drawNightShadows(this,1);
9653                            }
9654                            drawWindArrowsVH(this);
9655            		}
9656            	}
9657            },
9658            title: 'false',
9659            legend: {
9660                useHTML: true   
9661            },
9662            xAxis: {
9663                type: 'datetime',
9664                offset: 40,
9665                dateTimeLabelFormats: {
9666                    hour: '%H:%M',
9667                    day: '%e. %b'
9668                },
9669                labels:{
9670                	useHTML: true,
9671    				align: 'center',
9672                	formatter: function () {
9673                            return Highcharts.dateFormat(getVHStationDateFormat(this.value), this.value);
9674                        }
9675                }
9676            },
9677            yAxis: {
9678                title: {
9679                    text: false
9680                },
9681                labels: {
9682                    format: "{value} "+getVHStationUnit()
9683                },
9684                min:0,
9685                softMax: getVHStationUnitSoftMax(),
9686                allowDecimals: false,
9687                minorTickInterval: 1,
9688                //gridLineColor: '#C0C0C0',
9689                tickAmount: 5
9690            },
9691            tooltip: {
9692                crosshairs: true,
9693                shared: true,
9694                valueSuffix: ' '+getVHStationUnit(),
9695                 shape: 'square',
9696                useHTML: true,
9697                formatter: function () { 
9698                	// fix for faulty highcharts tooltip recognition
9699                	var date_format;
9700                        date_format="%A, den %e.%B, %H:%M Uhr";
9701                	var s = '<span style="font-size:10px;">'+Highcharts.dateFormat(getVHStationDateFormat(this.x, true), this.x)+ '</span> ';
9702                    var c=0;
9703                    
9704                    var sortedPoints = this.points.sort(function(a, b){
9705                        return ((a.y > b.y) ? -1 : ((a.y < b.y) ? 1 : 0));
9706                    });
9707
9708		            $.each(sortedPoints, function () {
9709	            		c++;
9710       		        	s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ this.series.name + ': ' +
9711              	    	'<b>'+this.y + '</b> ' + ' '+getVHStationUnit();
9712            		});
9713		            return '<div class="highcharts-tooltip">' + s + '</div>';
9714        		}
9715            },
9716            credits: { enabled: false },
9717            exporting: { enabled: false },
9718            series: vhstation_wind_data, 
9719            reflow: true
9720        });
9721    }
9722    if (typeof vhstation_glrad_data !== 'undefined' && vhstation_glrad_data) {
9723        $('#vh-stationen-chart').highcharts({
9724            chart: {
9725//            	marginLeft:69,
9726                height: 360, 
9727                events: {
9728                    load: function(){
9729                            if ($('#btn-vhs-mode-minutes').hasClass('btn-active') || $('#btn-vhs-mode-hour').hasClass('btn-active')) {            			
9730                                drawNightShadows(this,1);
9731                            }
9732                    },
9733                    redraw: function(){
9734                            //drawBlocksForWindArrows(this);
9735                            if ($('#btn-vhs-mode-minutes').hasClass('btn-active') || $('#btn-vhs-mode-hour').hasClass('btn-active')) {            			
9736                                drawNightShadows(this,1);
9737                            }
9738                    }
9739                }
9740            },
9741            title: 'false',
9742            legend: {
9743                useHTML: true   
9744            },
9745            xAxis: {
9746                type: 'datetime',
9747                dateTimeLabelFormats: {
9748                    hour: '%H:%M',
9749                    day: '%e. %b'
9750                },
9751                labels:{
9752                    useHTML: true,
9753                    align: 'center',
9754                    formatter: function () {
9755                            return Highcharts.dateFormat(getVHStationDateFormat(this.value), this.value);
9756                        }
9757                }
9758            },
9759            yAxis: {
9760                title: {
9761                    text: false
9762                },
9763                labels: {
9764                    format: "{value} "+getVHStationUnit()
9765                },
9766                min:0,
9767                softMax: getVHStationUnitSoftMax(),
9768                allowDecimals: false,
9769                minorTickInterval: 1,
9770                //gridLineColor: '#C0C0C0',
9771                tickAmount: 5
9772            },
9773            tooltip: {
9774                crosshairs: true,
9775                shared: true,
9776                valueSuffix: ' '+getVHStationUnit(),
9777                 shape: 'square',
9778                useHTML: true,
9779                formatter: function () { 
9780                    // fix for faulty highcharts tooltip recognition
9781                    var date_format;
9782                        date_format="%A, den %e.%B, %H:%M Uhr";
9783                    var s = '<span style="font-size:10px;">'+Highcharts.dateFormat(getVHStationDateFormat(this.x, true), this.x)+ '</span> ';
9784                    var c=0;
9785                    
9786                    var sortedPoints = this.points.sort(function(a, b){
9787                        return ((a.y > b.y) ? -1 : ((a.y < b.y) ? 1 : 0));
9788                    });
9789
9790                    $.each(sortedPoints, function () {
9791                        c++;
9792                        s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ this.series.name + ': ' +
9793                        '<b>'+this.y + '</b> ' + ' '+getVHStationUnit();
9794                    });
9795                    return '<div class="highcharts-tooltip">' + s + '</div>';
9796                }
9797            },
9798            credits: { enabled: false },
9799            exporting: { enabled: false },
9800            series: vhstation_glrad_data, 
9801            reflow: true
9802        });
9803    }
9804
9805    if (typeof vhstation_prs_data !== 'undefined' && vhstation_prs_data) {
9806        $('#vh-stationen-chart').highcharts({
9807            chart: {
9808//            	marginLeft:69,
9809                height: 360, 
9810                events: {
9811                    load: function(){
9812                            if ($('#btn-vhs-mode-minutes').hasClass('btn-active') || $('#btn-vhs-mode-hour').hasClass('btn-active')) {            			
9813                                drawNightShadows(this,1);
9814                            }
9815                    },
9816                    redraw: function(){
9817                            //drawBlocksForWindArrows(this);
9818                            if ($('#btn-vhs-mode-minutes').hasClass('btn-active') || $('#btn-vhs-mode-hour').hasClass('btn-active')) {            			
9819                                drawNightShadows(this,1);
9820                            }
9821                    }
9822                }
9823            },
9824            title: 'false',
9825            legend: {
9826                useHTML: true   
9827            },
9828            xAxis: {
9829                type: 'datetime',
9830                dateTimeLabelFormats: {
9831                    hour: '%H:%M',
9832                    day: '%e. %b'
9833                },
9834                labels:{
9835                    useHTML: true,
9836                    align: 'center',
9837                    formatter: function () {
9838                            return Highcharts.dateFormat(getVHStationDateFormat(this.value), this.value);
9839                        }
9840                }
9841            },
9842            yAxis: {
9843                title: {
9844                    text: false
9845                },
9846                labels: {
9847                    format: "{value} "+getVHStationUnit()
9848                },
9849                tickAmount: 5,
9850                minTickInterval: 5,
9851                minorTickInterval: 'auto'
9852            },
9853            tooltip: {
9854                crosshairs: true,
9855                shared: true,
9856                valueSuffix: ' '+getVHStationUnit(),
9857                 shape: 'square',
9858                useHTML: true,
9859                formatter: function () { 
9860                    // fix for faulty highcharts tooltip recognition
9861                    var date_format;
9862                        date_format="%A, den %e.%B, %H:%M Uhr";
9863                    var s = '<span style="font-size:10px;">'+Highcharts.dateFormat(getVHStationDateFormat(this.x, true), this.x)+ '</span> ';
9864                    var c=0;
9865                    
9866                    var sortedPoints = this.points.sort(function(a, b){
9867                        return ((a.y > b.y) ? -1 : ((a.y < b.y) ? 1 : 0));
9868                    });
9869
9870                    $.each(sortedPoints, function () {
9871                        c++;
9872                        s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ this.series.name + ': ' +
9873                        '<b>'+this.y + '</b> ' + ' '+getVHStationUnit();
9874                    });
9875                    return '<div class="highcharts-tooltip">' + s + '</div>';
9876                }
9877            },
9878            credits: { enabled: false },
9879            exporting: { enabled: false },
9880            series: vhstation_prs_data, 
9881            reflow: true
9882        });
9883    }
9884    if (typeof vhstation_lwet_data !== 'undefined' && vhstation_lwet_data) {
9885        $('#vh-stationen-chart').highcharts({
9886            chart: {
9887//            	marginLeft:69,
9888                height: 360, 
9889                events: {
9890                    load: function(){
9891                            if ($('#btn-vhs-mode-minutes').hasClass('btn-active') || $('#btn-vhs-mode-hour').hasClass('btn-active')) {            			
9892                                drawNightShadows(this,1);
9893                            }
9894                    },
9895                    redraw: function(){
9896                            //drawBlocksForWindArrows(this);
9897                            if ($('#btn-vhs-mode-minutes').hasClass('btn-active') || $('#btn-vhs-mode-hour').hasClass('btn-active')) {            			
9898                                drawNightShadows(this,1);
9899                            }
9900                    }
9901                }
9902            },
9903            title: 'false',
9904            legend: {
9905                useHTML: true   
9906            },
9907            xAxis: {
9908                type: 'datetime',
9909                dateTimeLabelFormats: {
9910                    hour: '%H:%M',
9911                    day: '%e. %b'
9912                },
9913                labels:{
9914                    useHTML: true,
9915                    align: 'center',
9916                    formatter: function () {
9917                            return Highcharts.dateFormat(getVHStationDateFormat(this.value), this.value);
9918                        }
9919                }
9920            },
9921            yAxis: {
9922                title: {
9923                    text: false
9924                },
9925                labels: {
9926                    format: "{value} "+getVHStationUnit()
9927                },
9928                min:0,
9929                max:100,
9930                allowDecimals: false,
9931                minorTickInterval: 1,
9932                //gridLineColor: '#C0C0C0',
9933                tickAmount: 5
9934            },
9935            tooltip: {
9936                crosshairs: true,
9937                shared: true,
9938                valueSuffix: ' '+getVHStationUnit(),
9939                 shape: 'square',
9940                useHTML: true,
9941                formatter: function () { 
9942                    // fix for faulty highcharts tooltip recognition
9943                    var date_format;
9944                        date_format="%A, den %e.%B, %H:%M Uhr";
9945                    var s = '<span style="font-size:10px;">'+Highcharts.dateFormat(getVHStationDateFormat(this.x, true), this.x)+ '</span> ';
9946                    var c=0;
9947                    
9948                    var sortedPoints = this.points.sort(function(a, b){
9949                        return ((a.y > b.y) ? -1 : ((a.y < b.y) ? 1 : 0));
9950                    });
9951
9952                    $.each(sortedPoints, function () {
9953                        c++;
9954                        s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ this.series.name + ': ' +
9955                        '<b>'+this.y + '</b> ' + ' '+getVHStationUnit();
9956                    });
9957                    return '<div class="highcharts-tooltip">' + s + '</div>';
9958                }
9959            },
9960            plotOptions: {
9961                area: {
9962                    zones: [
9963                        {value: 1, color: '#90b466'},
9964                        {value: 2, color: '#8eb365'},
9965                        {value: 3, color: '#8cb364'},
9966                        {value: 4, color: '#8ab263'},
9967                        {value: 5, color: '#88b263'},
9968                        {value: 6, color: '#86b162'},
9969                        {value: 7, color: '#84b161'},
9970                        {value: 8, color: '#82b060'},
9971                        {value: 9, color: '#80b05f'},
9972                        {value: 10, color: '#7daf5e'},
9973                        {value: 11, color: '#7baf5e'},
9974                        {value: 12, color: '#79ae5d'},
9975                        {value: 13, color: '#77ae5c'},
9976                        {value: 14, color: '#75ad5b'},
9977                        {value: 15, color: '#73ad5a'},
9978                        {value: 16, color: '#71ac59'},
9979                        {value: 17, color: '#6fac58'},
9980                        {value: 18, color: '#6dab58'},
9981                        {value: 19, color: '#6bab57'},
9982                        {value: 20, color: '#69aa56'},
9983                        {value: 21, color: '#67a955'},
9984                        {value: 22, color: '#65a954'},
9985                        {value: 23, color: '#63a853'},
9986                        {value: 24, color: '#61a852'},
9987                        {value: 25, color: '#5fa752'},
9988                        {value: 26, color: '#5ca751'},
9989                        {value: 27, color: '#5aa650'},
9990                        {value: 28, color: '#58a64f'},
9991                        {value: 29, color: '#56a54e'},
9992                        {value: 30, color: '#54a54d'},
9993                        {value: 31, color: '#52a44d'},
9994                        {value: 32, color: '#50a44c'},
9995                        {value: 33, color: '#4ea34b'},
9996                        {value: 34, color: '#4ca34a'},
9997                        {value: 35, color: '#4aa249'},
9998                        {value: 36, color: '#48a248'},
9999                        {value: 37, color: '#46a147'},
10000                        {value: 38, color: '#44a147'},
10001                        {value: 39, color: '#42a046'},
10002                        {value: 40, color: '#40a045'},
10003                        {value: 41, color: '#3e9f44'},
10004                        {value: 42, color: '#3c9e43'},
10005                        {value: 43, color: '#399e42'},
10006                        {value: 44, color: '#379d42'},
10007                        {value: 45, color: '#359d41'},
10008                        {value: 46, color: '#339c40'},
10009                        {value: 47, color: '#319c3f'},
10010                        {value: 48, color: '#2f9b3e'},
10011                        {value: 49, color: '#2d9b3d'},
10012                        {value: 50, color: '#2b9a3c'},
10013                        {value: 51, color: '#2a9a3d'},
10014                        {value: 52, color: '#299a3f'},
10015                        {value: 53, color: '#289a41'},
10016                        {value: 54, color: '#279a43'},
10017                        {value: 55, color: '#269b45'},
10018                        {value: 56, color: '#259b47'},
10019                        {value: 57, color: '#249b49'},
10020                        {value: 58, color: '#249b4b'},
10021                        {value: 59, color: '#239b4d'},
10022                        {value: 60, color: '#229b4f'},
10023                        {value: 61, color: '#219b51'},
10024                        {value: 62, color: '#209b53'},
10025                        {value: 63, color: '#1f9c55'},
10026                        {value: 64, color: '#1f9c57'},
10027                        {value: 65, color: '#1e9c59'},
10028                        {value: 66, color: '#1d9c5b'},
10029                        {value: 67, color: '#1c9c5d'},
10030                        {value: 68, color: '#1b9c5f'},
10031                        {value: 69, color: '#1a9c61'},
10032                        {value: 70, color: '#199c63'},
10033                        {value: 71, color: '#199d65'},
10034                        {value: 72, color: '#189d67'},
10035                        {value: 73, color: '#179d69'},
10036                        {value: 74, color: '#169d6b'},
10037                        {value: 75, color: '#159d6d'},
10038                        {value: 76, color: '#149d6e'},
10039                        {value: 77, color: '#149d70'},
10040                        {value: 78, color: '#139d72'},
10041                        {value: 79, color: '#129e74'},
10042                        {value: 80, color: '#119e76'},
10043                        {value: 81, color: '#109e78'},
10044                        {value: 82, color: '#0f9e7a'},
10045                        {value: 83, color: '#0e9e7c'},
10046                        {value: 84, color: '#0e9e7e'},
10047                        {value: 85, color: '#0d9e80'},
10048                        {value: 86, color: '#0c9e82'},
10049                        {value: 87, color: '#0b9e84'},
10050                        {value: 88, color: '#0a9f86'},
10051                        {value: 89, color: '#099f88'},
10052                        {value: 90, color: '#089f8a'},
10053                        {value: 91, color: '#089f8c'},
10054                        {value: 92, color: '#079f8e'},
10055                        {value: 93, color: '#069f90'},
10056                        {value: 94, color: '#059f92'},
10057                        {value: 95, color: '#049f94'},
10058                        {value: 96, color: '#03a096'},
10059                        {value: 97, color: '#03a098'},
10060                        {value: 98, color: '#02a09a'},
10061                        {value: 99, color: '#01a09c'},
10062                        {color: '#00a09e'},
10063                    ]
10064                }
10065            },
10066            credits: { enabled: false },
10067            exporting: { enabled: false },
10068            series: vhstation_lwet_data, 
10069            reflow: true
10070        });
10071    }
10072    if (typeof vhstation_soil_data != 'undefined' && vhstation_soil_data) {
10073        $('#vh-stationen-chart').highcharts({
10074            chart: {
10075                height: 360,//,
10076                events: {
10077                	load: function(){
10078                            if ($('#btn-vhs-mode-minutes').hasClass('btn-active') || $('#btn-vhs-mode-hour').hasClass('btn-active')) {
10079            			drawNightShadows(this,1);
10080                            }
10081            		},
10082                	redraw: function(){
10083                            if ($('#btn-vhs-mode-minutes').hasClass('btn-active') || $('#btn-vhs-mode-hour').hasClass('btn-active')) {
10084            			drawNightShadows(this,1);
10085                            }
10086            		}
10087            	}
10088            },
10089            title: 'false',
10090            legend: {
10091                useHTML: true   
10092            },
10093            xAxis: [{
10094                type: 'datetime',
10095                dateTimeLabelFormats: {
10096                    hour: '%H:%M',
10097                    day: '%e. %b'
10098                },
10099                labels:{
10100                	useHTML: true,
10101    				align: 'center',
10102                	formatter: function () {
10103                            return Highcharts.dateFormat(getVHStationDateFormat(this.value), this.value);
10104                        }
10105                }
10106            }],
10107            yAxis: [{
10108                title: {
10109                    text: 'Feuchtigkeit'
10110                },
10111                //floor: 0,
10112                labels: {
10113                    format: "{value}%"
10114                },
10115                min: 0,
10116                max: 100,
10117                softMax: 80,
10118                tickAmount: 6,
10119                allowDecimals: false,
10120            },{
10121                title: {
10122                    text: 'Temperatur'
10123                },
10124                //floor: 0,
10125                labels: {
10126                    format: "{value} °C"
10127                },
10128                opposite: true,
10129                softMin: 0,
10130                softMax: 20,
10131                minRange: 20,
10132                allowDecimals: false,
10133                minorTickInterval: 1,
10134                //gridLineColor: '#C0C0C0',
10135                tickAmount: 6
10136            }],
10137            tooltip: {
10138                crosshairs: true,
10139                shared: true,
10140                valueSuffix: '°C',
10141                 shape: 'square',
10142                useHTML: true,
10143                zIndex: 50,
10144                formatter: function () { 
10145                	var date_format;
10146                	date_format="%A, den %e.%B, %H:%M Uhr";
10147                	var s = '<span style="font-size:10px">'+Highcharts.dateFormat(getVHStationDateFormat(this.x, true), this.x)+ '</span> ';
10148		            this.points.sort( ordertooltip );
10149		            $.each(this.points, function () {
10150                                var digits = 1;
10151                                var unit = '%';
10152                                if (typeof this.series.name === 'string' && this.series.name.substring(0,15) === 'Bodentemperatur') {
10153                                    digits = 1;
10154                                    unit = '°C';
10155                                }
10156        		        s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ this.series.name + ': ' +
10157                	    '<b>'+Highcharts.numberFormat(this.y,digits) + '</b> ' + unit;
10158            		});
10159		            return s;
10160        		}
10161            },
10162            credits: { enabled: false },
10163            exporting: { enabled: false },
10164            series: vhstation_soil_data, 
10165            reflow: true
10166        });
10167    }
10168    if (typeof vhstation_soilba_data != 'undefined' && vhstation_soilba_data) {
10169        $('#vh-stationen-chart').highcharts({
10170            chart: {
10171                height: 360,//,
10172                events: {
10173                	load: function(){
10174                            if ($('#btn-vhs-mode-minutes').hasClass('btn-active') || $('#btn-vhs-mode-hour').hasClass('btn-active')) {
10175            			drawNightShadows(this,1);
10176                            }
10177            		},
10178                	redraw: function(){
10179                            if ($('#btn-vhs-mode-minutes').hasClass('btn-active') || $('#btn-vhs-mode-hour').hasClass('btn-active')) {
10180            			drawNightShadows(this,1);
10181                            }
10182            		}
10183            	}
10184            },
10185            title: 'false',
10186            legend: {
10187                useHTML: true
10188            },
10189            xAxis: [{
10190                type: 'datetime',
10191                dateTimeLabelFormats: {
10192                    hour: '%H:%M',
10193                    day: '%e. %b'
10194                },
10195                labels:{
10196                	useHTML: true,
10197    				align: 'center',
10198                	formatter: function () {
10199                            return Highcharts.dateFormat(getVHStationDateFormat(this.value), this.value);
10200                        }
10201                }
10202            }],
10203            yAxis: [{
10204                title: {
10205                    text: 'Bodensaugspannung'
10206                },
10207                //floor: 0,
10208                labels: {
10209                    format: "{value}hPa"
10210                },
10211                softMin: -600,
10212                softMax: -100,
10213                tickAmount: 6,
10214                allowDecimals: false,
10215            },{
10216                title: {
10217                    text: 'Temperatur'
10218                },
10219                //floor: 0,
10220                labels: {
10221                    format: "{value} °C"
10222                },
10223                opposite: true,
10224                softMin: 0,
10225                softMax: 20,
10226                minRange: 20,
10227                allowDecimals: false,
10228                minorTickInterval: 1,
10229                //gridLineColor: '#C0C0C0',
10230                tickAmount: 6
10231            }],
10232            tooltip: {
10233                crosshairs: true,
10234                shared: true,
10235                valueSuffix: '°C',
10236                 shape: 'square',
10237                useHTML: true,
10238                zIndex: 50,
10239                formatter: function () {
10240                	var date_format;
10241                	date_format="%A, den %e.%B, %H:%M Uhr";
10242                	var s = '<span style="font-size:10px">'+Highcharts.dateFormat(getVHStationDateFormat(this.x, true), this.x)+ '</span> ';
10243		            this.points.sort( ordertooltip );
10244		            $.each(this.points, function () {
10245                                var digits = 1;
10246                                var unit = 'hPa';
10247                                if (typeof this.series.name === 'string' && this.series.name.substring(0,15) === 'Bodentemperatur') {
10248                                    digits = 1;
10249                                    unit = '°C';
10250                                }
10251        		        s += '<br/>' + '<span class="hc-legend-color" style="color:' + this.series.color + '">' + '●' + '</span> '+ this.series.name + ': ' +
10252                	    '<b>'+Highcharts.numberFormat(this.y,digits) + '</b> ' + unit;
10253            		});
10254		            return s;
10255        		}
10256            },
10257            credits: { enabled: false },
10258            exporting: { enabled: false },
10259            series: vhstation_soilba_data,
10260            reflow: true
10261        });
10262    }
10263};
10264
10265var plotPhaenologie = function() {
10266    if (typeof vh_phaeno_plant_data != 'undefined' && typeof vh_phaeno_chosen_plant != 'undefined') {
10267        var timezone_id_local = typeof timezone_id !== 'undefined' ? timezone_id : null;
10268        Highcharts.setOptions({
10269            chart: {
10270                style: {
10271                    fontFamily: 'Open Sans'
10272                }
10273            },
10274            global: {
10275                /**
10276                 * Use moment-timezone.js to return the timezone offset for individual 
10277                 * timestamps, used in the X axis labels and the tooltip header.
10278                 */
10279            // getTimezoneOffset: function (timestamp) {
10280            //     return -moment.tz(timezone_id).utcOffset();
10281            // }
10282            timezone: timezone_id_local || $('#real-user-timezone').attr('data-value') || 'UTC'
10283
10284            },
10285            lang: {
10286                loading: 'Wird geladen...',
10287                months: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
10288                weekdays: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
10289                shortMonths: ['Jan', 'Feb', 'Mrz', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'],
10290            }
10291        });
10292
10293        // Drop-in fix for Highcharts issue #8477 on older Highcharts versions. The
10294        // issue is fixed since Highcharts v6.1.1.
10295        Highcharts.wrap(Highcharts.Axis.prototype, 'getPlotLinePath', function(proceed) {
10296            var path = proceed.apply(this, Array.prototype.slice.call(arguments, 1));
10297            if (path) {
10298                path.flat = false;
10299            }
10300            return path;
10301        });
10302
10303        Highcharts.Chart.prototype.firstRender = (function (func){
10304            return function(){
10305                func.apply(this, arguments);
10306                $.each(this.axes, function(){
10307                    $.each(this.plotLinesAndBands, function(){
10308                        if(this.label)
10309                            this.label.toFront();
10310                    });
10311                });
10312                if(this.tooltip && this.tooltip.label)
10313                    this.tooltip.label.toFront();
10314
10315                if(this.seriesGroup && this.seriesGroup.label)
10316                    this.seriesGroup.label.toFront();
10317            }
10318        } (Highcharts.Chart.prototype.firstRender));
10319
10320        var monthBands = {
10321            zIndex: 3,
10322            borderWidth: 1,
10323            borderColor: '#666666',
10324            color: '#bee0ff29',
10325            label: {
10326                y: 20,
10327                style: {
10328                    fontWeight: '700',
10329                    color: '#666666'
10330                }
10331            }
10332        }
10333        
10334
10335        var groupPadding = 0;
10336
10337        if(vh_phaeno_xaxis_categories.length >= 1) {
10338            groupPadding = 0.35;
10339        }
10340        if(vh_phaeno_xaxis_categories.length >= 2) {
10341            groupPadding = 0.25;
10342        }
10343        if(vh_phaeno_xaxis_categories.length >= 3) {
10344            groupPadding = 0.2;
10345        }
10346        if(vh_phaeno_xaxis_categories.length >= 4) {
10347            groupPadding = 0.1;
10348        }
10349        if(vh_phaeno_xaxis_categories.length >= 5) {
10350            groupPadding = 0;
10351        }
10352
10353        function dateFromDay(day){
10354
10355            if(day < 0)
10356                day +=1 ;
10357
10358            return moment({year: 1971, month: 0}).dayOfYear(day);
10359        }
10360
10361        var crosshairFormatter = function() {
10362            console.log(this);
10363        }
10364
10365        var tooltipFormatter = function() {
10366            
10367            //Extrema
10368            if(typeof this.date != 'undefined' && this.date.length == 8) {
10369                var year = +this.date.substr(0, 4);
10370                var month = +this.date.substr(4, 2) - 1;
10371                var day = +this.date.substr(6, 2);
10372
10373                var date = moment({year: year, month: month, day: day});
10374                var dateFormat = Highcharts.dateFormat('%e. %b %Y', date);
10375                return '<span style="color:' + this.color + '">\u25CF</span> ' + this.series.name + ': <b>' + dateFormat + '</b><br/>';
10376            }
10377
10378            //Durchschnitt
10379            if(typeof this.date != 'undefined' && this.date.length == 4) {
10380                var month = +this.date.substr(0, 2) - 1;
10381                var day = +this.date.substr(2, 2);
10382
10383                var date = moment({year: 1971, month: month, day: day});
10384                var dateFormat = Highcharts.dateFormat('%e. %b', date);
10385                return '<span style="color:' + this.color + '">\u25CF</span> ' + this.series.name + ': <b>' + dateFormat + '</b><br/>';
10386            }
10387
10388            //Perzentile
10389            if(typeof this.lowDate != 'undefined' && typeof this.highDate != 'undefined' && this.series.options.id.indexOf('percentile') !== -1) {
10390                var lowMonth = +this.lowDate.substr(0, 2) - 1;
10391                var lowDay = +this.lowDate.substr(2, 2);
10392                var lowDate = moment({year: 1971, month: lowMonth, day: lowDay});
10393
10394                if(this.lowDate == '****')
10395                    lowDate = dateFromDay(this.low);
10396
10397                var lowDateFormat = Highcharts.dateFormat('%e. %b', lowDate);
10398
10399                var highMonth = +this.highDate.substr(0, 2) - 1;
10400                var highDay = +this.highDate.substr(2, 2);
10401                var highDate = moment({year: 1971, month: highMonth, day: highDay});
10402
10403                if(this.highDate == '****')
10404                    highDate = dateFromDay(this.high);
10405
10406                var highDateFormat = Highcharts.dateFormat('%e. %b', highDate);
10407                return '<span style="color:' + this.color + '">\u25CF</span> ' + this.series.name + ': <b>' + lowDateFormat + ' - ' + highDateFormat + '</b><br/>';
10408
10409            }
10410
10411            //Allzeit-Bandbreite
10412            if(typeof this.lowDate != 'undefined' && typeof this.highDate != 'undefined' && this.series.options.id == 'alltime-bandwidth') {
10413                var lowYear = +this.lowDate.substr(0, 4);
10414                var lowMonth = +this.lowDate.substr(4, 2) - 1;
10415                var lowDay = +this.lowDate.substr(6, 2);
10416                var lowDate = moment({year: lowYear, month: lowMonth, day: lowDay});
10417
10418                if(this.lowDate == '****')
10419                    lowDate = dateFromDay(this.low);
10420
10421                var lowDateFormat = Highcharts.dateFormat('%e. %b (%Y)', lowDate);
10422
10423                var highYear = +this.highDate.substr(0, 4);
10424                var highMonth = +this.highDate.substr(4, 2) - 1;
10425                var highDay = +this.highDate.substr(6, 2);
10426                var highDate = moment({year: highYear, month: highMonth, day: highDay});
10427
10428                if(this.highDate == '****')
10429                    highDate = dateFromDay(this.high);
10430
10431                var highDateFormat = Highcharts.dateFormat('%e. %b (%Y)', highDate);
10432                return '<span style="color:' + this.color + '">\u25CF</span> ' + this.series.name + ': <b>' + lowDateFormat + ' - ' + highDateFormat + '</b><br/>';
10433
10434            }
10435
10436        };
10437
10438        var legendItemClick = function() {
10439            var hasDataShown = new Array(vh_phaeno_xaxis_categories.length).fill(false);
10440
10441            var clickedSeries = this;
10442
10443            var allHidden = true;
10444            this.chart.legend.getAllItems().forEach(function(series) {
10445                if(series.options.id == clickedSeries.options.id) return;
10446
10447                if(series.visible)
10448                    allHidden = false;
10449
10450                // console.log(series.visible);
10451            })
10452
10453            if(!allHidden)
10454                this.setVisible(!this.visible);
10455            else
10456                this.setVisible(true);
10457
10458            this.chart.series.forEach(function(seriesObj) {
10459                if(!seriesObj.visible) return;
10460
10461                seriesObj.data.forEach(function(point) {
10462                    hasDataShown[point.x] = true;
10463                });
10464            });
10465            //console.log(hasDataShown);
10466
10467            var breaks = [];
10468            hasDataShown.forEach(function(hasData, index) {
10469
10470                if(!hasData)
10471                    breaks.push( {from: index - .5, to: index + .5} );
10472
10473            });
10474
10475            //this.chart.xAxis[0].options.breaks = breaks;
10476            //this.chart.redraw();
10477            this.chart.update({xAxis: [{breaks: breaks}]});
10478
10479            return false;
10480        }
10481
10482        $('#phaeno-plant-chart').highcharts({
10483            chart: {
10484                height: 500,
10485                type: 'columnrange',
10486                inverted: true
10487            },
10488            title: {
10489                text: 'Mittelwertsdiagramm ' + vh_phaeno_chosen_plant.name
10490            },
10491            legend: {
10492                useHTML: true   
10493            },
10494            plotOptions: {
10495                columnrange: {
10496                    grouping: false,
10497                    groupPadding: groupPadding,
10498                },
10499                series: {
10500                    softThreshold: true,
10501                    threshold: 1,
10502                    events: {
10503                        legendItemClick: legendItemClick
10504                    },
10505                    minPointLength: 5
10506                }
10507            },
10508            tooltip: {
10509                pointFormatter: tooltipFormatter,
10510                positioner: function(labelWidth, labelHeight, point) {
10511                    var x = this.chart.hoverPoint.x;
10512                    var alltimeSeries = this.chart.get('alltime-bandwidth');
10513
10514                    var alltimePoint = alltimeSeries.points[x];
10515
10516                    if(point.plotX / this.chart.plotWidth < 0.5) {
10517
10518                        var absX = this.chart.plotLeft + this.chart.plotWidth - alltimePoint.plotHigh + this.options.padding + 10;
10519                        var absY = this.chart.plotTop + point.plotY;
10520
10521                        var labelOffsetX = absX;
10522                        var labelOffsetY = absY - labelHeight / 2;
10523
10524                        return { x: labelOffsetX, y: labelOffsetY };
10525                    } else {
10526                        var absX = this.chart.plotLeft + this.chart.plotWidth - alltimePoint.plotLow - labelWidth - this.options.padding - 10;
10527                        var absY = this.chart.plotTop + point.plotY;
10528
10529                        var labelOffsetX = absX;
10530                        var labelOffsetY = absY - labelHeight / 2;
10531
10532                        return { x: labelOffsetX, y: labelOffsetY };
10533                    }
10534                        
10535                    return {x: 0, y: 0};
10536                }
10537            },
10538            xAxis: [
10539                {
10540                    type: 'category',
10541                    categories: vh_phaeno_xaxis_categories,
10542                    height: '90%',
10543                    top: '10%',
10544                    labels: {
10545                        style: {
10546                            fontSize: '13px',
10547                            fontWeight: '600'
10548                        }
10549                    },
10550                    title: {
10551                        text: 'verfügbare Phasen',
10552                        style: {"fontWeight": "700"},
10553                        offset: 10,
10554                        align: 'high',
10555                        textAlign: 'right',
10556                        rotation: 0,
10557                        y: -15
10558                    },
10559                    min: 0
10560                }
10561            ],
10562            yAxis: [
10563                {
10564                    type: 'linear',
10565                    softMin: 1,
10566                    max: 365,
10567                    endOnTick: false,
10568                    startOnTick: false,
10569                    tickPixelInterval: 50,
10570                    minorTickInterval: 'auto',
10571                    tickLength: 10,
10572                    tickWidth: 1,
10573                    lineWidth: 1,
10574                    opposite: true,
10575                    title: {
10576                        text: 'Tag im Jahr',
10577                        style: {"fontWeight": "700"},
10578                        //offset: 14,
10579                        align: 'low',
10580                        x: 0
10581                    },
10582                    labels:{
10583                        style: {"fontWeight": "700"},
10584                    },
10585                    plotBands: [{
10586                            from: -31,
10587                            to: -1,
10588                            borderWidth: monthBands.borderWidth,
10589                            borderColor: monthBands.borderColor,
10590                            color: monthBands.color,
10591                            zIndex: monthBands.zIndex,
10592                            label: {
10593                                text: 'Dezember<br>Vorjahr',
10594                                y: monthBands.label.y-7,
10595                                style: monthBands.label.style
10596                            }
10597                        },{
10598                            from: 1,
10599                            to: 31,
10600                            borderWidth: monthBands.borderWidth,
10601                            borderColor: monthBands.borderColor,
10602                            color: monthBands.color,
10603                            zIndex: monthBands.zIndex,
10604                            label: {
10605                                text: 'Januar',
10606                                y: monthBands.label.y,
10607                                style: monthBands.label.style
10608                            }
10609                        },
10610                        {
10611                            from: 32,
10612                            to: 59,
10613                            borderWidth: monthBands.borderWidth,
10614                            borderColor: monthBands.borderColor,
10615                            color: monthBands.color,
10616                            zIndex: monthBands.zIndex,
10617                            label: {
10618                                text: 'Februar',
10619                                y: monthBands.label.y,
10620                                style: monthBands.label.style
10621                            }
10622                        },
10623                        {
10624                            from: 60,
10625                            to: 90,
10626                            borderWidth: monthBands.borderWidth,
10627                            borderColor: monthBands.borderColor,
10628                            color: monthBands.color,
10629                            zIndex: monthBands.zIndex,
10630                            label: {
10631                                text: 'März',
10632                                y: monthBands.label.y,
10633                                style: monthBands.label.style
10634                            }
10635                        },
10636                        {
10637                            from: 91,
10638                            to: 120,
10639                            borderWidth: monthBands.borderWidth,
10640                            borderColor: monthBands.borderColor,
10641                            color: monthBands.color,
10642                            zIndex: monthBands.zIndex,
10643                            label: {
10644                                text: 'April',
10645                                y: monthBands.label.y,
10646                                style: monthBands.label.style
10647                            }
10648                        },
10649                        {
10650                            from: 121,
10651                            to: 151,
10652                            borderWidth: monthBands.borderWidth,
10653                            borderColor: monthBands.borderColor,
10654                            color: monthBands.color,
10655                            zIndex: monthBands.zIndex,
10656                            label: {
10657                                text: 'Mai',
10658                                y: monthBands.label.y,
10659                                style: monthBands.label.style
10660                            }
10661                        },
10662                        {
10663                            from: 152,
10664                            to: 181,
10665                            borderWidth: monthBands.borderWidth,
10666                            borderColor: monthBands.borderColor,
10667                            color: monthBands.color,
10668                            zIndex: monthBands.zIndex,
10669                            label: {
10670                                text: 'Juni',
10671                                y: monthBands.label.y,
10672                                style: monthBands.label.style
10673                            }
10674                        },
10675                        {
10676                            from: 182,
10677                            to: 212,
10678                            borderWidth: monthBands.borderWidth,
10679                            borderColor: monthBands.borderColor,
10680                            color: monthBands.color,
10681                            zIndex: monthBands.zIndex,
10682                            label: {
10683                                text: 'Juli',
10684                                y: monthBands.label.y,
10685                                style: monthBands.label.style
10686                            }
10687                        },
10688                        {
10689                            from: 213,
10690                            to: 243,
10691                            borderWidth: monthBands.borderWidth,
10692                            borderColor: monthBands.borderColor,
10693                            color: monthBands.color,
10694                            zIndex: monthBands.zIndex,
10695                            label: {
10696                                text: 'August',
10697                                y: monthBands.label.y,
10698                                style: monthBands.label.style
10699                            }
10700                        },
10701                        {
10702                            from: 244,
10703                            to: 273,
10704                            borderWidth: monthBands.borderWidth,
10705                            borderColor: monthBands.borderColor,
10706                            color: monthBands.color,
10707                            zIndex: monthBands.zIndex,
10708                            label: {
10709                                text: 'September',
10710                                y: monthBands.label.y,
10711                                style: monthBands.label.style
10712                            }
10713                        },
10714                        {
10715                            from: 274,
10716                            to: 304,
10717                            borderWidth: monthBands.borderWidth,
10718                            borderColor: monthBands.borderColor,
10719                            color: monthBands.color,
10720                            zIndex: monthBands.zIndex,
10721                            label: {
10722                                text: 'Oktober',
10723                                y: monthBands.label.y,
10724                                style: monthBands.label.style
10725                            }
10726                        },
10727                        {
10728                            from: 305,
10729                            to: 334,
10730                            borderWidth: monthBands.borderWidth,
10731                            borderColor: monthBands.borderColor,
10732                            color: monthBands.color,
10733                            zIndex: monthBands.zIndex,
10734                            label: {
10735                                text: 'November',
10736                                y: monthBands.label.y,
10737                                style: monthBands.label.style
10738                            }
10739                        },
10740                        {
10741                            from: 335,
10742                            to: 365,
10743                            borderWidth: monthBands.borderWidth,
10744                            borderColor: monthBands.borderColor,
10745                            color: monthBands.color,
10746                            zIndex: monthBands.zIndex,
10747                            label: {
10748                                text: 'Dezember',
10749                                y: monthBands.label.y,
10750                                style: monthBands.label.style
10751                            }
10752                        }
10753                    ],
10754                    plotLines: [{
10755                        color: 'rgba(51, 122, 183, 0.8)',
10756                        value: moment().dayOfYear(),
10757                        width: 2,
10758                        zIndex: monthBands.zIndex + 1,
10759                        label: {
10760                            text: 'Heute ('+Highcharts.dateFormat('%e. %b %Y', moment())+')',
10761                            rotation: 0,
10762                            verticalAlign: 'bottom',
10763                            y: -10,
10764                            style: {fontWeight: '700', color: 'rgba(51, 122, 183, 1)' }
10765                        }
10766                    }]
10767          
10768                },
10769                {
10770                    type: 'linear',
10771                    linkedTo: 0,
10772                    tickPixelInterval: 70,
10773                    tickLength: 10,
10774                    tickWidth: 1,
10775                    lineWidth: 1,
10776                    gridLineWidth: 0,
10777                    title: {
10778                        text: null
10779                    },
10780                    labels:{
10781                        autoRotation: false,
10782                        padding: 1,
10783                        useHTML: true,
10784                        align: 'center',
10785                        style: {"fontWeight": "700"},
10786                        formatter: function () {
10787                            return Highcharts.dateFormat('%e. %b', dateFromDay(this.value));
10788                        }
10789                    }
10790                }
10791            ],
10792            credits: { enabled: false },
10793            exporting: { enabled: false },
10794            series: vh_phaeno_plant_data,
10795            reflow: true
10796        });
10797    }
10798
10799};
10800
10801var phaenologieShowYear = function(year) {
10802    var chart = $('#phaeno-plant-chart').highcharts();
10803
10804    chart.series.forEach(function(series) {
10805
10806        if(series.options.id.includes('recent-year')) {
10807            series.setVisible(false, false);
10808            series.options.showInLegend = false;
10809
10810            if(series.options.id.includes(year)) {
10811                series.setVisible(true, false);
10812                series.options.showInLegend = true;
10813            }
10814
10815        }
10816    
10817    });
10818
10819    chart.redraw();
10820    chart.legend.update();
10821}
10822
10823var plotOverviewWidgetGraph = function() {
10824
10825    var margin;
10826    var timezone_id_local = typeof timezone_id !== 'undefined' ? timezone_id : null;
10827    Highcharts.setOptions({
10828        global: {
10829            /**
10830             * Use moment-timezone.js to return the timezone offset for individual 
10831             * timestamps, used in the X axis labels and the tooltip header.
10832             */
10833            // getTimezoneOffset: function (timestamp) {
10834            //     return -moment.tz(timezone_id).utcOffset();
10835            // }
10836            timezone: timezone_id_local || $('#real-user-timezone').attr('data-value') || 'UTC'
10837
10838        },
10839        lang: typeof hc_user_settings_lang !== 'undefined' ? hc_user_settings_lang : {
10840            loading: 'Wird geladen...',
10841            months: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
10842            weekdays: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
10843            shortMonths: ['Jan', 'Feb', 'Mrz', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'],
10844        }
10845    });
10846    
10847    var zeroline = 0;
10848
10849    if (typeof hcwidget_overview_data_temp != 'undefined') {
10850        var yaxismax = false;
10851        if (typeof hccompact_tempmax != 'undefined') {
10852                yaxismax = hccompact_tempmax > -2 && hccompact_tempmax < 2 ? true : false;
10853        }
10854
10855        if (typeof hccompact_units != 'undefined') {
10856            if(hccompact_units['temp']=="°F") {
10857                zeroline = 32;
10858            }
10859            else if(hccompact_units['temp']=="K") {
10860                zeroline = 273.15;
10861            }
10862        }
10863
10864        $('#temp_graph').highcharts({
10865            chart: {
10866                height: 300,
10867                //width: 300,
10868                type: 'line',
10869                events: {
10870                  load: function(){
10871                    //drawHourlyLabels(this,'temp');
10872                    drawNightShadows(this,1);
10873                  },
10874                  redraw: function(){
10875                    //drawHourlyLabels(this,'temp');
10876                    drawNightShadows(this,1);
10877                  }
10878                }
10879            },
10880            title: 'false',
10881            legend: 'false',
10882            xAxis: {
10883                type: 'datetime',
10884                dateTimeLabelFormats: {
10885                    hour: '%H:%M',
10886                    day: '%e. %b'
10887                },
10888                labels:{
10889                  useHTML: true,
10890                  align: 'center',
10891                        formatter: function () {
10892                          var date_format;
10893                    var day = Highcharts.dateFormat("%e", this.value);
10894                    var hour = Highcharts.dateFormat("%H", this.value);
10895
10896                    if(hour%24==0)
10897                      date_format='%e. %b';
10898                    else
10899                      date_format='%H:%M';
10900                      return Highcharts.dateFormat(date_format, this.value);
10901                  }
10902                }
10903            },
10904            yAxis: [{
10905                title: {
10906                    text: ""
10907                },
10908                labels: {
10909                    format: "{value} "+hccompact_units['temp'],
10910                    style: { color: "#000000" }
10911                },
10912                softMax: 2,
10913                allowDecimals: true,
10914                minorTickInterval: 'auto',
10915                gridLineColor: '#C0C0C0',
10916                opposite:true,
10917                plotLines: [{
10918                    value: zeroline,
10919                    width: 2,
10920                    color: '#808080',
10921                    zIndex: 2
10922                }],
10923            }],
10924            tooltip: {
10925                crosshairs: true,
10926                shared: true,
10927                valueSuffix: ' '+hccompact_units['temp'],
10928                 shape: 'square',
10929                useHTML: true,
10930                dateTimeLabelFormats: {
10931                        minute:"%A, den %e.%B",
10932                        hour:"%A, den %e.%B",
10933                },
10934                zIndex: 50,
10935                positioner: function (w,h,p) {
10936                    if(p.plotX/this.chart.chartWidth>0.5)
10937                        return { x: 65, y: 0 };
10938                    else
10939                        return { x: this.chart.chartWidth-w-10, y: 0 };
10940                },
10941                formatter: function () { 
10942                  var date_format;
10943                  //date_format="%A, den %e.%B, %H:%M GMT+"+chartoffsethours;
10944                  date_format="%A, den %e.%B, %H:%M ";
10945                  var s = '<span style="font-size:10px">'+Highcharts.dateFormat(date_format, this.x)+ 'Uhr</span> ';
10946            this.points.sort( ordertooltip );
10947		            $.each(this.points, function () {
10948                   s += '<br/>' + '<span style="color:' + this.series.color + '">' + '</span> '+ this.series.name + ': ' + '<b>'+this.y + '</b> ' + ' '+hccompact_units['temp'];
10949                        });
10950            return s;
10951            }
10952            },
10953            plotOptions: {
10954                line: {
10955                    marker: {
10956                        enabled: false
10957                    }
10958                }
10959            },
10960            credits: { enabled: false },
10961            exporting: { enabled: false },
10962            series: hcwidget_overview_data_temp, 
10963            reflow: true
10964        });
10965
10966
10967    }
10968
10969    if (typeof hcwidget_overview_data_rain != 'undefined') {
10970        var yaxismax = false;
10971        if (typeof hccompact_tempmax != 'undefined') {
10972                yaxismax = hccompact_tempmax > -2 && hccompact_tempmax < 2 ? true : false;
10973        }
10974
10975        zeroline = 0;
10976        
10977        $('#rain_graph').highcharts({
10978            chart: {
10979                height: 300,
10980                //width: 300,
10981                type: 'column',
10982                events: {
10983                  load: function(){
10984                    //drawHourlyLabels(this,'temp');
10985                    drawNightShadows(this,2);
10986                  },
10987                  redraw: function(){
10988                    //drawHourlyLabels(this,'temp');
10989                    drawNightShadows(this,2);
10990                  }
10991                }
10992            },
10993            title: 'false',
10994            legend: 'false',
10995            xAxis: {
10996                type: 'datetime',
10997                dateTimeLabelFormats: {
10998                    hour: '%H:%M',
10999                    day: '%e. %b'
11000                },
11001                labels:{
11002                  useHTML: true,
11003                  align: 'center',
11004                        formatter: function () {
11005                          var date_format;
11006                    var day = Highcharts.dateFormat("%e", this.value);
11007                    var hour = Highcharts.dateFormat("%H", this.value);
11008
11009                    if(hour%24==0)
11010                      date_format='%e. %b';
11011                    else
11012                      date_format='%H:%M';
11013                      return Highcharts.dateFormat(date_format, this.value);
11014                  }
11015                }
11016            },
11017            yAxis: [{
11018                title: {
11019                    text: ""
11020                },
11021                labels: {
11022                    format: "{value} "+hccompact_units['rain'],
11023                    style: { color: "#000000" }
11024                },
11025                softMax: hccompact_units['rain']=="mm" ? 5 : 0.4,
11026                allowDecimals: true,
11027                minorTickInterval: 'auto',
11028                gridLineColor: '#C0C0C0',
11029                opposite:true,
11030                plotLines: [{
11031                    value: zeroline,
11032                    width: 2,
11033                    color: '#808080',
11034                    zIndex: 2
11035                }],
11036            }],
11037            tooltip: {
11038                crosshairs: true,
11039                shared: true,
11040                valueSuffix: ' '+hccompact_units['rain'],
11041                 shape: 'square',
11042                useHTML: true,
11043                dateTimeLabelFormats: {
11044                        minute:"%A, den %e.%B",
11045                        hour:"%A, den %e.%B",
11046                },
11047                zIndex: 50,
11048                positioner: function (w,h,p) {
11049                    if(p.plotX/this.chart.chartWidth>0.5)
11050                        return { x: 65, y: 0 };
11051                    else
11052                        return { x: this.chart.chartWidth-w-10, y: 0 };
11053                },
11054                formatter: function () { 
11055                  var date_format;
11056                  //date_format="%A, den %e.%B, %H:%M GMT+"+chartoffsethours;
11057                  date_format="%A, den %e.%B, %H:%M ";
11058                  var s = '<span style="font-size:10px">'+Highcharts.dateFormat(date_format, this.x)+ 'Uhr</span> ';
11059            this.points.sort( ordertooltip );
11060		            $.each(this.points, function () {
11061                   s += '<br/>' + '<span style="color:' + this.series.color + '">' + '</span> '+ this.series.name + ': ' + '<b>'+this.y + '</b> ' + ' '+hccompact_units['rain']; 
11062                        });
11063            return s;
11064            }
11065            },
11066            plotOptions: {
11067                line: {
11068                    marker: {
11069                        enabled: false
11070                    }
11071                },
11072                series: {
11073                    stacking: 'normal'
11074                }
11075            },
11076            credits: { enabled: false },
11077            exporting: { enabled: false },
11078            series: hcwidget_overview_data_rain, 
11079            reflow: true
11080        });
11081
11082
11083    }
11084
11085
11086}
11087

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.