瀏覽代碼

fix graphs

marek 1 月之前
父節點
當前提交
597f8cc9c4

+ 7 - 7
routes/include/panel/stationsHistory.js

@@ -72,7 +72,7 @@ export default (langName, lang) => new Elysia({ prefix: "/:station/history" })
     }
 
     set.headers['content-type'] = 'text/html; charset=utf8'
-    return eta.render(`${langName}/panel/stations/history/property`, { lang, user, dateMap: { years, months, days }, type: `daily`, property, meteostanica, data })
+    return eta.render(`${langName}/panel/stations/history/property`, { lang, user, dateMap: { years, months, days, raw: dateMap }, type: `daily`, property, meteostanica, data })
   })
  .get(`/:property/daily`, async ({ cookie, redirect, set, params: { station, property }, query: { day, month, year } }) => {
     const token = cookie.session.value
@@ -114,7 +114,7 @@ export default (langName, lang) => new Elysia({ prefix: "/:station/history" })
     }
 
     set.headers['content-type'] = 'text/html; charset=utf8'
-    return eta.render(`${langName}/panel/stations/history/property`, { lang, user, dateMap: { years, months, days }, type: `daily`, property, meteostanica, data })
+    return eta.render(`${langName}/panel/stations/history/property`, { lang, user, dateMap: { years, months, days, raw: dateMap }, type: `daily`, property, meteostanica, data })
   })
   .get(`/:property/monthly`, async ({ cookie, redirect, set, params: { station, property }, query: { month, year } }) => {
     const token = cookie.session.value
@@ -154,9 +154,9 @@ export default (langName, lang) => new Elysia({ prefix: "/:station/history" })
     }
 
     set.headers['content-type'] = 'text/html; charset=utf8'
-    return eta.render(`${langName}/panel/stations/history/property`, { lang, user, dateMap: { years, months }, type: `monthly`, property, meteostanica, data })
+    return eta.render(`${langName}/panel/stations/history/property`, { lang, user, dateMap: { years, months, raw: dateMap }, type: `monthly`, property, meteostanica, data })
   })
-  .get(`/:property/yearly`, async ({ cookie, redirect, set, params: { station, property }, query: { month, year } }) => {
+  .get(`/:property/yearly`, async ({ cookie, redirect, set, params: { station, property }, query: { year } }) => {
     const token = cookie.session.value
     const session = await Auth.getSession(token)
 
@@ -192,9 +192,9 @@ export default (langName, lang) => new Elysia({ prefix: "/:station/history" })
     }
 
     set.headers['content-type'] = 'text/html; charset=utf8'
-    return eta.render(`${langName}/panel/stations/history/property`, { lang, user, dateMap: { years }, type: `yearly`, property, meteostanica, data })
+    return eta.render(`${langName}/panel/stations/history/property`, { lang, user, dateMap: { years, raw: dateMap }, type: `yearly`, property, meteostanica, data })
   })
-  .get(`/:property/allTime`, async ({ cookie, redirect, set, params: { station, property }, query: { month, year } }) => {
+  .get(`/:property/allTime`, async ({ cookie, redirect, set, params: { station, property } }) => {
     const token = cookie.session.value
     const session = await Auth.getSession(token)
 
@@ -226,7 +226,7 @@ export default (langName, lang) => new Elysia({ prefix: "/:station/history" })
     }
 
     set.headers['content-type'] = 'text/html; charset=utf8'
-    return eta.render(`${langName}/panel/stations/history/property`, { lang, user, dateMap, type: `allTime`, property, meteostanica, data })
+    return eta.render(`${langName}/panel/stations/history/property`, { lang, user, dateMap: { raw: dateMap }, type: `allTime`, property, meteostanica, data })
   })
 //   .get(`/:property/allTime`, ({ params: { property }, set }) => {
 //     const data = Meteostanica.getDataPropertyAllTime(property)

+ 59 - 2
templates/en/panel/stations/history/property.eta

@@ -78,7 +78,43 @@
 </div>
 
 <script>
-  const ctx = document.getElementById('historyChart');
+  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 months = Object.keys(dateMap[years.find(i => i === yearSelect.value) ?? years[years.length - 1]])
+    const days = dateMap[years.find(i => i === yearSelect.value) ?? years[years.length - 1]][months.find(i => i === monthSelect?.value) ?? months[months.length - 1]]
+
+    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',
@@ -98,4 +134,25 @@
       }
     }
   });
-</script>
+</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(',')}}`; %>
+<% } %>

+ 58 - 1
templates/sk/panel/stations/history/property.eta

@@ -78,6 +78,42 @@
 </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 months = Object.keys(dateMap[years.find(i => i === yearSelect.value) ?? years[years.length - 1]])
+    const days = dateMap[years.find(i => i === yearSelect.value) ?? years[years.length - 1]][months.find(i => i === monthSelect?.value) ?? months[months.length - 1]]
+
+    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.getElementById('historyChart');
 
   new Chart(ctx, {
@@ -98,4 +134,25 @@
       }
     }
   });
-</script>
+</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(',')}}`; %>
+<% } %>