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">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">Viento</span> <strong id="month-wind">--</strong></li>
</ul>
</div>
</div>

View File

@ -167,12 +167,13 @@ function renderMonthStats(data) {
// Agrupar por día (el cron guarda varios registros por día)
const byDay = {};
monthData.forEach(d => {
const key = d.dia; // YYYY-MM-DD
if (!byDay[key]) byDay[key] = { maxTemps: [], minTemps: [], lluvia: [], humedad: [] };
const key = d.dia;
if (!byDay[key]) byDay[key] = { maxTemps: [], minTemps: [], lluvia: [], humedad: [], viento: [] };
byDay[key].maxTemps.push(d.temp_max);
byDay[key].minTemps.push(d.temp_min);
byDay[key].lluvia.push(parseFloat(d.lluvia));
byDay[key].humedad.push(parseFloat(d.humedad));
byDay[key].viento.push(parseFloat(d.viento_velocidad ?? 0));
});
const days = Object.values(byDay);
@ -183,12 +184,18 @@ function renderMonthStats(data) {
const lluviaTotal = lluviaPorDia.reduce((sum, v) => sum + v, 0);
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 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-max").textContent = Math.max(...maxTemps) + "°C";
$("month-min").textContent = Math.min(...minTemps) + "°C";
$("month-rain").textContent = lluviaTotal.toFixed(1) + " mm (total) / " + lluviaMedia.toFixed(1) + " mm (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();
windRoseChart = new Chart(canvas, {
type: "polarArea",
type: "radar",
data: {
labels,
datasets: [{
data: values,
backgroundColor: "rgba(164, 215, 244, 0.65)",
borderColor: "rgba(164, 215, 244, 1)",
borderWidth: 1
backgroundColor: "rgba(164, 215, 244, 0.2)",
borderColor: "rgba(164, 215, 244, 0.9)",
borderWidth: 2,
pointBackgroundColor: "rgba(164, 215, 244, 1)",
pointRadius: 3
}]
},
options: {
@ -348,17 +357,16 @@ function renderWindRose(data) {
legend: { display: false },
tooltip: {
callbacks: {
label: ctx => {
const l = ctx.label;
return ` ${l}: ${ctx.raw} días · vel. media ${avgSpeed[ctx.dataIndex]} km/h`;
}
label: ctx => ` ${ctx.label}: ${ctx.raw} días · vel. media ${avgSpeed[ctx.dataIndex]} km/h`
}
}
},
scales: {
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)" },
angleLines: { color: "rgba(255,255,255,0.1)" },
pointLabels: { color: "#a4d7f4", font: { size: 13, weight: "bold" } }
}
}