Skip to content

Commit

Permalink
patch: add safety checks (#315)
Browse files Browse the repository at this point in the history
  • Loading branch information
tinashechiraya authored Feb 6, 2025
1 parent a92cb48 commit 1dec9a0
Showing 1 changed file with 120 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,34 @@ 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 {
analysis: Analysis;
}

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: [
{
Expand All @@ -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,
Expand All @@ -54,7 +55,7 @@ export function BarChart({ analysis }: Props) {
});
}

const options:any = {
const options: any = {
responsive: true,
maintainAspectRatio: false,
plugins: {
Expand All @@ -64,33 +65,36 @@ export function BarChart({ analysis }: Props) {
title: {
display: false,
},
},
},
scales: {
y: {
beginAtZero: true,
},
}
};

return <Bar options={options} data={chartData} />
return <Bar options={options} data={chartData} />;
}

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: [
{
Expand All @@ -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,
Expand All @@ -113,7 +117,7 @@ export function LineChart({ analysis }: Props) {
});
}

const options:any = {
const options: any = {
responsive: true,
maintainAspectRatio: false,
scales: {
Expand Down Expand Up @@ -143,25 +147,29 @@ export function LineChart({ analysis }: Props) {
},
};

return <Line options={options} data={chartData}/>
return <Line options={options} data={chartData} />;
}

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: {
Expand All @@ -188,71 +196,103 @@ function SpatialBarChart({ analysis }: Props) {
}
};

return <Bar options={options} data={chartData} />
return <Bar options={options} data={chartData} />;
}


export function RenderBaseline({ analysis }: Props) {
const keys = Object.keys(analysis.results.columns)
return <Box overflow="auto" maxW="100%">
<Table className='BaselineAnalysisResultTable' cellPadding={8}>
<tr>
<th>Name</th>
{
keys.map(
(column: string) => <th key={column}>{column}</th>
)
}
</tr>
{
analysis.results.features.map((feature: any) => {
const properties = feature.properties;
return <tr>
<td>{properties.Name}</td>
{
keys.map(
(column: string) => <td key={column}>
{properties[column]}
</td>
)
}
if (!analysis.results?.features) {
return;
}

const keys = Object.keys(analysis.results?.columns || {});
return (
<Box overflow="auto" maxW="100%">
<Table className='BaselineAnalysisResultTable' cellPadding={8}>
<thead>
<tr>
<th>Name</th>
{keys.map((column: string) => <th key={column}>{column}</th>)}
</tr>
})
}
</Table>
</Box>
</thead>
<tbody>
{analysis.results.features.map((feature: any, index: number) => {
const properties = feature?.properties || {};
return (
<tr key={index}>
<td>{properties.Name || 'N/A'}</td>
{keys.map((column: string) => (
<td key={column}>{properties[column] || 'N/A'}</td>
))}
</tr>
);
})}
</tbody>
</Table>
</Box>
);
}

export function RenderTemporal({ analysis }: Props) {
return (
<Box display="flex" flexDirection="column" gap="4px" overflow={"auto"}>
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(
<Box flex="0 0 auto">
<LineChart analysis={analysis} />
</Box>
);
charts.push(
<Box flex="0 0 auto">
<BarChart analysis={analysis} />
<BarChart key="bar" analysis={analysis} />
</Box>
);
}else if (hasLineData) {
charts.push(
<LineChart analysis={analysis} />
);
}else if (hasBarData) {
charts.push(
<BarChart key="bar" analysis={analysis} />
);
}

if (charts.length === 0) {
return <Text color="black" marginTop={2}>No chart data available.</Text>;
}

return (
<Box display="flex" flexDirection="column" gap="4px" overflow="auto">
{charts}
</Box>
);
}



export function RenderSpatial({ analysis }: Props) {
return <Box>
<Text color='black' marginTop={2}>Relative % difference in {analysis.data.variable} between your reference area and selected camp/s:</Text>
<SpatialBarChart analysis={analysis} />
</Box>
return (
<Box>
<Text color='black' marginTop={2}>Relative % difference in {analysis.data.variable} between your reference area and selected camp/s:</Text>
<SpatialBarChart analysis={analysis} />
</Box>
);
}


export function RenderResult({ analysis }: Props) {
switch (analysis.data.analysisType) {
case "Baseline":
return <RenderBaseline analysis={analysis}/>
return <RenderBaseline analysis={analysis} />;
case "Temporal":
return <RenderTemporal analysis={analysis}/>
return <RenderTemporal analysis={analysis} />;
case "Spatial":
return <RenderSpatial analysis={analysis}/>
return <RenderSpatial analysis={analysis} />;
default:
return null
return <Text>No analysis type selected.</Text>;
}
}

0 comments on commit 1dec9a0

Please sign in to comment.