From dea122bcf8bc29aa40bb65a3d87695d9678a9b0e Mon Sep 17 00:00:00 2001 From: manudous Date: Mon, 27 Apr 2026 10:31:47 +0200 Subject: [PATCH 1/2] fix: update historical average calculations to include last 10 years and remove year from model Co-authored-by: Copilot --- front/src/app/embalse/[embalse]/page.tsx | 2 -- .../src/pods/embalse/api/embalse.api-model.ts | 1 - front/src/pods/embalse/api/embalse.api.ts | 2 -- .../embalse/components/chart/chart-legend.tsx | 3 +-- .../components/chart/history-chart.tsx | 22 ++++++++++++----- front/src/pods/embalse/embalse.mapper.ts | 1 - front/src/pods/embalse/embalse.repository.ts | 24 +++++++++++++------ front/src/pods/embalse/embalse.vm.ts | 2 +- 8 files changed, 35 insertions(+), 22 deletions(-) diff --git a/front/src/app/embalse/[embalse]/page.tsx b/front/src/app/embalse/[embalse]/page.tsx index 1bca99e..5b6bf34 100644 --- a/front/src/app/embalse/[embalse]/page.tsx +++ b/front/src/app/embalse/[embalse]/page.tsx @@ -36,7 +36,6 @@ export default async function EmbalseDetallePage({ params }: Props) { const { embalse } = await params; const embalseDoc = await getEmbalseBySlugCached(embalse); const embalseInfo = await getReservoirInfoBySlugCached(embalse); - const actualYear = new Date().getFullYear(); const actualMonth = new Date().getMonth(); // return month 0-11 if (!embalseDoc) { @@ -52,7 +51,6 @@ export default async function EmbalseDetallePage({ params }: Props) { const averageHistoricalData = await getAverageHistoricalByMonthCached( embalseDoc.nombre, actualMonth + 1, - actualYear - 10, // 10 years ago ).then(mapHistoricalReservoirToViewModel); return ( diff --git a/front/src/pods/embalse/api/embalse.api-model.ts b/front/src/pods/embalse/api/embalse.api-model.ts index 0db2038..b5ab28e 100644 --- a/front/src/pods/embalse/api/embalse.api-model.ts +++ b/front/src/pods/embalse/api/embalse.api-model.ts @@ -20,6 +20,5 @@ export interface ReservoirLastYearModel { export interface HistoricalAverageReservoir { embalse: string; mes: number; - año: number; promedio_agua_actual: number; } diff --git a/front/src/pods/embalse/api/embalse.api.ts b/front/src/pods/embalse/api/embalse.api.ts index 03b09c1..6bac2d0 100644 --- a/front/src/pods/embalse/api/embalse.api.ts +++ b/front/src/pods/embalse/api/embalse.api.ts @@ -88,13 +88,11 @@ export const getAverageHistoricalByMonthCached = unstable_cache( async ( reservoirName: string, month: number, - year: number, ): Promise => { try { const historicalStatistics = await getAverageHistoricalByMonth( reservoirName, month, - year, ); if (!historicalStatistics) { diff --git a/front/src/pods/embalse/components/chart/chart-legend.tsx b/front/src/pods/embalse/components/chart/chart-legend.tsx index 3f110a3..04bacb5 100644 --- a/front/src/pods/embalse/components/chart/chart-legend.tsx +++ b/front/src/pods/embalse/components/chart/chart-legend.tsx @@ -40,8 +40,7 @@ export const ChartLegend: React.FC = ({
- {monthsNames[dataTenYearsAgo.month - 1]} de {dataTenYearsAgo.year} - : + Media {monthsNames[dataTenYearsAgo.month - 1]} (10 años): {dataTenYearsAgo.average} Hm³
diff --git a/front/src/pods/embalse/components/chart/history-chart.tsx b/front/src/pods/embalse/components/chart/history-chart.tsx index 5ed5e61..67775f4 100644 --- a/front/src/pods/embalse/components/chart/history-chart.tsx +++ b/front/src/pods/embalse/components/chart/history-chart.tsx @@ -15,7 +15,6 @@ export const HistoryChart: React.FC = ({ if (percentageActual > 100) { percentageActual = 100; } - const isOutside = percentageActual < 10; // Cálculo de escalas const x = d3 .scaleBand() @@ -37,8 +36,21 @@ export const HistoryChart: React.FC = ({ const refX1 = barX - s.margin.left / 2; const refX2 = barX * 2 + s.margin.left + s.margin.right; - // Etiqueta: encima de la barra si el nivel es muy bajo (<10%), dentro si no - const labelY = isOutside ? barY - 8 : barY + 20; + // Posiciones Y de las líneas de referencia (SVG: valor menor = más arriba) + const refYOneYear = dataOneYearAgo + ? y((dataOneYearAgo.average * 100) / reservoirData.totalCapacity) + : Infinity; + const refYTenYears = dataTenYearsAgo + ? y((dataTenYearsAgo.average * 100) / reservoirData.totalCapacity) + : Infinity; + + // La línea más alta dentro del SVG (la de menor y) + const topRefLineY = Math.min(refYOneYear, refYTenYears); + + // Etiqueta: encima de la línea de referencia más alta, dentro de la barra + const labelInsideBar = barY + 20; + const labelAboveRefs = topRefLineY - 16; + const labelY = Math.min(labelInsideBar, labelAboveRefs); return (
= ({ y={labelY} textAnchor="middle" fontSize="16px" - fill={ - isOutside ? "var(--color-base-content)" : "var(--color-brand-100)" - } + fill="var(--color-brand-100)" fontWeight="900" > {reservoirData.currentVolume} Hm³ diff --git a/front/src/pods/embalse/embalse.mapper.ts b/front/src/pods/embalse/embalse.mapper.ts index abe6866..ace57bd 100644 --- a/front/src/pods/embalse/embalse.mapper.ts +++ b/front/src/pods/embalse/embalse.mapper.ts @@ -87,7 +87,6 @@ export const mapHistoricalReservoirToViewModel = ( return Boolean(apiData) ? { nameReservoir: apiData.embalse, - year: apiData.año, month: apiData.mes, average: apiData.promedio_agua_actual, } diff --git a/front/src/pods/embalse/embalse.repository.ts b/front/src/pods/embalse/embalse.repository.ts index d97312c..239cdf0 100644 --- a/front/src/pods/embalse/embalse.repository.ts +++ b/front/src/pods/embalse/embalse.repository.ts @@ -58,17 +58,15 @@ export const getAverageLastYearByMonth = async ( }; /** - * Obtain the average monthly and annual values ​​received per parameter + * Obtain the average for a given month across the last 10 years. * * @param name:string Reservoir name * @param month:number Month number (1-12) - * @param year:number Year number (yyyy) * @returns HistoricalAverageReservoir: */ export const getAverageHistoricalByMonth = async ( reservoirName: string, month: number, - year: number, ): Promise => { try { const db = await getDb(); @@ -79,14 +77,26 @@ export const getAverageHistoricalByMonth = async ( .aggregate([ { $match: { embalse: reservoirName } }, { $unwind: "$meses" }, - { $match: { "meses.año": year, "meses.mes": month } }, + { + $match: { + "meses.mes": month, + "meses.año": { $lt: new Date().getFullYear() }, + }, + }, + { + $group: { + _id: null, + embalse: { $first: "$embalse" }, + mes: { $first: "$meses.mes" }, + promedio_agua_actual: { $avg: "$meses.promedio_agua_actual" }, + }, + }, { $project: { _id: 0, embalse: 1, - año: "$meses.año", - mes: "$meses.mes", - promedio_agua_actual: "$meses.promedio_agua_actual", + mes: 1, + promedio_agua_actual: { $round: ["$promedio_agua_actual", 2] }, }, }, ]) diff --git a/front/src/pods/embalse/embalse.vm.ts b/front/src/pods/embalse/embalse.vm.ts index 536189e..eef0297 100644 --- a/front/src/pods/embalse/embalse.vm.ts +++ b/front/src/pods/embalse/embalse.vm.ts @@ -68,7 +68,7 @@ export const createEmptyDataLastYearModel = (): DataLastYearModel => ({ export interface HistoricalAverageReservoir { nameReservoir: string; month: number; - year: number; + year?: number; average: number; } export const createEmptyHistoricalAverageReservoir = From f99173ad8778eb37820a77e8fd27d514e1d2125a Mon Sep 17 00:00:00 2001 From: manudous Date: Mon, 27 Apr 2026 10:56:21 +0200 Subject: [PATCH 2/2] fix: update label positioning in history chart and remove year from historical data mapping --- .../embalse/components/chart/history-chart.tsx | 18 +++--------------- front/src/pods/embalse/embalse.mapper.spec.ts | 2 -- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/front/src/pods/embalse/components/chart/history-chart.tsx b/front/src/pods/embalse/components/chart/history-chart.tsx index 67775f4..7c2176b 100644 --- a/front/src/pods/embalse/components/chart/history-chart.tsx +++ b/front/src/pods/embalse/components/chart/history-chart.tsx @@ -15,6 +15,7 @@ export const HistoryChart: React.FC = ({ if (percentageActual > 100) { percentageActual = 100; } + const isOutside = percentageActual < 10; // Cálculo de escalas const x = d3 .scaleBand() @@ -36,21 +37,8 @@ export const HistoryChart: React.FC = ({ const refX1 = barX - s.margin.left / 2; const refX2 = barX * 2 + s.margin.left + s.margin.right; - // Posiciones Y de las líneas de referencia (SVG: valor menor = más arriba) - const refYOneYear = dataOneYearAgo - ? y((dataOneYearAgo.average * 100) / reservoirData.totalCapacity) - : Infinity; - const refYTenYears = dataTenYearsAgo - ? y((dataTenYearsAgo.average * 100) / reservoirData.totalCapacity) - : Infinity; - - // La línea más alta dentro del SVG (la de menor y) - const topRefLineY = Math.min(refYOneYear, refYTenYears); - - // Etiqueta: encima de la línea de referencia más alta, dentro de la barra - const labelInsideBar = barY + 20; - const labelAboveRefs = topRefLineY - 16; - const labelY = Math.min(labelInsideBar, labelAboveRefs); + // Etiqueta: encima de la barra si el nivel es muy bajo (<10%), dentro si no + const labelY = isOutside ? barY - 8 : barY + 20; return (
{ describe("mapHistoricalReservoirToViewModel", () => { it("should accurately map the fields for the last ten years", () => { const mockHistoricalData: historicalApi.HistoricalAverageReservoir = { - año: 2026, embalse: "Viñuela, La", mes: 3, promedio_agua_actual: 149.21, @@ -241,7 +240,6 @@ describe("mapHistoricalReservoirToViewModel", () => { mapHistoricalReservoirToViewModel(mockHistoricalData); const expectResult = { - year: 2026, nameReservoir: "Viñuela, La", month: 3, average: 149.21,