| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- <% layout("/en/history/layout", { title: `history` }) %>
- <%~ include("/en/partials/topbar") %>
- <% const backIcon = `
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
- <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m12 19l-7-7l7-7m7 7H5" />
- </svg>
- ` %>
- <div class="container-row">
- <a role="button" href="/en/history"><%~ backIcon %> history</a>
- <h2><%~ it?.lang?.history.properties?.[it?.property]() %></h2>
- </div>
- <div class="historyLinks">
- <a role="button" href="/en/history/<%= it.property %>/daily">day</a>
- <a role="button" href="/en/history/<%= it.property %>/monthly">month</a>
- <a role="button" href="/en/history/<%= it.property %>/yearly">year</a>
- <a role="button" href="/en/history/<%= it.property %>/allTime">all time</a>
- </div>
- <% if (it?.dateMap?.years) { %>
- <form id="historyForm">
- <% if (it?.dateMap?.days) { %>
- <div>
- <label for="day">day</label>
- <select id="day" name="day">
- <% for (const item of it?.dateMap?.days) { %>
- <option value="<%= item %>" <%= item === it?.selected?.day ? `selected` : `` %> ><%= item %></option>
- <% } %>
- </select>
- </div>
- <% } %>
- <% if (it?.dateMap?.months) { %>
- <div>
- <label for="month">month</label>
- <select id="month" name="month">
- <% for (const item of it?.dateMap?.months) { %>
- <option value="<%= item %>" <%= item === it?.selected?.month ? `selected` : `` %> > <%= it?.lang?.general.dateFormats.months?.[item]() %></option>
- <% } %>
- </select>
- </div>
- <% } %>
- <div>
- <label for="year">year</label>
- <select id="year" name="year">
- <% for (const item of it?.dateMap?.years) { %>
- <option value="<%= item %>" <%= item === it?.selected?.year ? `selected` : `` %> > <%= item %></option>
- <% } %>
- </select>
- </div>
- <button type="submit">load</button>
- </form>
- <% } %>
- <% const time = [] %>
- <% const data = [] %>
- <% for (const item of it.data) { %>
- <% time.push(item.timeMark) %>
-
- <% if (it.property === "outdoorConnected") {%>
- <% data.push(item.value) %>
- <% continue %>
- <% } %>
- <% data.push(item.value / 100) %>
- <% } %>
- <div>
- <canvas id="historyChart"></canvas>
- </div>
- <script>
- const dateMap = <%~ JSON.stringify(it?.dateMap.raw, null, 2) %>
- const monthLang = <%~ serializeToCode(it?.lang?.general.dateFormats.months) %>
- const daySelect = document.querySelector("#historyForm select#day")
- const monthSelect = document.querySelector("#historyForm select#month")
- const yearSelect = document.querySelector("#historyForm select#year")
- monthSelect.addEventListener('change', resetHistoryForm)
- yearSelect.addEventListener('change', resetHistoryForm)
- function resetHistoryForm(e) {
- daySelect.textContent = ''
- if (e.target.id === "year") monthSelect.textContent = ''
- const years = Object.keys(dateMap)
- const selectedYear = years.find(i => i === yearSelect.value) ?? years[years.length - 1]
- const months = Object.keys(dateMap[selectedYear])
- const selectedMonth = months.find(i => i === monthSelect.value) ?? months[months.length - 1]
- const days = dateMap[selectedYear][selectedMonth]
- for (const day of days) {
- const option = document.createElement('option')
- option.textContent = day
- option.value = day
- daySelect.append(option)
- }
- if (e.target.id === "year") {
- for (const [key, value] of Object.entries(months)) {
- const option = document.createElement('option')
- option.textContent = monthLang[key]()
- option.value = key
- monthSelect.append(option)
- }
- }
- }
- const ctx = document.querySelector('#historyChart');
- new Chart(ctx, {
- type: 'bar',
- data: {
- labels: <%~ JSON.stringify(time, null, 2) %>,
- datasets: [{
- label: `<%= it.property %>`,
- data: <%~ JSON.stringify(data, null, 2) %>,
- borderWidth: 1
- }]
- },
- options: {
- scales: {
- y: {
- beginAtZero: true
- }
- }
- }
- });
- </script>
- <% function serializeToCode(obj) { %>
- <% // Handle null/primitive types %>
- <% if (obj === null) return 'null'; %>
- <% if (typeof obj === 'string') return `'${obj.replace(/'/g, "\\'")}'`; %>
- <% if (typeof obj !== 'object') return obj.toString(); %>
- <% // Handle Arrays %>
- <% if (Array.isArray(obj)) { %>
- <% return `[${obj.map(item => serializeToCode(item)).join(',')}]`; %>
- <% } %>
- <% // Handle Objects %>
- <% const entries = Object.entries(obj).map(([key, value]) => { %>
- <% // Ensure keys are safe (quoted if they contain special characters) %>
- <% const safeKey = /^[a-z$_][a-z0-9$_]*$/i.test(key) ? key : `'${key}'`; %>
- <% return `${safeKey}: ${serializeToCode(value)}`; %>
- <% }); %>
- <% return `{${entries.join(',')}}`; %>
- <% } %>
|