(function () { function updateClock(clock) { clock.innerHTML = new Date().toLocaleTimeString("de-DE", { hour: "2-digit", minute: "2-digit", }); } function ensureTableSize(table, x, y) { // Adjust number of rows while (table.rows.length < x) { table.insertRow(); } while (table.rows.length > x) { table.deleteRow(table.rows.length - 1); } // Ensure each row has y cells for (let row of table.rows) { while (row.cells.length < y) { row.insertCell(); } while (row.cells.length > y) { row.deleteCell(row.cells.length - 1); } } } function formatWithSign(num) { if (num > 0) { return `+ ${num}`; } else if (num < 0) { return `- ${Math.abs(num)}`; } else { return ""; } } function cssClassExists(className) { return Array.from(document.styleSheets).some((sheet) => { try { return Array.from(sheet.cssRules).some( (rule) => rule.selectorText === `.${className}` ); } catch (e) { // Ignore CORS-restricted stylesheets return false; } }); } function fill_table(data, table) { // const res = JSON.parse(result) const columns = { line: 0, destination: 1, departure_time: 2, departure_delay: 3, until_departure: 4, }; // console.log(data) // ensureTableSize(table, Math.min(data.length, 8), 5); for (let i = 0; i < Math.min(data.length, table.rows.length); i++) { const row = table.rows[i]; console.log(row); // row.classList.add("departure-table-row") // row.style.height = `$10%`; const train = Object.entries(data[i]); for (let [key, value] of train) { if (key in columns) { const cell = row.cells[columns[key]]; let newContent = ""; let newClassList = []; if (key in columns) { newClassList.push(key); } if (key == "line") { const lineClass = `line-${value}`; const appliedClass = cssClassExists(lineClass) ? lineClass : "line-default"; newContent = `${value}`; } if (key == "destination") { let dest = String(value) .replace(/\s*\(.*?\)\s*/g, "") .replace(/^München\s*/i, "") .replace(/^[\s-]+|[\s-]+$/g, "") .replace("Ost", "Ostbahnhof") .replace("Hbf", "Hauptbahnhof") .replace("Gl.", "Gl. "); newContent = dest; } if (key == "departure_time") { if (train["canceled"]) { newContent = "Fällt aus :("; newClassList.push("train-canceled"); } else { const date = new Date(value * 1000); newContent = date.toLocaleTimeString("de-DE", { hour: "2-digit", minute: "2-digit", }); } } if (key == "departure_delay") { if (!train["canceled"]) { newContent = formatWithSign(value); if (value >= 5) newClassList.push("delay-high"); else if (value < 0) newClassList.push("delay-neg"); } } if (key == "until_departure") { if (!train["canceled"]) { const minutes = Math.round((value + 0) / 60); newContent = String(minutes) + " min"; if (minutes <= 6) newClassList.push("until-low"); else if (minutes <= 10) newClassList.push("until-medium"); } } // Only update if content changed if ( (cell.innerHTML !== newContent && key === "line") || (cell.textContent !== newContent && key !== "line") ) { if (key === "line") { cell.innerHTML = newContent; } else { cell.textContent = newContent; } } // Update classes only if changed cell.className = ""; // Clear all classes for (const cls of newClassList) cell.classList.add(cls); } } } // document.querySelector('.departure-table') // .style.setProperty('--row-count', table.rows.length); } function updateTable(table) { fetch("/update", { method: "POST", headers: { "Content-Type": "application/json", }, // TODO: pass number of rows we want }) .then((response) => response.json()) .then((result) => { // console.log(result); fill_table(result.table_data, table); // const res = JSON.parse(result); // console.log(res.table_data); // for (const elem of res.table_data) { // console.log(elem); // } }); } var clockElement = document.getElementById("clock"); var tableElement = document.getElementById("departures"); setInterval(function () { updateClock(clockElement); updateTable(tableElement); }, 1000); })();