----------------------------------------------- <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Date Chart</title> <style> #chart-container { position: relative; width: 80%; margin: auto; height: 500px; /* Adjust as needed */ } #myChart { position: absolute; top: 0; left: 0; width: 100%; height: 100%; /* Ensures the canvas covers the entire container */ } #imageBackground { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-size: contain; /* Ensure the image covers the container */ background-position: center; /* Center the image */ background-repeat: no-repeat; /* Avoid repeating the image */ opacity: 0.3; pointer-events: none; /* Ensure clicks go through to the canvas */ } </style> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> </head> <body> <button onclick="switchView('week')">Weekly View</button> <button onclick="switchView('month')">Monthly View</button> <div id="chart-container"> <div id="imageBackground"></div> <canvas id="myChart"></canvas> <div id="imageLink">...</div> </div> <script> let urlMap = new Map(); // Map to store URL mappings let dates = []; // Array to store dates for chart async function fetchData() { const response = await fetch('https://alcea-wisteria.de/artbackup/'); const html = await response.text(); return html; } function parseDOM(html) { const parser = new DOMParser(); const doc = parser.parseFromString(html, 'text/html'); const rows = doc.querySelectorAll('tr'); dates = []; urlMap.clear(); rows.forEach(row => { const dateCell = row.querySelector('td[data-sort]'); const link = row.querySelector('a[href]'); if (dateCell && link) { const dateText = dateCell.getAttribute('data-sort'); const url = link.getAttribute('href'); const dateMatch = /(\d{4}-\d{2}-\d{2})/.exec(dateText); if (dateMatch) { const date = dateMatch[1]; dates.push(date); const fullUrl = `https://alcea-wisteria.de${url}`; if (!urlMap.has(date)) { urlMap.set(date, []); } urlMap.get(date).push(fullUrl); console.log('Extracted Date:', date); console.log('Extracted URL:', fullUrl); } } }); } function getWeekYear(date) { const d = new Date(date); const year = d.getFullYear(); const start = new Date(year, 0, 1); const diff = d - start + ((start.getTimezoneOffset() - d.getTimezoneOffset()) * 60000); const oneDay = 86400000; const day = Math.floor(diff / oneDay); const week = Math.ceil((day + 1) / 7); return `${year}-W${week < 10 ? '0' : ''}${week}`; } function mapWeekToMonth(weekNumber) { if (weekNumber >= 1 && weekNumber <= 4) return '01'; // Month 01 if (weekNumber >= 5 && weekNumber <= 6) return '02'; // Month 02 if (weekNumber >= 7 && weekNumber <= 10) return '03'; // Month 03 if (weekNumber >= 11 && weekNumber <= 14) return '04'; // Month 04 if (weekNumber >= 15 && weekNumber <= 18) return '05'; // Month 05 if (weekNumber >= 19 && weekNumber <= 22) return '06'; // Month 06 if (weekNumber >= 23 && weekNumber <= 26) return '07'; // Month 07 if (weekNumber >= 27 && weekNumber <= 30) return '08'; // Month 08 if (weekNumber >= 31 && weekNumber <= 34) return '09'; // Month 09 if (weekNumber >= 35 && weekNumber <= 38) return '10'; // Month 10 if (weekNumber >= 39 && weekNumber <= 42) return '11'; // Month 11 if (weekNumber >= 43 && weekNumber <= 52) return '12'; // Month 12 return ''; // Default case if weekNumber is out of expected range } function getCounts(dates, type) { const counts = {}; dates.forEach(date => { let key; if (type === 'week') { key = getWeekYear(date); } else if (type === 'month') { key = date.slice(0, 7); // Extract YYYY-MM } counts[key] = (counts[key] || 0) + 1; }); const sortedKeys = Object.keys(counts).sort(); const labels = sortedKeys; const data = sortedKeys.map(key => counts[key]); return { labels, data }; } function findImageUrlForWeek(weekLabel) { const [year, week] = weekLabel.split('-W'); const weekNumber = parseInt(week, 10); const month = mapWeekToMonth(weekNumber); // Use mapWeekToMonth function const monthLabel = `${year}-${month}`; console.log('Calculated Month from Week:', monthLabel); return findImageUrlForMonth(monthLabel); } function findImageUrlForMonth(monthLabel) { const urls = []; dates.forEach(date => { if (date.startsWith(monthLabel)) { const dateUrls = getImageUrlsForDate(date); if (dateUrls.length > 0) { urls.push(...dateUrls); } } }); return urls.length > 0 ? urls[Math.floor(Math.random() * urls.length)] : ''; } function getImageUrlsForDate(date) { return urlMap.get(date) || []; } async function init() { const html = await fetchData(); parseDOM(html); const weekCounts = getCounts(dates, 'week'); const monthCounts = getCounts(dates, 'month'); const newestDate = dates.reduce((max, date) => (date > max ? date : max), dates[0]); const ctx = document.getElementById('myChart').getContext('2d'); const myChart = new Chart(ctx, { type: 'line', data: { labels: weekCounts.labels, datasets: [{ label: `Counts Per Week (Latest: ${newestDate})`, data: weekCounts.data, backgroundColor: 'rgba(75, 192, 192, 0.2)', borderColor: 'rgba(75, 192, 192, 1)', borderWidth: 1 }] }, options: { scales: { y: { beginAtZero: true, stepSize: 1 } }, plugins: { tooltip: { callbacks: { label: function (context) { const label = context.dataset.label || ''; const value = context.parsed.y; return `Value: ${value}`; } } } } } }); window.switchView = function (view) { if (view === 'week') { myChart.data.labels = weekCounts.labels; myChart.data.datasets[0].data = weekCounts.data; myChart.data.datasets[0].label = `Counts Per Week (Latest: ${newestDate})`; } else if (view === 'month') { myChart.data.labels = monthCounts.labels; myChart.data.datasets[0].data = monthCounts.data; myChart.data.datasets[0].label = `Counts Per Month (Latest: ${newestDate})`; } myChart.update(); }; myChart.canvas.addEventListener('click', function(event) { const points = myChart.getElementsAtEventForMode(event, 'nearest', { intersect: true }, true); if (points.length) { const firstPoint = points[0]; const label = myChart.data.labels[firstPoint.index]; let imageUrl = ''; if (label.includes('-W')) { imageUrl = findImageUrlForWeek(label); } else if (label.includes('-')) { if (label.length === 7) { // Monthly view (YYYY-MM) const urls = findImageUrlForMonth(label); imageUrl = findImageUrlForMonth(label); } else { imageUrl = getImageUrlsForDate(label)[0]; } } console.log('Clicked Date:', label); console.log('Image URL:', imageUrl); if (imageUrl) { document.getElementById('imageBackground').style.backgroundImage = `url(${imageUrl})`; document.getElementById('imageLink').outerHTML = `<a id="imageLink" href="${imageUrl}" target="_blank">${imageUrl.substring(imageUrl.lastIndexOf('/') + 1)}</a>`; } else { document.getElementById('imageBackground').style.backgroundImage = ''; } } }); } init(); </script> </body> </html> <details><summary>php version</summary><plaintext> <?php $url = "https://alcea-wisteria.de/artbackup/"; $html = file_get_contents($url); //$pattern = '/<tr>(.*?)<\/tr>/s'; //timestamp based $pattern = '/<td data-sort="([^"]*)"/'; //filename based preg_match_all($pattern, $html, $matches); $dates = array(); $urls = array(); foreach ($matches[0] as $match) { preg_match('/\d{4}-\d{2}-\d{2}/', $match, $date); if (!empty($date)) { $dates[] = $date[0]; $urls[] = $date[0]; // Append the date to the URL } } $newestIndex = array_search(max($dates), $dates); $newestUrl = $urls[$newestIndex]; // Weekly counts $weekCounts = array(); foreach ($dates as $date) { $weekYear = date('o-\WW', strtotime($date)); // Extract the year and week number if (isset($weekCounts[$weekYear])) { $weekCounts[$weekYear]++; } else { $weekCounts[$weekYear] = 1; } } $startDate = min(array_keys($weekCounts)); $endDate = date('o-\WW'); // Get the current year-week $currentDate = $startDate; while ($currentDate <= $endDate) { if (!isset($weekCounts[$currentDate])) { $weekCounts[$currentDate] = 0; } $currentDate = date('o-\WW', strtotime($currentDate . ' +1 week')); } ksort($weekCounts); $weekLabels = array_keys($weekCounts); $weekData = array_values($weekCounts); // Monthly counts $monthCounts = array(); foreach ($dates as $date) { $monthYear = date('Y-m', strtotime($date)); // Extract the year and month if (isset($monthCounts[$monthYear])) { $monthCounts[$monthYear]++; } else { $monthCounts[$monthYear] = 1; } } $startDate = min(array_keys($monthCounts)); $endDate = date('Y-m'); // Get the current year-month $currentDate = $startDate; while ($currentDate <= $endDate) { if (!isset($monthCounts[$currentDate])) { $monthCounts[$currentDate] = 0; } $currentDate = date('Y-m', strtotime($currentDate . ' +1 month')); } ksort($monthCounts); $monthLabels = array_keys($monthCounts); $monthData = array_values($monthCounts); ?> <!DOCTYPE html> <html> <head> <title>Date Chart</title> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> </head> <body> <button onclick="switchView('week')">Weekly View</button> <button onclick="switchView('month')">Monthly View</button> <canvas id="myChart"></canvas> <script> var weekLabels = <?php echo json_encode($weekLabels); ?>; var weekData = <?php echo json_encode($weekData); ?>; var monthLabels = <?php echo json_encode($monthLabels); ?>; var monthData = <?php echo json_encode($monthData); ?>; var ctx = document.getElementById('myChart').getContext('2d'); var myChart = new Chart(ctx, { type: 'line', data: { labels: weekLabels, datasets: [{ label: 'Counts Per Week (Latest: <?php echo $newestUrl; ?>)', data: weekData, backgroundColor: 'rgba(75, 192, 192, 0.2)', borderColor: 'rgba(75, 192, 192, 1)', borderWidth: 1 }] }, options: { scales: { y: { beginAtZero: true, stepSize: 1 } }, plugins: { tooltip: { callbacks: { label: function(context) { var label = context.dataset.label || ''; var value = context.parsed.y; var tooltipLabel = 'Value: ' + value; // Customize the tooltip label here return tooltipLabel; } } } } } }); function switchView(view) { if (view === 'week') { myChart.data.labels = weekLabels; myChart.data.datasets[0].data = weekData; myChart.data.datasets[0].label = 'Counts Per Week (Latest: <?php echo $newestUrl; ?>)'; } else if (view === 'month') { myChart.data.labels = monthLabels; myChart.data.datasets[0].data = monthData; myChart.data.datasets[0].label = 'Counts Per Month (Latest: <?php echo $newestUrl; ?>)'; } myChart.update(); } </script> </body> </html> </plaintext>