[frontend]: Add average punctuality over time graph
This commit is contained in:
@ -2,6 +2,7 @@ import React, { useState, useEffect } from "react";
|
|||||||
import ObjectTypeProportionPieChart from "./charts/ObjectTypeProportionPieChart";
|
import ObjectTypeProportionPieChart from "./charts/ObjectTypeProportionPieChart";
|
||||||
import LoadingOverlay from "./LoadingOverlay.jsx";
|
import LoadingOverlay from "./LoadingOverlay.jsx";
|
||||||
import HeatmapContainer from "./charts/HeatmapContainer";
|
import HeatmapContainer from "./charts/HeatmapContainer";
|
||||||
|
import PunctualityLineChart from "./charts/PunctualityLineChart.jsx";
|
||||||
|
|
||||||
const Statistics = () => {
|
const Statistics = () => {
|
||||||
const [transientTypes, setTransientTypes] = useState([]);
|
const [transientTypes, setTransientTypes] = useState([]);
|
||||||
@ -9,8 +10,11 @@ const Statistics = () => {
|
|||||||
const [trainStatuses, setTrainStatuses] = useState([]);
|
const [trainStatuses, setTrainStatuses] = useState([]);
|
||||||
const [trainLatenesses, setTrainLatenesses] = useState([]);
|
const [trainLatenesses, setTrainLatenesses] = useState([]);
|
||||||
const [coordinates, setCoordinates] = useState([]);
|
const [coordinates, setCoordinates] = useState([]);
|
||||||
|
const [punctualityData, setPunctualityData] = useState([]);
|
||||||
|
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [heatmapLoading, setHeatmapLoading] = useState(true);
|
const [heatmapLoading, setHeatmapLoading] = useState(true);
|
||||||
|
const [punctualityLoading, setPunctualityLoading] = useState(true);
|
||||||
const [error, setError] = useState("");
|
const [error, setError] = useState("");
|
||||||
|
|
||||||
// Fetch transient data separately
|
// Fetch transient data separately
|
||||||
@ -68,6 +72,30 @@ const Statistics = () => {
|
|||||||
fetchCoordinates();
|
fetchCoordinates();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// Fetch punctuality data
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchPunctualityData = async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch("https://z3o9pdmy8g.execute-api.us-east-1.amazonaws.com/return_punctuality_by_timestamp");
|
||||||
|
if (!response.ok) throw new Error("Network response was not ok");
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
const formattedData = data.map(item => ({
|
||||||
|
time: new Date(parseInt(item.timestamp) * 1000).toLocaleString(),
|
||||||
|
punctuality: parseFloat(item.average_punctuality)
|
||||||
|
}));
|
||||||
|
|
||||||
|
setPunctualityData(formattedData);
|
||||||
|
} catch (error) {
|
||||||
|
setError("Failed to fetch punctuality data");
|
||||||
|
} finally {
|
||||||
|
setPunctualityLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchPunctualityData();
|
||||||
|
}, []);
|
||||||
|
|
||||||
if (loading) return <LoadingOverlay message={"Fetching data..."} />;
|
if (loading) return <LoadingOverlay message={"Fetching data..."} />;
|
||||||
if (error) return <p className="text-center text-red-500">{error}</p>;
|
if (error) return <p className="text-center text-red-500">{error}</p>;
|
||||||
|
|
||||||
@ -120,10 +148,19 @@ const Statistics = () => {
|
|||||||
|
|
||||||
<div className="bg-white shadow-md rounded-lg p-4">
|
<div className="bg-white shadow-md rounded-lg p-4">
|
||||||
<ObjectTypeProportionPieChart
|
<ObjectTypeProportionPieChart
|
||||||
label={`Live Train Latenesses`}
|
label={`Live Punctuality`}
|
||||||
dataList={trainLatenesses}
|
dataList={trainLatenesses}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="bg-white shadow-md rounded-lg p-4"
|
||||||
|
style={{width: "400px", height: "400px"}}>
|
||||||
|
{punctualityLoading ? (
|
||||||
|
<p className="text-center text-gray-500">Loading Punctuality Data...</p>
|
||||||
|
) : (
|
||||||
|
<PunctualityLineChart data={punctualityData}/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
28
frontend/src/components/charts/PunctualityLineChart.jsx
Normal file
28
frontend/src/components/charts/PunctualityLineChart.jsx
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { LineChart, Line, XAxis, YAxis, Tooltip, ResponsiveContainer, CartesianGrid } from "recharts";
|
||||||
|
|
||||||
|
const PunctualityLineChart = ({ data }) => {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col items-center p-4 bg-white shadow-lg rounded-lg w-full max-w-md">
|
||||||
|
<h2 className="text-xl font-semibold text-center mb-4">Average Punctuality Over Time</h2>
|
||||||
|
<ResponsiveContainer width={"100%"} height={400}>
|
||||||
|
<LineChart data={data} margin={{ bottom: 20, left: 20, right: 20, top: 20 }}>
|
||||||
|
<CartesianGrid strokeDasharray="3 3" />
|
||||||
|
<XAxis
|
||||||
|
dataKey="time"
|
||||||
|
angle={-30}
|
||||||
|
textAnchor="end"
|
||||||
|
height={60}
|
||||||
|
padding={{ left: 20, right: 20 }}
|
||||||
|
tick={{ fontSize: 10 }}
|
||||||
|
/>
|
||||||
|
<YAxis domain={[0, "auto"]} tick={{ fontSize: 10 }} />
|
||||||
|
<Tooltip contentStyle={{ fontSize: 10 }} />
|
||||||
|
<Line type="monotone" dataKey="punctuality" stroke="#8884d8" dot={false} />
|
||||||
|
</LineChart>
|
||||||
|
</ResponsiveContainer>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PunctualityLineChart;
|
Reference in New Issue
Block a user