Source code for laborchestrator.traffic_light

from dash_extensions.enrich import html, dcc, Output, Input, State


[docs] def TrafficLight(component_id, size=60): """ Creates a reusable traffic light component with adjustable size. Args: component_id (str): The unique identifier for the component. size (int): The size of the traffic lights (width and height in pixels). Returns: html.Div: A Dash component representing the traffic light. """ size_px = f"{size}px" font_size = round(16*size/60) label_style = dict(color="white", whiteSpace="nowrap", fontSize=font_size) return html.Div( id=component_id, style={ "width": f"{size * 4}px", # Adjust container width based on size "backgroundColor": "black", "borderRadius": "10px", "padding": "10px", "display": "flex", "flexDirection": "column", "alignItems": "flex-start", }, children=[ dcc.Store(id=f"{component_id}-active", data=0), # Store to track active state # Green Light with Label html.Div( style={"display": "flex", "alignItems": "center", "marginBottom": "10px"}, children=[ html.Div( id=f"{component_id}-green-light", style={ "width": size_px, "height": size_px, "backgroundColor": "gray", "borderRadius": "50%", "marginRight": "10px", }, ), html.Div("Schedule Optimal", style=label_style), ], ), # Yellow Light with Label html.Div( style={"display": "flex", "alignItems": "center", "marginBottom": "10px"}, children=[ html.Div( id=f"{component_id}-yellow-light", style={ "width": size_px, "height": size_px, "backgroundColor": "gray", "borderRadius": "50%", "marginRight": "10px", }, ), html.Div("Schedule Feasible", style=label_style), ], ), # Orange Light with Label html.Div( style={"display": "flex", "alignItems": "center", "marginBottom": "10px"}, children=[ html.Div( id=f"{component_id}-orange-light", style={ "width": size_px, "height": size_px, "backgroundColor": "gray", "borderRadius": "50%", "marginRight": "10px", }, ), html.Div( ["Schedule Executable ", html.Br(), "(but Infeasible)"], style=label_style, ), ], ), # Red Light with Label html.Div( style={"display": "flex", "alignItems": "center"}, children=[ html.Div( id=f"{component_id}-red-light", style={ "width": size_px, "height": size_px, "backgroundColor": "gray", "borderRadius": "50%", "marginRight": "10px", }, ), html.Div("No Schedule Found", style=label_style), ], ), ], )
# Callback to update traffic lights
[docs] def register_traffic_light_callbacks(app, component_id): """ Registers the callback for the traffic light component. Args: app (Dash): The Dash app instance. component_id (str): The unique identifier of the traffic light. """ @app.callback( [ Output(f"{component_id}-green-light", "style"), Output(f"{component_id}-yellow-light", "style"), Output(f"{component_id}-orange-light", "style"), Output(f"{component_id}-red-light", "style"), ], [ Input(f"{component_id}-active", "data") ], [ State(f"{component_id}-green-light", "style"), State(f"{component_id}-yellow-light", "style"), State(f"{component_id}-orange-light", "style"), State(f"{component_id}-red-light", "style"), ] ) def update_traffic_light(active, green_style, yellow_style, orange_style, red_style): """ Updates the traffic light's active light based on the `active` property, while preserving existing style entries. Args: active (int): The index of the active light (0 for green, 1 for yellow, 2 for orange, 3 for red). green_style, yellow_style, orange_style, red_style (dict): Current styles of each light. Returns: tuple: Updated styles for each light. """ def update_style(current_style, color, is_active): # Create a new dictionary to preserve existing styles while updating relevant keys updated_style = current_style.copy() # Copy the current style updated_style.update({ "backgroundColor": color if is_active else "gray", "boxShadow": f"0 0 20px {color}" if is_active else "", }) return updated_style return ( update_style(green_style or {}, "green", active == 0), update_style(yellow_style or {}, "yellow", active == 1), update_style(orange_style or {}, "orange", active == 2), update_style(red_style or {}, "red", active == 3), )