-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
enh: add initial streamlit dashboard setup
- Loading branch information
Showing
6 changed files
with
205 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import pandas as pd | ||
import streamlit as st | ||
|
||
from rssched.app.utils.io import get_uploaded_data | ||
|
||
st.title(f"Run Info") | ||
|
||
# Retrieve uploaded request and response data | ||
request, response, instance_name = get_uploaded_data() | ||
|
||
|
||
request_summary_df = pd.DataFrame( | ||
{ | ||
"Locations": [len(request.vehicle_types)], | ||
"Vehicle types": [len(request.vehicle_types)], | ||
"Depots": [len(request.depots)], | ||
"Depot capacity": [sum(depot.capacity for depot in request.depots)], | ||
"Routes": [len(request.routes)], | ||
"Departures": [len(request.departures)], | ||
"Maintenance tracks": [ | ||
sum(slot.track_count for slot in request.maintenance_slots) | ||
], | ||
} | ||
) | ||
|
||
response_summary_df = pd.DataFrame( | ||
{ | ||
"Unserved passengers": [response.objective_value.unserved_passengers], | ||
"Maintenance violoation": [response.objective_value.maintenance_violation], | ||
"Vehicle count": [response.objective_value.vehicle_count], | ||
"Costs": [response.objective_value.costs], | ||
} | ||
) | ||
|
||
st.write(f"**Instance:** {instance_name}") | ||
|
||
st.subheader("Request Summary") | ||
st.write(f"**File:** {st.session_state.request_file.name}") | ||
st.dataframe(request_summary_df, hide_index=True) | ||
|
||
st.subheader("Response Summary") | ||
st.write(f"**File:** {st.session_state.response_file.name}") | ||
st.dataframe(response_summary_df, hide_index=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import streamlit as st | ||
|
||
from rssched.app.utils.io import get_uploaded_data | ||
from rssched.visualization.vehicle_type_gantt import plot_gantt_per_vehicle_type | ||
|
||
st.title("Schedule") | ||
|
||
request, response, instance_name = get_uploaded_data() | ||
|
||
plots = plot_gantt_per_vehicle_type(response, instance_name) | ||
|
||
tabs = st.tabs(plots.keys()) | ||
|
||
for tab, (title, fig) in zip(tabs, plots.items()): | ||
with tab: | ||
st.plotly_chart(fig) | ||
|
||
""" | ||
from rssched.visualization.vehicle_utilization import plot_vehicle_utilization | ||
from rssched.visualization.fleet_efficiency import plot_fleet_efficiency | ||
from rssched.visualization.active_events import plot_active_events_over_time | ||
tabs = st.tabs( | ||
[ | ||
"Gantt Chart", | ||
"Active Events", | ||
"Vehicle Utilization", | ||
"Fleet Efficiency", | ||
] | ||
) | ||
with tabs[0]: | ||
st.plotly_chart(plot_gantt_per_vehicle_type(response, instance_name)[0]) | ||
with tabs[1]: | ||
st.plotly_chart(plot_active_events_over_time(response, instance_name)) | ||
with tabs[2]: | ||
st.plotly_chart(plot_vehicle_utilization(response, instance_name)) | ||
with tabs[3]: | ||
st.plotly_chart(plot_fleet_efficiency(response, instance_name)) | ||
""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import streamlit as st | ||
|
||
from rssched.app.utils.io import get_uploaded_data | ||
from rssched.visualization.active_events import plot_active_events_over_time | ||
from rssched.visualization.fleet_efficiency import plot_fleet_efficiency | ||
from rssched.visualization.vehicle_utilization import plot_vehicle_utilization | ||
|
||
st.title("Fleet") | ||
|
||
request, response, instance_name = get_uploaded_data() | ||
|
||
|
||
tabs = st.tabs(["Active Events", "Vehicle Utilization", "Efficiency"]) | ||
|
||
with tabs[0]: | ||
st.plotly_chart(plot_active_events_over_time(response, instance_name)) | ||
|
||
with tabs[1]: | ||
st.plotly_chart(plot_vehicle_utilization(response, instance_name)) | ||
|
||
with tabs[2]: | ||
st.plotly_chart(plot_fleet_efficiency(response, instance_name)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import streamlit as st | ||
|
||
from rssched.app.utils.io import get_uploaded_data | ||
|
||
st.title("Depots") | ||
|
||
request, response, instance_name = get_uploaded_data() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import streamlit as st | ||
|
||
from rssched.app.utils.io import import_request, import_response | ||
|
||
st.title("RSSched Analyzer") | ||
st.markdown( | ||
""" | ||
### About | ||
This page provides an aggregated summary of the request data uploaded by the user. | ||
You can see important statistics such as the number of locations, vehicle types, depots, | ||
routes, and other relevant metrics. Additionally, an objective value from the response is also displayed below. | ||
""" | ||
) | ||
|
||
st.subheader("Upload Data") | ||
|
||
# Session state to store file uploads | ||
if "request_file" not in st.session_state: | ||
st.session_state.request_file = None | ||
if "response_file" not in st.session_state: | ||
st.session_state.response_file = None | ||
|
||
# Upload Request and Response Files | ||
request_file = st.file_uploader( | ||
"Set request file (JSON)", type=["json"], key="request_uploader" | ||
) | ||
response_file = st.file_uploader( | ||
"Set response file (JSON)", type=["json"], key="response_uploader" | ||
) | ||
|
||
# If both files are uploaded, process them | ||
if request_file is not None and response_file is not None: | ||
request_instance_name = ".".join(request_file.name.split(".")[:2]) | ||
response_instance_name = ".".join(response_file.name.split(".")[:2]) | ||
|
||
if request_instance_name != response_instance_name: | ||
st.warning( | ||
f"Instance of request '{request_instance_name}' and response '{response_instance_name}' not the same." | ||
) | ||
|
||
st.session_state.rssched_instance_name = request_instance_name | ||
st.session_state.request_file = request_file | ||
st.session_state.response_file = response_file | ||
st.session_state.instance_name = response_file | ||
st.session_state.request_data = import_request(st.session_state.request_file) | ||
st.session_state.response_data = import_response(st.session_state.response_file) | ||
|
||
st.success("Files uploaded and processed successfully!") | ||
|
||
|
||
# Reset button to clear the uploaded files and session state | ||
if st.button("Reset"): | ||
st.session_state.request_file = None | ||
st.session_state.response_file = None | ||
st.session_state.request_data = None | ||
st.session_state.response_data = None | ||
st.rerun() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import json | ||
from typing import Tuple | ||
|
||
import streamlit as st | ||
|
||
from rssched.io.reader import convert_keys_to_snake_case | ||
from rssched.model.request import Request | ||
from rssched.model.response import Info, ObjectiveValue, Response, Schedule | ||
|
||
|
||
def import_request(file_obj) -> Request: | ||
data = convert_keys_to_snake_case(json.load(file_obj)) | ||
return Request(**data) | ||
|
||
|
||
def import_response(file_obj) -> Response: | ||
data = convert_keys_to_snake_case(json.load(file_obj)) | ||
|
||
info = Info(**data["info"]) | ||
objective_value = ObjectiveValue(**data["objective_value"]) | ||
schedule = Schedule(**data["schedule"]) | ||
|
||
return Response(info=info, objective_value=objective_value, schedule=schedule) | ||
|
||
|
||
def get_uploaded_data() -> Tuple[Request, Response, str]: | ||
if st.session_state.get("request_data") and st.session_state.get("response_data"): | ||
request_data = st.session_state["request_data"] | ||
response_data = st.session_state["response_data"] | ||
return request_data, response_data, st.session_state["rssched_instance_name"] | ||
else: | ||
st.warning("Please upload both request and response files on the main page.") | ||
st.stop() |