feat: wind rose tipo radar, viento max/media/min en resumen del mes

This commit is contained in:
Tatiana Villa Ema 2026-04-27 01:16:30 +02:00
parent d6c9f5e781
commit 0bacaa4706
2 changed files with 20 additions and 11 deletions

View File

@ -100,6 +100,7 @@
<li><span class="dato-label">Mínima absoluta</span> <strong id="month-min">--</strong></li> <li><span class="dato-label">Mínima absoluta</span> <strong id="month-min">--</strong></li>
<li><span class="dato-label">Lluvia</span> <strong id="month-rain">--</strong></li> <li><span class="dato-label">Lluvia</span> <strong id="month-rain">--</strong></li>
<li><span class="dato-label">Humedad</span> <strong id="month-humidity">--</strong></li> <li><span class="dato-label">Humedad</span> <strong id="month-humidity">--</strong></li>
<li><span class="dato-label">Viento</span> <strong id="month-wind">--</strong></li>
</ul> </ul>
</div> </div>
</div> </div>

View File

@ -167,12 +167,13 @@ function renderMonthStats(data) {
// Agrupar por día (el cron guarda varios registros por día) // Agrupar por día (el cron guarda varios registros por día)
const byDay = {}; const byDay = {};
monthData.forEach(d => { monthData.forEach(d => {
const key = d.dia; // YYYY-MM-DD const key = d.dia;
if (!byDay[key]) byDay[key] = { maxTemps: [], minTemps: [], lluvia: [], humedad: [] }; if (!byDay[key]) byDay[key] = { maxTemps: [], minTemps: [], lluvia: [], humedad: [], viento: [] };
byDay[key].maxTemps.push(d.temp_max); byDay[key].maxTemps.push(d.temp_max);
byDay[key].minTemps.push(d.temp_min); byDay[key].minTemps.push(d.temp_min);
byDay[key].lluvia.push(parseFloat(d.lluvia)); byDay[key].lluvia.push(parseFloat(d.lluvia));
byDay[key].humedad.push(parseFloat(d.humedad)); byDay[key].humedad.push(parseFloat(d.humedad));
byDay[key].viento.push(parseFloat(d.viento_velocidad ?? 0));
}); });
const days = Object.values(byDay); const days = Object.values(byDay);
@ -183,12 +184,18 @@ function renderMonthStats(data) {
const lluviaTotal = lluviaPorDia.reduce((sum, v) => sum + v, 0); const lluviaTotal = lluviaPorDia.reduce((sum, v) => sum + v, 0);
const lluviaMedia = lluviaTotal / days.length; const lluviaMedia = lluviaTotal / days.length;
const humedad = (days.reduce((sum, d) => sum + d.humedad.reduce((a, b) => a + b, 0) / d.humedad.length, 0) / days.length).toFixed(1); const humedad = (days.reduce((sum, d) => sum + d.humedad.reduce((a, b) => a + b, 0) / d.humedad.length, 0) / days.length).toFixed(1);
const vientoMaxPorDia = days.map(d => Math.max(...d.viento));
const vientoMediaPorDia = days.map(d => d.viento.reduce((a, b) => a + b, 0) / d.viento.length);
const vientoMax = Math.max(...vientoMaxPorDia).toFixed(0);
const vientoMin = Math.min(...vientoMaxPorDia).toFixed(0);
const vientoMedia = (vientoMediaPorDia.reduce((a, b) => a + b, 0) / days.length).toFixed(1);
$("month-days").textContent = days.length; $("month-days").textContent = days.length;
$("month-max").textContent = Math.max(...maxTemps) + "°C"; $("month-max").textContent = Math.max(...maxTemps) + "°C";
$("month-min").textContent = Math.min(...minTemps) + "°C"; $("month-min").textContent = Math.min(...minTemps) + "°C";
$("month-rain").textContent = lluviaTotal.toFixed(1) + " mm (total) / " + lluviaMedia.toFixed(1) + " mm (media diaria)"; $("month-rain").textContent = lluviaTotal.toFixed(1) + " mm (total) / " + lluviaMedia.toFixed(1) + " mm (media diaria)";
$("month-humidity").textContent = humedad + " % (media diaria)"; $("month-humidity").textContent = humedad + " % (media diaria)";
$("month-wind").textContent = `${vientoMax} km/h (máx) / ${vientoMedia} km/h (media) / ${vientoMin} km/h (mín)`;
} }
// ==================== // ====================
@ -332,14 +339,16 @@ function renderWindRose(data) {
if (windRoseChart) windRoseChart.destroy(); if (windRoseChart) windRoseChart.destroy();
windRoseChart = new Chart(canvas, { windRoseChart = new Chart(canvas, {
type: "polarArea", type: "radar",
data: { data: {
labels, labels,
datasets: [{ datasets: [{
data: values, data: values,
backgroundColor: "rgba(164, 215, 244, 0.65)", backgroundColor: "rgba(164, 215, 244, 0.2)",
borderColor: "rgba(164, 215, 244, 1)", borderColor: "rgba(164, 215, 244, 0.9)",
borderWidth: 1 borderWidth: 2,
pointBackgroundColor: "rgba(164, 215, 244, 1)",
pointRadius: 3
}] }]
}, },
options: { options: {
@ -348,17 +357,16 @@ function renderWindRose(data) {
legend: { display: false }, legend: { display: false },
tooltip: { tooltip: {
callbacks: { callbacks: {
label: ctx => { label: ctx => ` ${ctx.label}: ${ctx.raw} días · vel. media ${avgSpeed[ctx.dataIndex]} km/h`
const l = ctx.label;
return ` ${l}: ${ctx.raw} días · vel. media ${avgSpeed[ctx.dataIndex]} km/h`;
}
} }
} }
}, },
scales: { scales: {
r: { r: {
ticks: { color: "#666", font: { size: 10 }, backdropColor: "transparent" }, beginAtZero: true,
ticks: { color: "#666", font: { size: 9 }, backdropColor: "transparent", stepSize: 1 },
grid: { color: "rgba(255,255,255,0.08)" }, grid: { color: "rgba(255,255,255,0.08)" },
angleLines: { color: "rgba(255,255,255,0.1)" },
pointLabels: { color: "#a4d7f4", font: { size: 13, weight: "bold" } } pointLabels: { color: "#a4d7f4", font: { size: 13, weight: "bold" } }
} }
} }