Skip to content
Snippets Groups Projects
Commit bf558ae2 authored by Aymeric Chaumont's avatar Aymeric Chaumont
Browse files

fixed back routes for stats and added graph component

parent 76f0e6da
No related branches found
No related tags found
1 merge request!23Extract stats
......@@ -26,11 +26,11 @@ def create_record(new_record: schemas.RecordBase, db: Session):
def get_waiting_time(place: str, db: Session):
""" Get the last estimated waiting time for the given place """
db_record = db.query(models.Records).filter(models.Records.place == place).order_by(models.Records.date.desc()).one()
db_record = db.query(models.Records).filter(models.Records.place == place).order_by(models.Records.date.desc()).first()
return db_record.waiting_time
def get_stats(place: str, weekday: int, min_time: time, max_time: time, interval: timedelta, db: Session):
def get_stats(place: str, weekday: int, min_time_hour: int, min_time_mn: int, max_time_hour: int, max_time_mn: int, interval: timedelta, db: Session):
""" Get the average waiting time for each interval between two time steps """
def shift_time(t: time, delta: timedelta):
......@@ -58,14 +58,14 @@ def get_stats(place: str, weekday: int, min_time: time, max_time: time, interval
return int(records[0])
return None
def add_slot(dic, start_time, end_time):
def add_slot(slots_list, start_time, end_time):
average_waiting_time = avg_time_query(start_time, end_time)
if average_waiting_time:
key = f'{start_time.hour:02}-{start_time.minute:02}-{end_time.hour:02}-{end_time.minute:02}'
dic[key] = average_waiting_time
name = f'{start_time.hour:02}h{start_time.minute:02}'
slots_list.append({'name': name, 'time': average_waiting_time})
stats = {}
min_time, max_time = time(min_time_hour, min_time_mn), time(max_time_hour, max_time_mn)
stats = []
start_time, end_time = min_time, shift_time(min_time, interval)
while start_time < max_time:
add_slot(stats, start_time, end_time)
......
......@@ -56,9 +56,10 @@ async def waiting_time(place: str, db: Session = Depends(get_db)):
return crud.get_waiting_time(place, db)
@app.get('/api/{place}/stats/{day}/{start_time}/{end_time}/{interval}', response_model=int)
async def stats(place: str, day: int, start_time: time, end_time: time, interval: timedelta, db: Session = Depends(get_db)):
return crud.get_stats(place, day, start_time, end_time, interval, db)
@app.get('/api/{place}/stats/{day}/{min_time_hour}/{min_time_mn}/{max_time_hour}/{max_time_mn}/{interval}', response_model=list)
async def stats(place: str, day: int, min_time_hour: int, min_time_mn: int,
max_time_hour: int, max_time_mn: int, interval: timedelta, db: Session = Depends(get_db)):
return crud.get_stats(place, day, min_time_hour, min_time_mn, max_time_hour, max_time_mn, interval, db)
"""
......
This diff is collapsed.
......@@ -16,7 +16,8 @@
"react-helmet": "^6.1.0",
"react-router-dom": "^6.3.0",
"react-scripts": "5.0.1",
"react-spring": "^9.4.5"
"react-spring": "^9.4.5",
"recharts": "^2.1.12"
},
"scripts": {
"start": "react-scripts start",
......
import React from 'react';
import axios from "axios"
import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
import gradient from "./gradient";
import styles from "../styles/Graph.css"
export default function DailyGraph({place, day, min_time_hour, min_time_mn, max_time_hour, max_time_mn, interval}) {
const url = process.env.REACT_APP_BASE_URL_BACK + '/' + place + '/stats/' + day + '/' + min_time_hour + '/' + min_time_mn
+ '/' + max_time_hour + '/' + max_time_mn + '/' + interval
const [data, setData] = React.useState([]);
React.useEffect(() => {
axios.get(url).then((response) => {
setData(response.data); console.log(response.data);
});
}, [url]);
if (!data) return null;
const CustomTooltip = ({ active, payload, label }) => {
if (active && payload && payload.length) {
return (
<div className="custom-tooltip">
<p className="label">{`Temps d'attente : ${payload[0].value} minutes`}</p>
</div>
);
}
return null;
};
return (
<div className='parent'>
<div className="graph">
<ResponsiveContainer width="100%" height="100%">
<AreaChart
width={500}
height={300}
data={data}
margin={{
top: 5,
right: 30,
left: 20,
bottom: 5,
}}
>
{gradient()}
<CartesianGrid
stroke="#FFFFFF"
strokeDasharray="1 5" />
<XAxis
axisLine={false}
tickLine={false}
tick={{ fill: "#FFFFFF", fontSize: "18" }}
padding={{ left: 20 }}
dataKey="name"/>
<YAxis
axisLine={false}
tickLine={false}
tick={{ fill: "#FFFFFF", fontSize: "18" }}
dataKey = "time"/>
<Tooltip content={<CustomTooltip />}/>
<Area
type="monotone"
dataKey="time"
stroke="#5661B3"
fillOpacity={1}
fill="url(#colorGradient)"
dot={{ stroke: "#0967D2", strokeWidth: 2, fill: "#fff" }}
/>
</AreaChart>
</ResponsiveContainer>
</div>
</div>
);
}
......@@ -5,15 +5,15 @@ import styles from "../styles/WaitingTime.css"
export default function WaitingTime({place}) {
const baseURL = process.env.REACT_APP_BASE_URL_BACK + '/' + place + "/waiting_time";
const url = process.env.REACT_APP_BASE_URL_BACK + '/' + place + "/waiting_time";
const [post, setPost] = React.useState(null);
React.useEffect(() => {
axios.get(baseURL).then((response) => {
setPost(Math.round(response.data / 60));
console.log(response.data)
axios.get(url).then((response) => {
if (response.data < 60) {setPost(0)} else{
setPost(Math.round(response.data / 60))};
});
}, []);
}, [url]);
if (!post) return null;
return (
......
import React from "react";
export default function gradient () {
return (
<defs>
<linearGradient id="colorGradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="10%" stopColor="#ff0000" stopOpacity={0.55} />
<stop offset="50%" stopColor="#fff200" stopOpacity={0.55} />
<stop offset="90%" stopColor="#1e9600" stopOpacity={0.55} />
</linearGradient>
</defs>
);
}
......@@ -2,3 +2,4 @@ export { default as Header } from "./Header"
export { default as Footer } from "./Footer"
export { default as Timetable } from "./Timetable"
export { default as WaitingTime } from "./WaitingTime"
export { default as DailyGraph } from "./Graph"
\ No newline at end of file
.footer{
position: fixed;
bottom: 0;
width: 100%;
}
......
.parent{
display: flex;
justify-content: center;
}
.graph{
height: 30em;
width: 60em;
display: flex;
}
\ No newline at end of file
body {
height: 100%;
body, html {
height: 100vh;
color: white;
text-align: center;
background: linear-gradient(to right, #B06AB3, #4568DC);
min-height: 100%;
}
import React from "react"
import Timetable from "../components/Timetable"
import WaitingTime from "../components/WaitingTime"
import { DailyGraph, Timetable, WaitingTime } from "../components"
export default function Eiffel(props) {
export default function Eiffel() {
return (
<div>
<h2>
RU Eiffel
</h2>
<WaitingTime place="eiffel" />
<DailyGraph place="eiffel" day={3} min_time_hour={12} min_time_mn={0} max_time_hour={12} max_time_mn={40} interval={300}/>
<Timetable schedule={ {
'LundiMidi': '11h30 - 14h',
'LundiSoir': '18h30 - 21h',
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment