PageSourceSearch

https://tourismus.bayern/wp-content/plugins/baytm-m17-chart-fix/assets/js/m17-chart-fix-v2.js

js tourismus.bayern collected 2026-10-02 10:23:10 UTC 7,691 bytes, 281 lines download raw bytes

1(function () {
2    "use strict";
3
4    var MODULE_SELECTOR = "#statistics.statSection";
5    var CHART_SELECTOR = ".apexcharts-canvas";
6    var Y_AXIS_LABEL_SELECTOR = ".apexcharts-yaxis text";
7    var scheduledRuns = new Set();
8    var observerPaused = false;
9
10    function round(value) {
11        return Math.round(value * 10) / 10;
12    }
13
14    function getModuleRoot() {
15        return document.querySelector(MODULE_SELECTOR);
16    }
17
18    function getCharts() {
19        var root = getModuleRoot();
20
21        if (!root) {
22            return [];
23        }
24
25        return Array.prototype.slice.call(root.querySelectorAll(CHART_SELECTOR));
26    }
27
28    function getYAxisLabelTops(chart) {
29        return Array.prototype.slice.call(chart.querySelectorAll(Y_AXIS_LABEL_SELECTOR))
30            .map(function (label) {
31                var rect = label.getBoundingClientRect();
32                return round(rect.top);
33            })
34            .filter(function (top) {
35                return Number.isFinite(top) && top > 0;
36            });
37    }
38
39    function getYAxisLabels(chart) {
40        return Array.prototype.slice.call(chart.querySelectorAll(Y_AXIS_LABEL_SELECTOR));
41    }
42
43    function hasCollapsedYAxis(chart) {
44        var labels = getYAxisLabels(chart);
45        var tops = getYAxisLabelTops(chart);
46
47        if (labels.length < 3 || tops.length < 3) {
48            return false;
49        }
50
51        var uniqueTops = Array.from(new Set(tops));
52
53        if (uniqueTops.length <= 2) {
54            return true;
55        }
56
57        for (var index = 1; index < uniqueTops.length; index += 1) {
58            if (Math.abs(uniqueTops[index] - uniqueTops[index - 1]) < 2) {
59                return true;
60            }
61        }
62
63        return false;
64    }
65
66    function parseLabelValue(text) {
67        if (!text) {
68            return null;
69        }
70
71        var normalized = String(text)
72            .replace(/\s+/g, " ")
73            .trim()
74            .replace(/\./g, "")
75            .replace(",", ".");
76        var multiplier = 1;
77
78        if (/mio/i.test(normalized)) {
79            multiplier = 1000000;
80        } else if (/tsd/i.test(normalized)) {
81            multiplier = 1000;
82        } else if (/\bb\b/i.test(normalized)) {
83            multiplier = 1000000000;
84        }
85
86        var match = normalized.match(/-?\d+(?:\.\d+)?/);
87
88        if (!match) {
89            return null;
90        }
91
92        return parseFloat(match[0]) * multiplier;
93    }
94
95    function getPlotRect(chart) {
96        var plot = chart.querySelector(".apexcharts-grid");
97
98        if (!plot) {
99            plot = chart.querySelector(".apexcharts-inner");
100        }
101
102        if (!plot) {
103            plot = chart.querySelector("svg");
104        }
105
106        return plot ? plot.getBoundingClientRect() : null;
107    }
108
109    function getSvgMetrics(chart) {
110        var svg = chart.querySelector("svg");
111
112        if (!svg) {
113            return null;
114        }
115
116        var svgRect = svg.getBoundingClientRect();
117        var viewBox = svg.viewBox && svg.viewBox.baseVal ? svg.viewBox.baseVal : null;
118        var width = viewBox && viewBox.width ? viewBox.width : svgRect.width;
119        var height = viewBox && viewBox.height ? viewBox.height : svgRect.height;
120
121        if (!svgRect.height || !height) {
122            return null;
123        }
124
125        return {
126            svg: svg,
127            rect: svgRect,
128            scaleY: height / svgRect.height
129        };
130    }
131
132    function distributeYAxisLabels(chart) {
133        var labels = getYAxisLabels(chart);
134        var plotRect = getPlotRect(chart);
135        var svgMetrics = getSvgMetrics(chart);
136
137        if (labels.length < 3 || !plotRect || !svgMetrics) {
138            return;
139        }
140
141        var labelRects = labels.map(function (label) {
142            return label.getBoundingClientRect();
143        });
144        var averageHeight = labelRects.reduce(function (sum, rect) {
145            return sum + rect.height;
146        }, 0) / labelRects.length;
147        var topClientY = plotRect.top + averageHeight * 0.5;
148        var bottomClientY = plotRect.bottom - averageHeight * 0.5;
149        var step = labels.length > 1 ? (bottomClientY - topClientY) / (labels.length - 1) : 0;
150        var firstValue = parseLabelValue(labels[0].textContent);
151        var lastValue = parseLabelValue(labels[labels.length - 1].textContent);
152        var descending = firstValue !== null && lastValue !== null ? firstValue > lastValue : true;
153
154        labels.forEach(function (label, index) {
155            var targetClientY = descending
156                ? topClientY + step * index
157                : bottomClientY - step * index;
158            var svgY = (targetClientY - svgMetrics.rect.top) * svgMetrics.scaleY;
159
160            label.setAttribute("y", svgY.toFixed(2));
161            label.setAttribute("dominant-baseline", "middle");
162            label.setAttribute("alignment-baseline", "middle");
163            label.removeAttribute("transform");
164        });
165    }
166
167    function repairChart(chart) {
168        if (!hasCollapsedYAxis(chart)) {
169            return;
170        }
171
172        observerPaused = true;
173        distributeYAxisLabels(chart);
174
175        window.setTimeout(function () {
176            observerPaused = false;
177        }, 120);
178    }
179
180    function repairCharts() {
181        var charts = getCharts();
182
183        if (!charts.length) {
184            return;
185        }
186
187        charts.forEach(function (chart) {
188            repairChart(chart);
189        });
190    }
191
192    function scheduleRepair(delay) {
193        if (scheduledRuns.has(delay)) {
194            return;
195        }
196
197        scheduledRuns.add(delay);
198
199        window.setTimeout(function () {
200            scheduledRuns.delete(delay);
201            repairCharts();
202        }, delay);
203    }
204
205    function scheduleRepairBurst() {
206        [120, 360, 720].forEach(scheduleRepair);
207    }
208
209    function bindModuleListeners(root) {
210        root.addEventListener(
211            "click",
212            function () {
213                scheduleRepairBurst();
214            },
215            true
216        );
217
218        root.addEventListener(
219            "change",
220            function () {
221                scheduleRepairBurst();
222            },
223            true
224        );
225
226        var observer = new MutationObserver(function (mutations) {
227            if (observerPaused) {
228                return;
229            }
230
231            var shouldRepair = mutations.some(function (mutation) {
232                if (mutation.type === "childList") {
233                    return mutation.addedNodes.length > 0 || mutation.removedNodes.length > 0;
234                }
235
236                return false;
237            });
238
239            if (shouldRepair) {
240                scheduleRepairBurst();
241            }
242        });
243
244        observer.observe(root, {
245            childList: true,
246            subtree: true
247        });
248    }
249
250    function init() {
251        var root = getModuleRoot();
252
253        if (!root) {
254            return;
255        }
256
257        bindModuleListeners(root);
258        scheduleRepairBurst();
259
260        window.addEventListener("load", scheduleRepairBurst, { passive: true });
261        window.addEventListener("pageshow", scheduleRepairBurst, { passive: true });
262
263        document.addEventListener("visibilitychange", function () {
264            if (!document.hidden) {
265                scheduleRepairBurst();
266            }
267        });
268
269        if (document.fonts && typeof document.fonts.ready === "object") {
270            document.fonts.ready.then(scheduleRepairBurst).catch(function () {
271                scheduleRepairBurst();
272            });
273        }
274    }
275
276    if (document.readyState === "loading") {
277        document.addEventListener("DOMContentLoaded", init, { once: true });
278    } else {
279        init();
280    }
281})();

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.