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

fixed back routes for stats and added graph component

parent aa575cf4
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)
......
......@@ -57,9 +57,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)
"""
......
Source diff could not be displayed: it is too large. Options to address this: view the blob.
......@@ -15,7 +15,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>
);
}
......@@ -7,19 +7,23 @@ export default function WaitingTime({ place }) {
const baseURL = process.env.REACT_APP_BASE_URL_BACK + "/" + place + "/waiting_time";
const [post, setPost] = React.useState(null);
export default function WaitingTime({place}) {
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))};
});
}, [baseURL]);
}, [url]);
if (!post) return null;
return (
<div className="parent">
<div className="waiting-time">
Temps d&apos;attente estimé à <b>{post} minutes</b>.
Temps d'attente estimé à <b>{post} minutes</b>.
</div>
</div>
);
)
}
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>
);
}
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 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"
.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";
<<<<<<< HEAD
import Timetable from "../components/Timetable";
import WaitingTime from "../components/WaitingTime";
......@@ -25,3 +26,30 @@ export default function Eiffel() {
</div>
);
}
=======
import { DailyGraph, Timetable, WaitingTime } from "../components"
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',
'MardiMidi': '11h30 - 14h',
'MardiSoir': '18h30 - 21h',
'MercrediMidi': '11h30 - 14h',
'MercrediSoir': '18h30 - 21h',
'JeudiMidi': '11h30 - 14h',
'JeudiSoir': '18h30 - 21h',
'VendrediMidi': '11h30 - 14h',
'VendrediSoir': '18h30 - 21h'} }/>
</div>
)
}
>>>>>>> fixed back routes for stats and added graph component
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment