# File: logs.py # Copyright (C) 2026 Erick Ahmed # SPDX-License-Identifier: AGPL-3.0-or-later import pandas as pd import plotly.graph_objects as go from dash import html, dcc def render_logs_table(df: pd.DataFrame): if df is None or df.empty: return html.Div("No data available") df = df.copy() if 'j1939_metadata' in df.columns: df['Priority'] = df['j1939_metadata'].apply(lambda x: x.get('Priority') if isinstance(x, dict) else None) df['PF'] = df['j1939_metadata'].apply(lambda x: x.get('PF') if isinstance(x, dict) else None) df['PS'] = df['j1939_metadata'].apply(lambda x: x.get('PS') if isinstance(x, dict) else None) df['SA'] = df['j1939_metadata'].apply(lambda x: x.get('SA') if isinstance(x, dict) else None) df['DA'] = df['j1939_metadata'].apply(lambda x: x.get('DA') if isinstance(x, dict) else None) df['PGN'] = df['j1939_metadata'].apply(lambda x: x.get('PGN') if isinstance(x, dict) else None) else: for col in ['Priority', 'PF', 'PS', 'SA', 'DA', 'PGN']: df[col] = None for i in range(8): col = f'b{i}' if col in df.columns: df[col] = df[col].apply(lambda x: f"{int(x):02X}" if pd.notna(x) else "") else: df[col] = "" if 'ID' in df.columns: df['ID'] = df['ID'].astype(str) display_cols = ['Timestamp', 'ID', 'DLC', 'b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'Priority', 'PF', 'PS', 'SA', 'DA', 'PGN'] display_df = df[[c for c in display_cols if c in df.columns]] display_df = display_df.fillna("") max_rows = 1000 total_rows = len(display_df) if total_rows > max_rows: display_df = display_df.iloc[:max_rows] fig = go.Figure(data=[go.Table( header=dict( values=["" + str(c) + "" for c in display_df.columns], fill_color='#1a1a1a', font=dict(color='white', size=12), align='center' ), cells=dict( values=[display_df[col] for col in display_df.columns], fill_color='#f8f9fa', font=dict(color='#2a2a2a', size=11), align='center' ) )]) fig.update_layout( height=800, margin=dict(l=0, r=0, t=10, b=0) ) return html.Div([ html.Div(f"Displaying first {len(display_df)} of {total_rows} total frames.", className="text-muted mb-2"), dcc.Graph(figure=fig, style={'height': '80vh'}) ])