diff --git a/django_project/frontend/src/components/DashboardCharts/CombinedCharts.tsx b/django_project/frontend/src/components/DashboardCharts/CombinedCharts.tsx index c34c4b6f..65b8aee3 100644 --- a/django_project/frontend/src/components/DashboardCharts/CombinedCharts.tsx +++ b/django_project/frontend/src/components/DashboardCharts/CombinedCharts.tsx @@ -5,10 +5,9 @@ import { Bar, Line } from "react-chartjs-2"; import { CategoryScale } from "chart.js"; import Chart from "chart.js/auto"; import ChartDataLabels from "chartjs-plugin-datalabels"; -import {FeatureCollection} from "geojson"; +import { FeatureCollection } from "geojson"; import 'chartjs-adapter-date-fns'; - Chart.register(CategoryScale); interface Props { @@ -16,22 +15,24 @@ interface Props { } export function BarChart({ analysis }: Props) { - // Extracting data for the chart - - const jsonData = analysis.results[0]; + const jsonData = analysis.results?.[0]; - let labels: number[] = [jsonData.features[0].properties.year]; - if (jsonData.features.length > 1) { - labels.push(jsonData.features[jsonData.features.length -1].properties.year); + if (!jsonData || !jsonData.features || jsonData.features.length === 0) { + return; } - const name1 = jsonData.features[0].properties.Name; - const name2 = jsonData.features.length > 1 ? jsonData.features[1].properties.Name : null; + + const name1 = jsonData.features?.[0]?.properties?.Name; + const name2 = jsonData.features?.[1]?.properties?.Name || null; + + const labels: number[] = jsonData.features?.length + ? [jsonData.features?.[0]?.properties?.year, jsonData.features?.[jsonData.features.length - 1]?.properties?.year] + : []; const dataBar1 = jsonData.features - .filter((feature:any) => feature.properties.Name === name1) - .map((feature:any) => feature.properties[analysis.data.variable]); + .filter((feature: any) => feature?.properties?.Name === name1) + .map((feature: any) => feature?.properties?.[analysis.data.variable] || 0); - let chartData:any = { + let chartData: any = { labels, datasets: [ { @@ -42,10 +43,10 @@ export function BarChart({ analysis }: Props) { ], }; - if (name2 !== null && name1 != name2) { + if (name2 !== null && name1 !== name2) { const dataBar2 = jsonData.features - .filter((feature:any) => feature.properties.Name === name2) - .map((feature:any) => feature.properties[analysis.data.variable]); + .filter((feature: any) => feature?.properties?.Name === name2) + .map((feature: any) => feature?.properties?.[analysis.data.variable] || 0); chartData.datasets.push({ label: name2, @@ -54,7 +55,7 @@ export function BarChart({ analysis }: Props) { }); } - const options:any = { + const options: any = { responsive: true, maintainAspectRatio: false, plugins: { @@ -64,7 +65,7 @@ export function BarChart({ analysis }: Props) { title: { display: false, }, - }, + }, scales: { y: { beginAtZero: true, @@ -72,25 +73,28 @@ export function BarChart({ analysis }: Props) { } }; - return + return ; } export function LineChart({ analysis }: Props) { - // Extracting data for the chart + const jsonData = analysis.results?.[1]; - const jsonData = analysis.results[1]; + if (!jsonData || !jsonData.features || jsonData.features.length === 0) { + return; + } + + const name1 = jsonData.features?.[0]?.properties?.Name; + const name2 = jsonData.features?.[1]?.properties?.Name || null; - const name1 = jsonData.features[0].properties.Name; - const name2 = jsonData.features[1].properties.Name; const labels: number[] = jsonData.features - .filter((feature:any) => feature.properties.Name === name1) - .map((feature:any) => feature.properties.date); + .filter((feature: any) => feature?.properties?.Name === name1) + .map((feature: any) => feature?.properties?.date || ''); const data1 = jsonData.features - .filter((feature:any) => feature.properties.Name === name1) - .map((feature:any) => feature.properties[analysis.data.variable]); + .filter((feature: any) => feature?.properties?.Name === name1) + .map((feature: any) => feature?.properties?.[analysis.data.variable] || 0); - let chartData:any = { + let chartData: any = { labels, datasets: [ { @@ -101,10 +105,10 @@ export function LineChart({ analysis }: Props) { ], }; - if (name1 != name2) { + if (name1 !== name2) { const data2 = jsonData.features - .filter((feature:any) => feature.properties.Name === name2) - .map((feature:any) => feature.properties[analysis.data.variable]); + .filter((feature: any) => feature?.properties?.Name === name2) + .map((feature: any) => feature?.properties?.[analysis.data.variable] || 0); chartData.datasets.push({ label: name2, @@ -113,7 +117,7 @@ export function LineChart({ analysis }: Props) { }); } - const options:any = { + const options: any = { responsive: true, maintainAspectRatio: false, scales: { @@ -143,25 +147,29 @@ export function LineChart({ analysis }: Props) { }, }; - return + return ; } function SpatialBarChart({ analysis }: Props) { - const featureCollection: FeatureCollection = analysis.results; + const featureCollection: FeatureCollection | undefined = analysis.results; + + if (!featureCollection || !featureCollection.features || featureCollection.features.length === 0) { + return; + } - const labels: string[] = featureCollection.features.map((feature) => feature.properties['Name']) - let chartData:any = { + const labels: string[] = featureCollection.features.map((feature) => feature?.properties?.['Name'] || 'Unknown'); + let chartData: any = { labels, datasets: [ { label: '% difference to reference area', - data: featureCollection.features.map((feature) => feature.properties["mean"]), + data: featureCollection.features.map((feature) => feature?.properties?.["mean"] || 0), backgroundColor: "blue" } ], }; - - const options:any = { + + const options: any = { responsive: true, maintainAspectRatio: false, plugins: { @@ -188,71 +196,103 @@ function SpatialBarChart({ analysis }: Props) { } }; - return + return ; } - export function RenderBaseline({ analysis }: Props) { - const keys = Object.keys(analysis.results.columns) - return - - - - { - keys.map( - (column: string) => - ) - } - - { - analysis.results.features.map((feature: any) => { - const properties = feature.properties; - return - - { - keys.map( - (column: string) => - ) - } + if (!analysis.results?.features) { + return; + } + + const keys = Object.keys(analysis.results?.columns || {}); + return ( + +
Name{column}
{properties.Name} - {properties[column]} -
+ + + + {keys.map((column: string) => )} - }) - } -
Name{column}
-
+ + + {analysis.results.features.map((feature: any, index: number) => { + const properties = feature?.properties || {}; + return ( + + {properties.Name || 'N/A'} + {keys.map((column: string) => ( + {properties[column] || 'N/A'} + ))} + + ); + })} + + + + ); } export function RenderTemporal({ analysis }: Props) { - return ( - + const jsonDataLine = analysis.results?.[1]; + const jsonDataBar = analysis.results?.[0]; + + const hasLineData = jsonDataLine?.features?.length > 0; + const hasBarData = jsonDataBar?.features?.length > 0; + + const charts = []; + + if(hasLineData && hasBarData){ + charts.push( + ); + charts.push( - + + ); + }else if (hasLineData) { + charts.push( + + ); + }else if (hasBarData) { + charts.push( + + ); + } + + if (charts.length === 0) { + return No chart data available.; + } + + return ( + + {charts} ); } + + export function RenderSpatial({ analysis }: Props) { - return - Relative % difference in {analysis.data.variable} between your reference area and selected camp/s: - - + return ( + + Relative % difference in {analysis.data.variable} between your reference area and selected camp/s: + + + ); } - export function RenderResult({ analysis }: Props) { switch (analysis.data.analysisType) { case "Baseline": - return + return ; case "Temporal": - return + return ; case "Spatial": - return + return ; default: - return null + return No analysis type selected.; } }