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): ...@@ -26,11 +26,11 @@ def create_record(new_record: schemas.RecordBase, db: Session):
def get_waiting_time(place: str, db: Session): def get_waiting_time(place: str, db: Session):
""" Get the last estimated waiting time for the given place """ """ 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 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 """ """ Get the average waiting time for each interval between two time steps """
def shift_time(t: time, delta: timedelta): 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 ...@@ -58,14 +58,14 @@ def get_stats(place: str, weekday: int, min_time: time, max_time: time, interval
return int(records[0]) return int(records[0])
return None 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) average_waiting_time = avg_time_query(start_time, end_time)
if average_waiting_time: if average_waiting_time:
key = f'{start_time.hour:02}-{start_time.minute:02}-{end_time.hour:02}-{end_time.minute:02}' name = f'{start_time.hour:02}h{start_time.minute:02}'
dic[key] = average_waiting_time slots_list.append({'name': name, 'time': average_waiting_time})
min_time, max_time = time(min_time_hour, min_time_mn), time(max_time_hour, max_time_mn)
stats = {} stats = []
start_time, end_time = min_time, shift_time(min_time, interval) start_time, end_time = min_time, shift_time(min_time, interval)
while start_time < max_time: while start_time < max_time:
add_slot(stats, start_time, end_time) add_slot(stats, start_time, end_time)
......
...@@ -57,9 +57,10 @@ async def waiting_time(place: str, db: Session = Depends(get_db)): ...@@ -57,9 +57,10 @@ async def waiting_time(place: str, db: Session = Depends(get_db)):
return crud.get_waiting_time(place, db) return crud.get_waiting_time(place, db)
@app.get('/api/{place}/stats/{day}/{start_time}/{end_time}/{interval}', response_model=int) @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, start_time: time, end_time: time, interval: timedelta, db: Session = Depends(get_db)): async def stats(place: str, day: int, min_time_hour: int, min_time_mn: int,
return crud.get_stats(place, day, start_time, end_time, interval, db) 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.
...@@ -15,7 +15,8 @@ ...@@ -15,7 +15,8 @@
"react-helmet": "^6.1.0", "react-helmet": "^6.1.0",
"react-router-dom": "^6.3.0", "react-router-dom": "^6.3.0",
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"react-spring": "^9.4.5" "react-spring": "^9.4.5",
"recharts": "^2.1.12"
}, },
"scripts": { "scripts": {
"start": "react-scripts start", "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 }) { ...@@ -7,19 +7,23 @@ export default function WaitingTime({ place }) {
const baseURL = process.env.REACT_APP_BASE_URL_BACK + "/" + place + "/waiting_time"; const baseURL = process.env.REACT_APP_BASE_URL_BACK + "/" + place + "/waiting_time";
const [post, setPost] = React.useState(null); 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(() => { React.useEffect(() => {
axios.get(baseURL).then((response) => { axios.get(url).then((response) => {
setPost(Math.round(response.data / 60)); if (response.data < 60) {setPost(0)} else{
console.log(response.data); setPost(Math.round(response.data / 60))};
}); });
}, [baseURL]); }, [url]);
if (!post) return null; if (!post) return null;
return ( return (
<div className="parent"> <div className="parent">
<div className="waiting-time"> <div className="waiting-time">
Temps d&apos;attente estimé à <b>{post} minutes</b>. Temps d'attente estimé à <b>{post} minutes</b>.
</div> </div>
</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 Header } from "./Header"
export { default as Footer } from "./Footer"; export { default as Footer } from "./Footer"
export { default as Timetable } from "./Timetable"; export { default as Timetable } from "./Timetable"
export { default as WaitingTime } from "./WaitingTime"; export { default as WaitingTime } from "./WaitingTime"
export { default as DailyGraph } from "./Graph"
.footer{ .footer{
position: fixed;
bottom: 0; bottom: 0;
width: 100%; width: 100%;
} }
......
.parent{
display: flex;
justify-content: center;
}
.graph{
height: 30em;
width: 60em;
display: flex;
}
\ No newline at end of file
body { body, html {
height: 100%; height: 100vh;
color: white; color: white;
text-align: center; text-align: center;
background: linear-gradient(to right, #B06AB3, #4568DC); background: linear-gradient(to right, #B06AB3, #4568DC);
min-height: 100%;
} }
import React from "react"; import React from "react";
<<<<<<< HEAD
import Timetable from "../components/Timetable"; import Timetable from "../components/Timetable";
import WaitingTime from "../components/WaitingTime"; import WaitingTime from "../components/WaitingTime";
...@@ -25,3 +26,30 @@ export default function Eiffel() { ...@@ -25,3 +26,30 @@ export default function Eiffel() {
</div> </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