Spaces:
Sleeping
Sleeping
| import html | |
| from dash import ClientsideFunction, Input, Output, State, dcc, no_update #type: ignore | |
| from .dash_data import load_session | |
| from .dash_figures import multiline, track_map | |
| def register_callbacks(app, cfg: dict): | |
| sessions_dir = cfg["output"]["sessions_dir"] | |
| theme = cfg["theme"] | |
| chart_cfg = cfg["charts"] | |
| tabs_cfg = cfg["tabs"] | |
| tab_plots = {t["id"]: t.get("plots", []) for t in tabs_cfg} | |
| def update_header(session): | |
| if not session: | |
| return "" | |
| _, info = load_session(sessions_dir, session) | |
| track = html.escape(info["track"]) | |
| if info.get("track_configuration"): | |
| track += f" ({html.escape(info['track_configuration'])})" | |
| car = html.escape(str(info['car'])) | |
| max_rpm = html.escape(str(info['max_rpm'])) | |
| max_fuel = html.escape(str(info['max_fuel_kg'])) | |
| return f"Car: {car} | Track: {track} | Max RPM: {max_rpm} | Fuel: {max_fuel} kg" | |
| # show/hide the two content areas based on active tab | |
| def toggle_content_areas(tab): | |
| show = {"display": "block", "marginTop": "12px"} | |
| hide = {"display": "none", "marginTop": "12px"} | |
| if tab == "map": | |
| return hide, show | |
| return show, hide | |
| # regular (non-map) tabs | |
| def update_tab(session, tab): | |
| if not session or tab == "map": | |
| return "" | |
| df, _ = load_session(sessions_dir, session) | |
| return [ | |
| dcc.Graph( | |
| id=f"g-{p['id']}", | |
| figure=multiline(df, p, theme, chart_cfg), | |
| config={"displayModeBar": False}, | |
| ) | |
| for p in tab_plots.get(tab, []) | |
| ] | |
| # rebuild map figure when session or colour changes | |
| def update_map(session, color_col): | |
| if not session: | |
| return no_update, no_update, no_update | |
| df, _ = load_session(sessions_dir, session) | |
| if "pos_x" not in df.columns or "pos_z" not in df.columns: | |
| return no_update, no_update, no_update | |
| fig = track_map(df, 0, color_col or "speed_kmh", theme) | |
| store = {"pos_x": df["pos_x"].tolist(), "pos_z": df["pos_z"].tolist()} | |
| return fig, len(df) - 1, store | |
| # move car marker — pure JS, no server round-trip | |
| app.clientside_callback( | |
| ClientsideFunction(namespace="map", function_name="move_marker"), | |
| Output("map-dummy", "data"), | |
| Input("map-slider", "value"), | |
| State("map-pos-store", "data"), | |
| prevent_initial_call=True, | |
| ) | |